From 507d13f45963fcd1264ed218866f5f216a76f5fe Mon Sep 17 00:00:00 2001 From: Jakub Delicat Date: Thu, 16 Dec 2021 14:07:59 +0000 Subject: [PATCH] Import docker from LAB15_OLD --- .../ArNetworking/ArNetworking-Reference.html | 16 + .../Aria/ArNetworking/CommandLineOptions.txt | 68 + .../ArNetworking/CommandLineOptions.txt.in | 68 + Legacy/Aria/ArNetworking/Makefile | 260 + Legacy/Aria/ArNetworking/Makefile.dep | 4845 ++ .../docs/figures/ArNetworking_overview.png | Bin 0 -> 60624 bytes Legacy/Aria/ArNetworking/doxygen.conf | 1304 + Legacy/Aria/ArNetworking/doxygen.conf.in | 1304 + .../examples/ArNetworking_Examples-vc2003.sln | 87 + .../examples/ArNetworking_Examples-vc2008.sln | 79 + Legacy/Aria/ArNetworking/examples/Makefile | 8 + Legacy/Aria/ArNetworking/examples/README.txt | 26 + .../examples/clientCommandLister.cpp | 36 + .../examples/clientDemo-vc2003.vcproj | 181 + .../examples/clientDemo-vc2008.vcproj | 251 + .../examples/clientDemo-vc2010.vcxproj | 159 + .../Aria/ArNetworking/examples/clientDemo.cpp | 634 + .../examples/clientDemoStatic-vc2003.vcproj | 136 + .../examples/clientDemoStatic-vc2008.vcproj | 214 + .../examples/clientDemoStatic-vc2010.vcxproj | 146 + .../ArNetworking/examples/configClient.cpp | 66 + .../examples/configClientToServer.cpp | 82 + .../ArNetworking/examples/configServer.cpp | 61 + .../examples/configServerRobot.cpp | 30 + .../ArNetworking/examples/drawingsExample.cpp | 287 + .../examples/drawingsExampleWithRobot.cpp | 256 + .../ArNetworking/examples/getVideoExample.cpp | 164 + .../ArNetworking/examples/popupExample.cpp | 189 + .../examples/ptzCameraClientExample.cpp | 334 + .../examples/serverDemo-vc2003.vcproj | 180 + .../examples/serverDemo-vc2008.vcproj | 247 + .../examples/serverDemo-vc2010.vcxproj | 152 + .../Aria/ArNetworking/examples/serverDemo.cpp | 257 + .../ArNetworking/examples/serverDemo.userInfo | 8 + .../examples/serverDemoStatic-vc2003.vcproj | 138 + .../examples/serverDemoStatic-vc2008.vcproj | 213 + .../examples/serverDemoStatic-vc2010.vcxproj | 143 + .../examples/simpleServerExample.cpp | 129 + .../ArNetworking/include/ArCentralForwarder.h | 168 + .../ArNetworking/include/ArCentralManager.h | 88 + .../ArNetworking/include/ArClientArgUtils.h | 170 + .../Aria/ArNetworking/include/ArClientBase.h | 424 + .../ArNetworking/include/ArClientCommands.h | 24 + .../Aria/ArNetworking/include/ArClientData.h | 86 + .../ArNetworking/include/ArClientFileUtils.h | 367 + .../include/ArClientHandlerConfig.h | 223 + .../include/ArClientSimpleConnector.h | 71 + .../include/ArClientSwitchManager.h | 187 + .../include/ArHybridForwarderVideo.h | 88 + .../Aria/ArNetworking/include/ArMapChanger.h | 557 + .../Aria/ArNetworking/include/ArNetPacket.h | 84 + .../include/ArNetPacketReceiverTcp.h | 79 + .../include/ArNetPacketReceiverUdp.h | 41 + .../include/ArNetPacketSenderTcp.h | 51 + .../Aria/ArNetworking/include/ArNetworking.h | 188 + .../Aria/ArNetworking/include/ArServerBase.h | 513 + .../ArNetworking/include/ArServerClient.h | 284 + .../ArNetworking/include/ArServerClientData.h | 40 + .../include/ArServerClientIdentifier.h | 133 + .../ArNetworking/include/ArServerCommands.h | 49 + .../Aria/ArNetworking/include/ArServerData.h | 70 + .../ArNetworking/include/ArServerFileUtils.h | 244 + .../include/ArServerHandlerCamera.h | 418 + .../include/ArServerHandlerCameraCollection.h | 142 + .../include/ArServerHandlerCommMonitor.h | 125 + .../include/ArServerHandlerCommands.h | 69 + .../include/ArServerHandlerConfig.h | 321 + .../ArNetworking/include/ArServerHandlerMap.h | 185 + .../include/ArServerHandlerMapping.h | 193 + .../include/ArServerHandlerPopup.h | 256 + .../include/ArServerInfoDrawings.h | 88 + .../ArNetworking/include/ArServerInfoRobot.h | 123 + .../ArNetworking/include/ArServerInfoSensor.h | 65 + .../include/ArServerInfoStrings.h | 67 + .../Aria/ArNetworking/include/ArServerMode.h | 252 + .../ArNetworking/include/ArServerModeDrive.h | 56 + .../ArNetworking/include/ArServerModeIdle.h | 43 + .../include/ArServerModeRatioDrive.h | 132 + .../ArNetworking/include/ArServerModeStop.h | 37 + .../ArNetworking/include/ArServerModeWander.h | 26 + .../include/ArServerSimpleCommands.h | 301 + .../include/ArServerSimpleOpener.h | 103 + .../ArNetworking/include/ArServerUserInfo.h | 71 + .../include/ArTempDirectoryHelper.h | 75 + Legacy/Aria/ArNetworking/include/md5.h | 104 + Legacy/Aria/ArNetworking/include/wrapper.i | 268 + .../Aria/ArNetworking/javaExamples/Makefile | 48 + .../Aria/ArNetworking/javaExamples/README.txt | 71 + .../javaExamples/customClientExample.java | 76 + .../javaExamples/customServerExample.java | 57 + .../ArNetworking/javaExamples/simple.java | 88 + .../ArNetworking/pythonExamples/README.txt | 22 + .../pythonExamples/customClientExample.py | 66 + .../pythonExamples/customServerExample.py | 27 + .../pythonExamples/drawingsExample.py | 204 + .../ArNetworking/pythonExamples/simple.py | 77 + .../ArNetworking/src/ArCentralForwarder.cpp | 923 + .../ArNetworking/src/ArCentralManager.cpp | 712 + .../ArNetworking/src/ArClientArgUtils.cpp | 702 + Legacy/Aria/ArNetworking/src/ArClientBase.cpp | 2332 + Legacy/Aria/ArNetworking/src/ArClientData.cpp | 53 + .../ArNetworking/src/ArClientFileUtils.cpp | 1416 + .../src/ArClientHandlerConfig.cpp | 1139 + .../src/ArClientSimpleConnector.cpp | 170 + .../src/ArClientSwitchManager.cpp | 687 + .../src/ArHybridForwarderVideo.cpp | 240 + Legacy/Aria/ArNetworking/src/ArMapChanger.cpp | 3212 + Legacy/Aria/ArNetworking/src/ArNetPacket.cpp | 212 + .../src/ArNetPacketReceiverTcp.cpp | 328 + .../src/ArNetPacketReceiverUdp.cpp | 141 + .../ArNetworking/src/ArNetPacketSenderTcp.cpp | 251 + .../src/ArNetworkingDLL-vc2003.vcproj | 520 + .../src/ArNetworkingDLL-vc2008.vcproj | 700 + .../src/ArNetworkingDLL-vc2010.vcxproj | 298 + .../src/ArNetworkingStatic-vc2003.vcproj | 502 + .../src/ArNetworkingStatic-vc2008.vcproj | 514 + .../src/ArNetworkingStatic-vc2010.vcxproj | 263 + Legacy/Aria/ArNetworking/src/ArServerBase.cpp | 2299 + .../Aria/ArNetworking/src/ArServerClient.cpp | 1563 + Legacy/Aria/ArNetworking/src/ArServerData.cpp | 95 + .../ArNetworking/src/ArServerFileUtils.cpp | 1352 + .../src/ArServerHandlerCamera.cpp | 1306 + .../src/ArServerHandlerCameraCollection.cpp | 300 + .../src/ArServerHandlerCommMonitor.cpp | 138 + .../src/ArServerHandlerCommands.cpp | 296 + .../src/ArServerHandlerConfig.cpp | 1618 + .../ArNetworking/src/ArServerHandlerMap.cpp | 890 + .../src/ArServerHandlerMapping.cpp | 713 + .../ArNetworking/src/ArServerHandlerPopup.cpp | 413 + .../ArNetworking/src/ArServerInfoDrawings.cpp | 265 + .../ArNetworking/src/ArServerInfoRobot.cpp | 270 + .../ArNetworking/src/ArServerInfoSensor.cpp | 177 + .../ArNetworking/src/ArServerInfoStrings.cpp | 138 + Legacy/Aria/ArNetworking/src/ArServerMode.cpp | 682 + .../ArNetworking/src/ArServerModeDrive.cpp | 244 + .../ArNetworking/src/ArServerModeIdle.cpp | 163 + .../src/ArServerModeRatioDrive.cpp | 543 + .../ArNetworking/src/ArServerModeStop.cpp | 139 + .../ArNetworking/src/ArServerModeWander.cpp | 64 + .../src/ArServerSimpleCommands.cpp | 971 + .../ArNetworking/src/ArServerSimpleOpener.cpp | 333 + .../ArNetworking/src/ArServerUserInfo.cpp | 273 + .../src/ArTempDirectoryHelper.cpp | 250 + Legacy/Aria/ArNetworking/src/md5.cpp | 390 + Legacy/Aria/ArNetworking/tests/Makefile | 9 + Legacy/Aria/ArNetworking/tests/baseTest.cpp | 62 + .../ArNetworking/tests/cameraModeClient.cpp | 85 + .../Aria/ArNetworking/tests/clientLoadMap.cpp | 52 + .../tests/clientLocalizeToPose.cpp | 56 + .../Aria/ArNetworking/tests/clientPatrol.cpp | 50 + .../Aria/ArNetworking/tests/clientTest.vcproj | 176 + .../ArNetworking/tests/commandTestClient.cpp | 94 + .../ArNetworking/tests/commandTestServer.cpp | 67 + Legacy/Aria/ArNetworking/tests/fileClient.cpp | 217 + .../Aria/ArNetworking/tests/fileClientRaw.cpp | 228 + Legacy/Aria/ArNetworking/tests/fileServer.cpp | 20 + .../Aria/ArNetworking/tests/fileToServer.cpp | 155 + Legacy/Aria/ArNetworking/tests/idleClient.cpp | 58 + .../ArNetworking/tests/infoDrawingClient.cpp | 133 + .../ArNetworking/tests/infoDrawingServer.cpp | 30 + Legacy/Aria/ArNetworking/tests/mapClient.cpp | 79 + Legacy/Aria/ArNetworking/tests/mapServer.cpp | 27 + Legacy/Aria/ArNetworking/tests/md5test.cpp | 143 + .../ArNetworking/tests/modeInfoClient.cpp | 86 + .../Aria/ArNetworking/tests/reloadConfig.cpp | 48 + .../Aria/ArNetworking/tests/serverTest.vcproj | 182 + .../ArNetworking/tests/simpleServerTest.cpp | 16 + .../tests/standaloneClientDemo.cpp | 161 + .../tests/standaloneServerDemo.cpp | 191 + .../Aria/ArNetworking/tests/switchServer.cpp | 61 + .../Aria/ArNetworking/tests/switchWatcher.cpp | 105 + Legacy/Aria/ArNetworking/tests/testClient.cpp | 53 + .../ArNetworking/tests/testRequestOnce.cpp | 71 + Legacy/Aria/ArNetworking/tests/testServer.cpp | 35 + .../Aria/ArNetworking/tests/testStatic.vcproj | 157 + .../ArNetworking/tests/userServerTest.cpp | 152 + .../tests/userServerTest.userInfo | 4 + .../Aria/ArNetworking/tests/watchDockInfo.cpp | 103 + Legacy/Aria/Aria-Reference.html | 16 + Legacy/Aria/Changes.txt | 1450 + Legacy/Aria/CommandLineOptions.txt | 370 + Legacy/Aria/INSTALL.txt | 7 + Legacy/Aria/LICENSE.txt | 424 + Legacy/Aria/Makefile | 776 + Legacy/Aria/Makefile.dep | 14508 ++++ Legacy/Aria/README.txt | 546 + Legacy/Aria/advanced/Makefile | 32 + Legacy/Aria/advanced/README.txt | 30 + Legacy/Aria/advanced/actsDemo.cpp | 1015 + Legacy/Aria/advanced/actsDemoSimple.cpp | 751 + Legacy/Aria/advanced/amptuDemo.cpp | 198 + Legacy/Aria/advanced/amptuDemo.vcproj | 177 + Legacy/Aria/advanced/condition.cpp | 143 + .../advanced/functorListsAndStdAlgorithms.cpp | 127 + Legacy/Aria/advanced/joydriveActionMod.cpp | 136 + Legacy/Aria/advanced/joydriveActionMod.vcproj | 187 + Legacy/Aria/advanced/joydriveActionModule.cpp | 88 + .../Aria/advanced/joydriveActionModule.vcproj | 177 + Legacy/Aria/advanced/joydriveUserControl.cpp | 110 + Legacy/Aria/advanced/peoplebotDemo.cpp | 1582 + Legacy/Aria/advanced/sickAutoLogger.cpp | 217 + Legacy/Aria/advanced/sickAutoLogger.vcproj | 177 + Legacy/Aria/advanced/sickSpinLogger.cpp | 162 + Legacy/Aria/advanced/sickSquareLogger.cpp | 214 + Legacy/Aria/bin/SIMULATOR_README.txt | 3 + Legacy/Aria/docs/figures/Amigobot.jpg | Bin 0 -> 15525 bytes .../ArRangeDevice_currentReadingPolar.dia | Bin 0 -> 2716 bytes .../ArRangeDevice_currentReadingPolar.png | Bin 0 -> 21271 bytes .../Aria/docs/figures/ArRobot_Task_Cycle.dia | Bin 0 -> 3636 bytes .../Aria/docs/figures/ArRobot_Task_Cycle.png | Bin 0 -> 37904 bytes .../docs/figures/MobileSim_with_laser.png | Bin 0 -> 27783 bytes .../figures/Robot_Communication_Options.png | Bin 0 -> 167992 bytes .../figures/Robot_Communications_Options.dia | Bin 0 -> 6864 bytes Legacy/Aria/docs/overview.dox | 1879 + Legacy/Aria/docs/params.dox | 285 + Legacy/Aria/doxygen.conf | 1316 + Legacy/Aria/examples/All_Examples-vc2003.sln | 325 + Legacy/Aria/examples/All_Examples-vc2008.sln | 286 + Legacy/Aria/examples/All_Examples-vc2010.sln | 265 + Legacy/Aria/examples/Makefile | 30 + Legacy/Aria/examples/README.txt | 104 + .../Aria/examples/actionExample-vc2003.vcproj | 179 + .../Aria/examples/actionExample-vc2008.vcproj | 236 + .../examples/actionExample-vc2010.vcxproj | 155 + Legacy/Aria/examples/actionExample.cpp | 337 + Legacy/Aria/examples/actionExample.vcproj | 167 + .../examples/actionGroupExample-vc2003.vcproj | 151 + .../examples/actionGroupExample-vc2008.vcproj | 211 + .../actionGroupExample-vc2010.vcxproj | 143 + Legacy/Aria/examples/actionGroupExample.cpp | 173 + .../Aria/examples/actionGroupExample.vcproj | 147 + .../actsColorFollowingExample-vc2003.vcproj | 258 + .../actsColorFollowingExample-vc2008.vcproj | 346 + .../actsColorFollowingExample-vc2010.vcxproj | 224 + .../examples/actsColorFollowingExample.cpp | 335 + Legacy/Aria/examples/armExample-vc2003.vcproj | 149 + Legacy/Aria/examples/armExample-vc2008.vcproj | 211 + .../Aria/examples/armExample-vc2010.vcxproj | 143 + Legacy/Aria/examples/armExample.cpp | 162 + .../examples/auxSerialExample-vc2003.vcproj | 156 + .../examples/auxSerialExample-vc2008.vcproj | 212 + .../examples/auxSerialExample-vc2010.vcxproj | 144 + Legacy/Aria/examples/auxSerialExample.cpp | 152 + Legacy/Aria/examples/cameraPTZExample.cpp | 167 + Legacy/Aria/examples/cameraPTZExample.vcxproj | 154 + Legacy/Aria/examples/configExample.cpp | 155 + Legacy/Aria/examples/demo | Bin 0 -> 19160 bytes Legacy/Aria/examples/demo-vc2003.vcproj | 178 + Legacy/Aria/examples/demo-vc2008.vcproj | 242 + Legacy/Aria/examples/demo-vc2010.vcxproj | 164 + Legacy/Aria/examples/demo.cpp | 214 + Legacy/Aria/examples/demoStatic-vc2003.vcproj | 141 + Legacy/Aria/examples/demoStatic-vc2008.vcproj | 213 + .../Aria/examples/demoStatic-vc2010.vcxproj | 143 + .../directMotionExample-vc2003.vcproj | 156 + .../directMotionExample-vc2008.vcproj | 212 + .../directMotionExample-vc2010.vcxproj | 144 + Legacy/Aria/examples/directMotionExample.cpp | 338 + .../Aria/examples/dpptuExample-vc2003.vcproj | 156 + .../Aria/examples/dpptuExample-vc2008.vcproj | 212 + .../Aria/examples/dpptuExample-vc2010.vcxproj | 144 + Legacy/Aria/examples/dpptuExample.cpp | 600 + .../examples/functorExample-vc2003.vcproj | 156 + .../examples/functorExample-vc2008.vcproj | 212 + .../examples/functorExample-vc2010.vcxproj | 144 + Legacy/Aria/examples/functorExample.cpp | 162 + .../examples/gotoActionExample-vc2003.vcproj | 156 + .../examples/gotoActionExample-vc2008.vcproj | 212 + .../examples/gotoActionExample-vc2010.vcxproj | 144 + Legacy/Aria/examples/gotoActionExample.cpp | 143 + Legacy/Aria/examples/gpsExample-vc2003.vcproj | 123 + Legacy/Aria/examples/gpsExample-vc2008.vcproj | 184 + .../Aria/examples/gpsExample-vc2010.vcxproj | 106 + Legacy/Aria/examples/gpsExample.cpp | 136 + Legacy/Aria/examples/gpsRobotTaskExample.cpp | 199 + .../examples/gripperExample-vc2003.vcproj | 156 + .../examples/gripperExample-vc2008.vcproj | 212 + .../examples/gripperExample-vc2010.vcxproj | 144 + Legacy/Aria/examples/gripperExample.cpp | 208 + .../Aria/examples/gyroExample-vc2003.vcproj | 173 + .../Aria/examples/gyroExample-vc2008.vcproj | 234 + .../Aria/examples/gyroExample-vc2010.vcxproj | 153 + Legacy/Aria/examples/gyroExample.cpp | 199 + Legacy/Aria/examples/imuExample.cpp | 171 + Legacy/Aria/examples/ipthru-vc2003.vcproj | 185 + Legacy/Aria/examples/ipthru-vc2008.vcproj | 249 + Legacy/Aria/examples/ipthru-vc2010.vcxproj | 153 + Legacy/Aria/examples/ipthru.cpp | 237 + .../joydriveActionExample-vc2003.vcproj | 156 + .../joydriveActionExample-vc2008.vcproj | 210 + .../joydriveActionExample-vc2010.vcproj | 210 + .../Aria/examples/joydriveActionExample.cpp | 155 + .../examples/joydriveThreaded-vc2003.vcproj | 173 + .../examples/joydriveThreaded-vc2008.vcproj | 234 + .../examples/joydriveThreaded-vc2010.vcxproj | 153 + Legacy/Aria/examples/joydriveThreaded.cpp | 265 + .../examples/joydriveUserTask-vc2003.vcproj | 173 + .../examples/joydriveUserTask-vc2008.vcproj | 234 + Legacy/Aria/examples/joydriveUserTask.cpp | 165 + Legacy/Aria/examples/laserConnect.cpp | 133 + Legacy/Aria/examples/lasers.cpp | 133 + Legacy/Aria/examples/lineFinderExample.cpp | 103 + Legacy/Aria/examples/moduleExample.cpp | 103 + Legacy/Aria/examples/moduleExample.vcproj | 148 + Legacy/Aria/examples/moduleExample_Mod.cpp | 85 + Legacy/Aria/examples/moduleExample_Mod.vcproj | 158 + Legacy/Aria/examples/mtxIO.cpp | 159 + Legacy/Aria/examples/mtxLCDDisplay.cpp | 86 + Legacy/Aria/examples/mtxPowerControl.cpp | 114 + Legacy/Aria/examples/mtxWheelLights.cpp | 106 + .../examples/netServerExample-vc2003.vcproj | 156 + .../examples/netServerExample-vc2008.vcproj | 212 + .../examples/netServerExample-vc2010.vcxproj | 144 + Legacy/Aria/examples/netServerExample.cpp | 91 + .../examples/robotConnectionCallbacks.cpp | 144 + .../robotSyncTaskExample-vc2003.vcproj | 156 + .../robotSyncTaskExample-vc2008.vcproj | 212 + .../robotSyncTaskExample-vc2010.vcxproj | 144 + Legacy/Aria/examples/robotSyncTaskExample.cpp | 130 + Legacy/Aria/examples/seekurPower.cpp | 189 + Legacy/Aria/examples/sickLogger-vc2003.vcproj | 187 + Legacy/Aria/examples/sickLogger-vc2008.vcproj | 253 + .../Aria/examples/sickLogger-vc2010.vcxproj | 286 + Legacy/Aria/examples/sickLogger.cpp | 151 + .../examples/sickLoggerStatic-vc2003.vcproj | 182 + Legacy/Aria/examples/sickRobotExample.cpp | 145 + Legacy/Aria/examples/sickTeleop-vc2003.vcproj | 185 + Legacy/Aria/examples/sickTeleop-vc2008.vcproj | 249 + Legacy/Aria/examples/sickTeleop.cpp | 124 + .../Aria/examples/simpleConnect-vc2003.vcproj | 176 + .../Aria/examples/simpleConnect-vc2008.vcproj | 237 + .../examples/simpleConnect-vc2010.vcxproj | 156 + Legacy/Aria/examples/simpleConnect.cpp | 99 + Legacy/Aria/examples/simpleMotionCommands.cpp | 168 + .../socketClientExample-vc2003.vcproj | 156 + .../socketClientExample-vc2008.vcproj | 212 + .../socketClientExample-vc2010.vcxproj | 144 + Legacy/Aria/examples/socketClientExample.cpp | 117 + .../socketServerExample-vc2003.vcproj | 156 + .../socketServerExample-vc2008.vcproj | 210 + .../socketServerExample-vc2010.vcxproj | 143 + Legacy/Aria/examples/socketServerExample.cpp | 146 + Legacy/Aria/examples/sound-computers.wav | Bin 0 -> 48494 bytes Legacy/Aria/examples/sound-impressed.wav | Bin 0 -> 13728 bytes Legacy/Aria/examples/sound-ping.wav | Bin 0 -> 5254 bytes Legacy/Aria/examples/sound-r2a.wav | Bin 0 -> 31810 bytes Legacy/Aria/examples/sound-r2b.wav | Bin 0 -> 178806 bytes .../examples/soundsQueueExample-vc2003.vcproj | 132 + .../examples/soundsQueueExample-vc2008.vcproj | 194 + .../soundsQueueExample-vc2010.vcxproj | 116 + Legacy/Aria/examples/soundsQueueExample.cpp | 165 + .../teleopActionsExample-vc2003.vcproj | 156 + .../teleopActionsExample-vc2008.vcproj | 212 + .../teleopActionsExample-vc2010.vcxproj | 144 + Legacy/Aria/examples/teleopActionsExample.cpp | 119 + .../Aria/examples/threadExample-vc2003.vcproj | 256 + .../Aria/examples/threadExample-vc2008.vcproj | 237 + .../examples/threadExample-vc2010.vcxproj | 157 + Legacy/Aria/examples/threadExample.cpp | 184 + .../examples/triangleDriveToActionExample.cpp | 130 + .../examples/twoRobotWander-vc2003.vcproj | 173 + .../examples/twoRobotWander-vc2008.vcproj | 165 + .../examples/twoRobotWander-vc2010.vcxproj | 139 + Legacy/Aria/examples/twoRobotWander.cpp | 231 + Legacy/Aria/examples/wander-vc2003.vcproj | 173 + Legacy/Aria/examples/wander-vc2008.vcproj | 234 + Legacy/Aria/examples/wander-vc2010.vcxproj | 153 + Legacy/Aria/examples/wander.cpp | 118 + .../examples/wanderAndLogData-vc2003.vcproj | 130 + .../examples/wanderAndLogData-vc2008.vcproj | 191 + .../examples/wanderAndLogData-vc2010.vcxproj | 114 + Legacy/Aria/examples/wanderAndLogData.cpp | 352 + Legacy/Aria/icon.png | Bin 0 -> 4671 bytes Legacy/Aria/include/ArACTS.h | 155 + Legacy/Aria/include/ArAMPTU.h | 152 + Legacy/Aria/include/ArASyncTask.h | 109 + Legacy/Aria/include/ArAction.h | 142 + Legacy/Aria/include/ArActionAvoidFront.h | 78 + Legacy/Aria/include/ArActionAvoidSide.h | 62 + Legacy/Aria/include/ArActionBumpers.h | 77 + Legacy/Aria/include/ArActionColorFollow.h | 131 + .../Aria/include/ArActionConstantVelocity.h | 56 + .../include/ArActionDeceleratingLimiter.h | 114 + Legacy/Aria/include/ArActionDesired.h | 878 + Legacy/Aria/include/ArActionDriveDistance.h | 108 + Legacy/Aria/include/ArActionGoto.h | 122 + Legacy/Aria/include/ArActionGotoStraight.h | 127 + Legacy/Aria/include/ArActionGroup.h | 77 + Legacy/Aria/include/ArActionGroups.h | 209 + Legacy/Aria/include/ArActionIRs.h | 77 + Legacy/Aria/include/ArActionInput.h | 69 + Legacy/Aria/include/ArActionJoydrive.h | 102 + Legacy/Aria/include/ArActionKeydrive.h | 103 + .../Aria/include/ArActionLimiterBackwards.h | 68 + Legacy/Aria/include/ArActionLimiterForwards.h | 69 + Legacy/Aria/include/ArActionLimiterRot.h | 79 + .../Aria/include/ArActionLimiterTableSensor.h | 59 + .../Aria/include/ArActionMovementParameters.h | 92 + .../ArActionMovementParametersDebugging.h | 94 + Legacy/Aria/include/ArActionRatioInput.h | 142 + Legacy/Aria/include/ArActionRobotJoydrive.h | 87 + Legacy/Aria/include/ArActionStallRecover.h | 101 + Legacy/Aria/include/ArActionStop.h | 54 + Legacy/Aria/include/ArActionTriangleDriveTo.h | 283 + Legacy/Aria/include/ArActionTurn.h | 68 + Legacy/Aria/include/ArAnalogGyro.h | 222 + Legacy/Aria/include/ArArg.h | 172 + Legacy/Aria/include/ArArgumentBuilder.h | 266 + Legacy/Aria/include/ArArgumentParser.h | 184 + Legacy/Aria/include/ArBasePacket.h | 226 + Legacy/Aria/include/ArBatteryConnector.h | 193 + Legacy/Aria/include/ArBatteryMTX.h | 560 + Legacy/Aria/include/ArBumpers.h | 64 + Legacy/Aria/include/ArCameraCollection.h | 506 + Legacy/Aria/include/ArCameraCommands.h | 167 + Legacy/Aria/include/ArCommands.h | 172 + Legacy/Aria/include/ArCondition.h | 100 + Legacy/Aria/include/ArConfig.h | 613 + Legacy/Aria/include/ArConfigArg.h | 786 + Legacy/Aria/include/ArConfigGroup.h | 59 + Legacy/Aria/include/ArDPPTU.h | 457 + Legacy/Aria/include/ArDataLogger.h | 126 + Legacy/Aria/include/ArDeviceConnection.h | 186 + Legacy/Aria/include/ArDrawingData.h | 217 + Legacy/Aria/include/ArExitErrorSource.h | 69 + Legacy/Aria/include/ArExport.h | 51 + Legacy/Aria/include/ArFileParser.h | 224 + Legacy/Aria/include/ArForbiddenRangeDevice.h | 74 + Legacy/Aria/include/ArFunctor.h | 5415 ++ Legacy/Aria/include/ArFunctorASyncTask.h | 47 + Legacy/Aria/include/ArGPS.h | 623 + Legacy/Aria/include/ArGPSConnector.h | 142 + Legacy/Aria/include/ArGPSCoords.h | 234 + Legacy/Aria/include/ArGripper.h | 151 + Legacy/Aria/include/ArHasFileName.h | 69 + Legacy/Aria/include/ArIRs.h | 59 + Legacy/Aria/include/ArInterpolation.h | 96 + Legacy/Aria/include/ArIrrfDevice.h | 74 + Legacy/Aria/include/ArJoyHandler.h | 166 + Legacy/Aria/include/ArKeyHandler.h | 154 + Legacy/Aria/include/ArLCDConnector.h | 226 + Legacy/Aria/include/ArLCDMTX.h | 373 + Legacy/Aria/include/ArLMS1XX.h | 256 + Legacy/Aria/include/ArLMS2xx.h | 231 + Legacy/Aria/include/ArLMS2xxPacket.h | 87 + Legacy/Aria/include/ArLMS2xxPacketReceiver.h | 71 + Legacy/Aria/include/ArLaser.h | 761 + Legacy/Aria/include/ArLaserConnector.h | 250 + Legacy/Aria/include/ArLaserFilter.h | 108 + Legacy/Aria/include/ArLaserLogger.h | 197 + Legacy/Aria/include/ArLaserReflectorDevice.h | 64 + Legacy/Aria/include/ArLineFinder.h | 165 + Legacy/Aria/include/ArLog.h | 166 + Legacy/Aria/include/ArLogFileConnection.h | 93 + Legacy/Aria/include/ArMD5Calculator.h | 150 + Legacy/Aria/include/ArMTXIO.h | 313 + Legacy/Aria/include/ArMap.h | 655 + Legacy/Aria/include/ArMapComponents.h | 1376 + Legacy/Aria/include/ArMapInterface.h | 1494 + Legacy/Aria/include/ArMapObject.h | 370 + Legacy/Aria/include/ArMapUtils.h | 960 + Legacy/Aria/include/ArMode.h | 102 + Legacy/Aria/include/ArModes.h | 510 + Legacy/Aria/include/ArModule.h | 171 + Legacy/Aria/include/ArModuleLoader.h | 82 + Legacy/Aria/include/ArMutex.h | 210 + Legacy/Aria/include/ArNMEAParser.h | 169 + Legacy/Aria/include/ArNetServer.h | 223 + Legacy/Aria/include/ArNovatelGPS.h | 98 + Legacy/Aria/include/ArP2Arm.h | 299 + Legacy/Aria/include/ArPTZ.h | 357 + Legacy/Aria/include/ArPTZConnector.h | 170 + Legacy/Aria/include/ArPixelDevice.h | 235 + Legacy/Aria/include/ArPriorityResolver.h | 50 + Legacy/Aria/include/ArRVisionPTZ.h | 152 + Legacy/Aria/include/ArRangeBuffer.h | 133 + Legacy/Aria/include/ArRangeDevice.h | 442 + Legacy/Aria/include/ArRangeDeviceThreaded.h | 76 + Legacy/Aria/include/ArRatioInputJoydrive.h | 114 + Legacy/Aria/include/ArRatioInputKeydrive.h | 99 + .../Aria/include/ArRatioInputRobotJoydrive.h | 76 + Legacy/Aria/include/ArRecurrentTask.h | 87 + Legacy/Aria/include/ArResolver.h | 65 + Legacy/Aria/include/ArRingQueue.h | 229 + Legacy/Aria/include/ArRobot.h | 1848 + .../Aria/include/ArRobotBatteryPacketReader.h | 100 + Legacy/Aria/include/ArRobotConfig.h | 75 + .../Aria/include/ArRobotConfigPacketReader.h | 293 + Legacy/Aria/include/ArRobotConnector.h | 165 + Legacy/Aria/include/ArRobotJoyHandler.h | 101 + Legacy/Aria/include/ArRobotPacket.h | 81 + .../Aria/include/ArRobotPacketReaderThread.h | 59 + Legacy/Aria/include/ArRobotPacketReceiver.h | 101 + Legacy/Aria/include/ArRobotPacketSender.h | 95 + Legacy/Aria/include/ArRobotParams.h | 1296 + Legacy/Aria/include/ArRobotTypes.h | 381 + Legacy/Aria/include/ArS3Series.h | 250 + Legacy/Aria/include/ArSZSeries.h | 204 + Legacy/Aria/include/ArSensorReading.h | 213 + Legacy/Aria/include/ArSerialConnection.h | 141 + Legacy/Aria/include/ArSick.h | 340 + Legacy/Aria/include/ArSignalHandler.h | 163 + Legacy/Aria/include/ArSimpleConnector.h | 97 + Legacy/Aria/include/ArSimulatedLaser.h | 110 + Legacy/Aria/include/ArSocket.h | 400 + Legacy/Aria/include/ArSonarAutoDisabler.h | 91 + Legacy/Aria/include/ArSonarConnector.h | 200 + Legacy/Aria/include/ArSonarDevice.h | 94 + Legacy/Aria/include/ArSonarMTX.h | 565 + Legacy/Aria/include/ArSonyPTZ.h | 124 + Legacy/Aria/include/ArSoundPlayer.h | 123 + Legacy/Aria/include/ArSoundsQueue.h | 557 + Legacy/Aria/include/ArSpeech.h | 166 + Legacy/Aria/include/ArStringInfoGroup.h | 99 + Legacy/Aria/include/ArSyncLoop.h | 61 + Legacy/Aria/include/ArSyncTask.h | 164 + Legacy/Aria/include/ArSystemStatus.h | 186 + Legacy/Aria/include/ArTCM2.h | 252 + Legacy/Aria/include/ArTCMCompassDirect.h | 119 + Legacy/Aria/include/ArTCMCompassRobot.h | 67 + Legacy/Aria/include/ArTaskState.h | 54 + Legacy/Aria/include/ArTcpConnection.h | 96 + Legacy/Aria/include/ArThread.h | 270 + Legacy/Aria/include/ArTransform.h | 156 + Legacy/Aria/include/ArTrimbleGPS.h | 88 + Legacy/Aria/include/ArUrg.h | 127 + Legacy/Aria/include/ArUrg_2_0.h | 152 + Legacy/Aria/include/ArVCC4.h | 599 + Legacy/Aria/include/ArVersalogicIO.h | 150 + Legacy/Aria/include/ArZippable.h | 205 + Legacy/Aria/include/Aria.h | 159 + Legacy/Aria/include/ariaInternal.h | 333 + Legacy/Aria/include/ariaOSDef.h | 78 + Legacy/Aria/include/ariaTypedefs.h | 95 + Legacy/Aria/include/ariaUtil.h | 2357 + Legacy/Aria/include/md5.h | 129 + Legacy/Aria/include/wrapper.i | 742 + Legacy/Aria/include/wrapper_ExtraClasses.h | 74 + Legacy/Aria/include/wrapper_Functors.h | 100 + Legacy/Aria/include/wrapper_std_list_java.i | 74 + Legacy/Aria/java/ArNetworkingJava.vcproj | 132 + Legacy/Aria/java/ArNetworkingSwigJava.vcproj | 132 + Legacy/Aria/java/AriaJava-vc2010.sln | 79 + Legacy/Aria/java/AriaJava.sln | 61 + Legacy/Aria/java/AriaJava.vcproj | 160 + Legacy/Aria/java/AriaSwigJava.vcproj | 144 + Legacy/Aria/javaExamples/Makefile | 48 + Legacy/Aria/javaExamples/README.txt | 95 + Legacy/Aria/javaExamples/actionExample.java | 273 + Legacy/Aria/javaExamples/joyHandler.java | 46 + Legacy/Aria/javaExamples/laserWander.java | 82 + Legacy/Aria/javaExamples/map.java | 45 + .../javaExamples/robotSyncTaskExample.java | 114 + Legacy/Aria/javaExamples/simple.java | 71 + Legacy/Aria/javaExamples/socket.java | 54 + Legacy/Aria/lib/libAria.so | Bin 0 -> 5447696 bytes Legacy/Aria/maps/ActivMediaLab.map | 78 + Legacy/Aria/maps/columbia.map | 63824 ++++++++++++++++ Legacy/Aria/maps/office.map | 108 + Legacy/Aria/maps/triangle.map | 16 + Legacy/Aria/params/amigo-sh.p | 516 + Legacy/Aria/params/amigo.p | 516 + Legacy/Aria/params/mt400.p | 524 + Legacy/Aria/params/p2at.p | 524 + Legacy/Aria/params/p2at8+.p | 524 + Legacy/Aria/params/p2at8.p | 524 + Legacy/Aria/params/p2ce.p | 524 + Legacy/Aria/params/p2d8+.p | 524 + Legacy/Aria/params/p2d8.p | 524 + Legacy/Aria/params/p2de.p | 524 + Legacy/Aria/params/p2df.p | 524 + Legacy/Aria/params/p2dx.p | 524 + Legacy/Aria/params/p2it.p | 524 + Legacy/Aria/params/p2pb.p | 532 + Legacy/Aria/params/p2pp.p | 532 + Legacy/Aria/params/p3at-sh-lms1xx.p | 524 + Legacy/Aria/params/p3at-sh-lms500.p | 524 + Legacy/Aria/params/p3at-sh.p | 524 + Legacy/Aria/params/p3at.p | 524 + Legacy/Aria/params/p3atiw-sh.p | 524 + Legacy/Aria/params/p3dx-sh-lms1xx.p | 524 + Legacy/Aria/params/p3dx-sh-lms500.p | 524 + Legacy/Aria/params/p3dx-sh.p | 524 + Legacy/Aria/params/p3dx.p | 524 + Legacy/Aria/params/patrolbot-sh.p | 524 + Legacy/Aria/params/peoplebot-sh-lms1xx.p | 544 + Legacy/Aria/params/peoplebot-sh-lms500.p | 544 + Legacy/Aria/params/peoplebot-sh.p | 544 + Legacy/Aria/params/perfpb+.p | 544 + Legacy/Aria/params/perfpb.p | 544 + Legacy/Aria/params/pion1m.p | 515 + Legacy/Aria/params/pion1x.p | 515 + Legacy/Aria/params/pionat.p | 515 + Legacy/Aria/params/pioneer-lx.p | 516 + Legacy/Aria/params/powerbot-sh-lms500.p | 540 + Legacy/Aria/params/powerbot-sh-uarcs.p | 524 + Legacy/Aria/params/powerbot-sh.p | 540 + Legacy/Aria/params/powerbot.p | 539 + Legacy/Aria/params/psos1m.p | 515 + Legacy/Aria/params/psos1x.p | 515 + Legacy/Aria/params/psos43m.p | 515 + Legacy/Aria/params/researchPB-lms500.p | 524 + Legacy/Aria/params/researchPB.p | 524 + Legacy/Aria/params/seekur.p | 508 + Legacy/Aria/params/seekurjr.p | 508 + Legacy/Aria/params/wheelchair-sh.p | 508 + Legacy/Aria/python/ArNetworkingPy.vcxproj | 99 + Legacy/Aria/python/ArNetworkingPython.vcproj | 128 + Legacy/Aria/python/ArNetworkingPython.vcxproj | 114 + .../Aria/python/ArNetworkingSwigPython.vcproj | 127 + .../python/ArNetworkingSwigPython.vcxproj | 103 + Legacy/Aria/python/AriaPy-vc2003.sln | 73 + Legacy/Aria/python/AriaPy-vc2010.sln | 74 + Legacy/Aria/python/AriaPy.vcproj | 167 + Legacy/Aria/python/AriaPy.vcxproj | 147 + Legacy/Aria/python/AriaSwigPython.vcproj | 135 + Legacy/Aria/python/AriaSwigPython.vcxproj | 110 + Legacy/Aria/pythonExamples/README.txt | 152 + Legacy/Aria/pythonExamples/basicActions.py | 85 + Legacy/Aria/pythonExamples/configExample.cfg | 13 + Legacy/Aria/pythonExamples/configExample.py | 164 + Legacy/Aria/pythonExamples/customActions.py | 256 + .../Aria/pythonExamples/pythonThreadTest.py | 62 + .../Aria/pythonExamples/rangeDeviceReading.py | 81 + .../pythonExamples/robotSyncTaskExample.py | 113 + Legacy/Aria/pythonExamples/simple.py | 88 + Legacy/Aria/pythonExamples/teleop.py | 104 + Legacy/Aria/src/ArACTS.cpp | 319 + Legacy/Aria/src/ArAMPTU.cpp | 346 + Legacy/Aria/src/ArASyncTask.cpp | 90 + Legacy/Aria/src/ArAction.cpp | 158 + Legacy/Aria/src/ArActionAvoidFront.cpp | 158 + Legacy/Aria/src/ArActionAvoidSide.cpp | 85 + Legacy/Aria/src/ArActionBumpers.cpp | 232 + Legacy/Aria/src/ArActionColorFollow.cpp | 285 + Legacy/Aria/src/ArActionConstantVelocity.cpp | 57 + .../Aria/src/ArActionDeceleratingLimiter.cpp | 550 + Legacy/Aria/src/ArActionDesired.cpp | 164 + Legacy/Aria/src/ArActionDriveDistance.cpp | 145 + Legacy/Aria/src/ArActionGoto.cpp | 182 + Legacy/Aria/src/ArActionGotoStraight.cpp | 191 + Legacy/Aria/src/ArActionGroup.cpp | 160 + Legacy/Aria/src/ArActionGroups.cpp | 357 + Legacy/Aria/src/ArActionIRs.cpp | 243 + Legacy/Aria/src/ArActionInput.cpp | 95 + Legacy/Aria/src/ArActionJoydrive.cpp | 191 + Legacy/Aria/src/ArActionKeydrive.cpp | 236 + Legacy/Aria/src/ArActionLimiterBackwards.cpp | 115 + Legacy/Aria/src/ArActionLimiterForwards.cpp | 134 + Legacy/Aria/src/ArActionLimiterRot.cpp | 186 + .../Aria/src/ArActionLimiterTableSensor.cpp | 56 + .../Aria/src/ArActionMovementParameters.cpp | 230 + .../ArActionMovementParametersDebugging.cpp | 285 + Legacy/Aria/src/ArActionRatioInput.cpp | 523 + Legacy/Aria/src/ArActionRobotJoydrive.cpp | 175 + Legacy/Aria/src/ArActionStallRecover.cpp | 308 + Legacy/Aria/src/ArActionStop.cpp | 54 + Legacy/Aria/src/ArActionTriangleDriveTo.cpp | 964 + Legacy/Aria/src/ArActionTurn.cpp | 119 + Legacy/Aria/src/ArAnalogGyro.cpp | 347 + Legacy/Aria/src/ArArg.cpp | 487 + Legacy/Aria/src/ArArgumentBuilder.cpp | 969 + Legacy/Aria/src/ArArgumentParser.cpp | 884 + Legacy/Aria/src/ArBasePacket.cpp | 682 + Legacy/Aria/src/ArBatteryConnector.cpp | 723 + Legacy/Aria/src/ArBatteryMTX.cpp | 1291 + Legacy/Aria/src/ArBumpers.cpp | 161 + Legacy/Aria/src/ArCameraCollection.cpp | 668 + Legacy/Aria/src/ArCameraCommands.cpp | 60 + Legacy/Aria/src/ArCondition_LIN.cpp | 256 + Legacy/Aria/src/ArCondition_WIN.cpp | 155 + Legacy/Aria/src/ArConfig.cpp | 3481 + Legacy/Aria/src/ArConfigArg.cpp | 4087 + Legacy/Aria/src/ArConfigGroup.cpp | 130 + Legacy/Aria/src/ArDPPTU.cpp | 915 + Legacy/Aria/src/ArDataLogger.cpp | 688 + Legacy/Aria/src/ArDeviceConnection.cpp | 201 + Legacy/Aria/src/ArFileParser.cpp | 707 + Legacy/Aria/src/ArForbiddenRangeDevice.cpp | 219 + Legacy/Aria/src/ArFunctorASyncTask.cpp | 47 + Legacy/Aria/src/ArGPS.cpp | 837 + Legacy/Aria/src/ArGPSConnector.cpp | 231 + Legacy/Aria/src/ArGPSCoords.cpp | 317 + Legacy/Aria/src/ArGripper.cpp | 544 + Legacy/Aria/src/ArIRs.cpp | 169 + Legacy/Aria/src/ArInterpolation.cpp | 325 + Legacy/Aria/src/ArIrrfDevice.cpp | 183 + Legacy/Aria/src/ArJoyHandler.cpp | 330 + Legacy/Aria/src/ArJoyHandler_LIN.cpp | 189 + Legacy/Aria/src/ArJoyHandler_WIN.cpp | 300 + Legacy/Aria/src/ArKeyHandler.cpp | 468 + Legacy/Aria/src/ArLCDConnector.cpp | 1185 + Legacy/Aria/src/ArLCDMTX.cpp | 2138 + Legacy/Aria/src/ArLMS1XX.cpp | 3047 + Legacy/Aria/src/ArLMS2xx.cpp | 1695 + Legacy/Aria/src/ArLMS2xxPacket.cpp | 197 + Legacy/Aria/src/ArLMS2xxPacketReceiver.cpp | 273 + Legacy/Aria/src/ArLaser.cpp | 1401 + Legacy/Aria/src/ArLaserConnector.cpp | 1569 + Legacy/Aria/src/ArLaserFilter.cpp | 512 + Legacy/Aria/src/ArLaserLogger.cpp | 872 + Legacy/Aria/src/ArLaserReflectorDevice.cpp | 119 + Legacy/Aria/src/ArLineFinder.cpp | 730 + Legacy/Aria/src/ArLog.cpp | 863 + Legacy/Aria/src/ArLogFileConnection.cpp | 272 + Legacy/Aria/src/ArMD5Calculator.cpp | 190 + Legacy/Aria/src/ArMTXIO.cpp | 1491 + Legacy/Aria/src/ArMap.cpp | 1612 + Legacy/Aria/src/ArMapComponents.cpp | 6217 ++ Legacy/Aria/src/ArMapInterface.cpp | 208 + Legacy/Aria/src/ArMapObject.cpp | 588 + Legacy/Aria/src/ArMapUtils.cpp | 1240 + Legacy/Aria/src/ArMode.cpp | 277 + Legacy/Aria/src/ArModes.cpp | 2538 + Legacy/Aria/src/ArModule.cpp | 38 + Legacy/Aria/src/ArModuleLoader.cpp | 252 + Legacy/Aria/src/ArMutex.cpp | 117 + Legacy/Aria/src/ArMutex_LIN.cpp | 336 + Legacy/Aria/src/ArMutex_WIN.cpp | 272 + Legacy/Aria/src/ArNMEAParser.cpp | 284 + Legacy/Aria/src/ArNetServer.cpp | 720 + Legacy/Aria/src/ArNovatelGPS.cpp | 158 + Legacy/Aria/src/ArP2Arm.cpp | 784 + Legacy/Aria/src/ArPTZ.cpp | 183 + Legacy/Aria/src/ArPTZConnector.cpp | 316 + Legacy/Aria/src/ArPriorityResolver.cpp | 107 + Legacy/Aria/src/ArRVisionPTZ.cpp | 341 + Legacy/Aria/src/ArRangeBuffer.cpp | 543 + Legacy/Aria/src/ArRangeDevice.cpp | 629 + Legacy/Aria/src/ArRangeDeviceThreaded.cpp | 46 + Legacy/Aria/src/ArRatioInputJoydrive.cpp | 153 + Legacy/Aria/src/ArRatioInputKeydrive.cpp | 247 + Legacy/Aria/src/ArRatioInputRobotJoydrive.cpp | 139 + Legacy/Aria/src/ArRecurrentTask.cpp | 153 + Legacy/Aria/src/ArRobot.cpp | 7458 ++ .../Aria/src/ArRobotBatteryPacketReader.cpp | 122 + Legacy/Aria/src/ArRobotConfig.cpp | 193 + Legacy/Aria/src/ArRobotConfigPacketReader.cpp | 361 + Legacy/Aria/src/ArRobotConnector.cpp | 508 + Legacy/Aria/src/ArRobotJoyHandler.cpp | 172 + Legacy/Aria/src/ArRobotPacket.cpp | 184 + Legacy/Aria/src/ArRobotPacketReaderThread.cpp | 89 + Legacy/Aria/src/ArRobotPacketReceiver.cpp | 393 + Legacy/Aria/src/ArRobotPacketSender.cpp | 369 + Legacy/Aria/src/ArRobotParams.cpp | 1662 + Legacy/Aria/src/ArRobotTypes.cpp | 2449 + Legacy/Aria/src/ArS3Series.cpp | 1456 + Legacy/Aria/src/ArSZSeries.cpp | 1178 + Legacy/Aria/src/ArSensorReading.cpp | 203 + Legacy/Aria/src/ArSerialConnection_LIN.cpp | 639 + Legacy/Aria/src/ArSerialConnection_WIN.cpp | 459 + Legacy/Aria/src/ArSick.cpp | 226 + Legacy/Aria/src/ArSignalHandler_LIN.cpp | 342 + Legacy/Aria/src/ArSignalHandler_WIN.cpp | 186 + Legacy/Aria/src/ArSimpleConnector.cpp | 274 + Legacy/Aria/src/ArSimulatedLaser.cpp | 567 + Legacy/Aria/src/ArSocket.cpp | 555 + Legacy/Aria/src/ArSocket_LIN.cpp | 723 + Legacy/Aria/src/ArSocket_WIN.cpp | 813 + Legacy/Aria/src/ArSonarAutoDisabler.cpp | 128 + Legacy/Aria/src/ArSonarConnector.cpp | 860 + Legacy/Aria/src/ArSonarDevice.cpp | 162 + Legacy/Aria/src/ArSonarMTX.cpp | 2083 + Legacy/Aria/src/ArSonyPTZ.cpp | 285 + Legacy/Aria/src/ArSoundPlayer.cpp | 311 + Legacy/Aria/src/ArSoundsQueue.cpp | 759 + Legacy/Aria/src/ArSpeech.cpp | 123 + Legacy/Aria/src/ArStringInfoGroup.cpp | 160 + Legacy/Aria/src/ArSyncLoop.cpp | 173 + Legacy/Aria/src/ArSyncTask.cpp | 398 + Legacy/Aria/src/ArSystemStatus.cpp | 362 + Legacy/Aria/src/ArTCM2.cpp | 181 + Legacy/Aria/src/ArTCMCompassDirect.cpp | 170 + Legacy/Aria/src/ArTCMCompassRobot.cpp | 80 + Legacy/Aria/src/ArTcpConnection.cpp | 274 + Legacy/Aria/src/ArThread.cpp | 291 + Legacy/Aria/src/ArThread_LIN.cpp | 348 + Legacy/Aria/src/ArThread_WIN.cpp | 266 + Legacy/Aria/src/ArTransform.cpp | 88 + Legacy/Aria/src/ArTrimbleGPS.cpp | 190 + Legacy/Aria/src/ArUrg.cpp | 816 + Legacy/Aria/src/ArUrg_2_0.cpp | 1065 + Legacy/Aria/src/ArVCC4.cpp | 2355 + Legacy/Aria/src/ArVersalogicIO.cpp | 360 + Legacy/Aria/src/Aria.cpp | 1264 + Legacy/Aria/src/AriaDLL-vc2003.vcproj | 2485 + Legacy/Aria/src/AriaDLL-vc2008.vcproj | 3171 + Legacy/Aria/src/AriaDLL-vc2010.vcxproj | 1957 + Legacy/Aria/src/AriaStatic-vc2003.sln | 21 + Legacy/Aria/src/AriaStatic-vc2003.vcproj | 2436 + Legacy/Aria/src/AriaStatic-vc2008.vcproj | 3114 + Legacy/Aria/src/AriaStatic-vc2010.vcxproj | 1140 + Legacy/Aria/src/AriaStatic.sln | 21 + Legacy/Aria/src/Makefile | 14 + Legacy/Aria/src/ariaUtil.cpp | 2669 + Legacy/Aria/src/md5.cpp | 415 + Legacy/Aria/tests/ArTestConfig.cpp | 731 + Legacy/Aria/tests/ArTestConfig.h | 36 + Legacy/Aria/tests/AriaTests-vc2003.sln | 48 + Legacy/Aria/tests/AriaTests-vc2008.sln | 100 + Legacy/Aria/tests/Makefile | 28 + Legacy/Aria/tests/README.txt | 150 + .../Aria/tests/absoluteHeadingActionTest.cpp | 160 + Legacy/Aria/tests/accDecelMaxTest.cpp | 192 + Legacy/Aria/tests/actionArgumentTest.cpp | 150 + Legacy/Aria/tests/actionAverageTest.cpp | 53 + .../tests/actionManagementTest-vc2008.vcproj | 194 + Legacy/Aria/tests/actionManagementTest.cpp | 88 + Legacy/Aria/tests/actsTest.cpp | 62 + Legacy/Aria/tests/angleBetweenTest.cpp | 93 + Legacy/Aria/tests/angleFixTest.cpp | 77 + Legacy/Aria/tests/angleTest.cpp | 188 + Legacy/Aria/tests/asyncConnectTest.cpp | 167 + Legacy/Aria/tests/auxSerialTest.cpp | 166 + Legacy/Aria/tests/batteryTest.cpp | 107 + Legacy/Aria/tests/callbackTest.cpp | 96 + Legacy/Aria/tests/chargeTest.cpp | 88 + Legacy/Aria/tests/compassDirect.cpp | 65 + Legacy/Aria/tests/compassDirectCalib.cpp | 46 + .../tests/configSectionTest-vc2008.vcproj | 180 + Legacy/Aria/tests/configSectionTest.cpp | 196 + Legacy/Aria/tests/configTest-vc2008.vcproj | 191 + Legacy/Aria/tests/configTest.cpp | 181 + Legacy/Aria/tests/configTest.txt | 8 + Legacy/Aria/tests/connectTest.cpp | 150 + Legacy/Aria/tests/connectionTest.cpp | 173 + Legacy/Aria/tests/dcdTest.cpp | 45 + Legacy/Aria/tests/deleteArgs.cpp | 130 + Legacy/Aria/tests/driveFast.cpp | 250 + Legacy/Aria/tests/driveHardDirect.cpp | 457 + Legacy/Aria/tests/encoderCorrectionTest.cpp | 194 + Legacy/Aria/tests/encoderTest.cpp | 83 + Legacy/Aria/tests/fileParserTest.cpp | 110 + Legacy/Aria/tests/fileParserTestBad.txt | 28 + Legacy/Aria/tests/fileParserTestGood.txt | 15 + Legacy/Aria/tests/functorTest.cpp | 500 + Legacy/Aria/tests/gotoTest.cpp | 129 + Legacy/Aria/tests/gpsCoordsTest.cpp | 113 + Legacy/Aria/tests/gpsInternals.cpp | 156 + Legacy/Aria/tests/gripperStateFlagsTest.cpp | 217 + Legacy/Aria/tests/gyroDrive-vc2008.vcproj | 245 + Legacy/Aria/tests/gyroDrive.cpp | 210 + Legacy/Aria/tests/gyroDrive.vcproj | 178 + Legacy/Aria/tests/hardDriveWander.cpp | 138 + Legacy/Aria/tests/interpolationTest.cpp | 118 + Legacy/Aria/tests/ioTest.cpp | 136 + Legacy/Aria/tests/joytest-vc2008.vcproj | 245 + Legacy/Aria/tests/joytest.cpp | 83 + Legacy/Aria/tests/joytest.vcproj | 178 + Legacy/Aria/tests/keyHandlerTest.cpp | 93 + Legacy/Aria/tests/keys.cpp | 137 + Legacy/Aria/tests/lineTest.cpp | 158 + Legacy/Aria/tests/lms2xxTest.cpp | 82 + Legacy/Aria/tests/logRobotJoystick.cpp | 75 + Legacy/Aria/tests/logSIPData.cpp | 235 + Legacy/Aria/tests/logSIPs.cpp | 75 + Legacy/Aria/tests/mapTest-vc2003.vcproj | 178 + Legacy/Aria/tests/mapTest.cpp | 170 + Legacy/Aria/tests/mathTests.cpp | 46 + Legacy/Aria/tests/moduleActionExample.cpp | 113 + .../Aria/tests/moduleActionExample2_Mod.cpp | 79 + Legacy/Aria/tests/moduleActionExample_Mod.cpp | 94 + Legacy/Aria/tests/moveCommandTest.cpp | 84 + Legacy/Aria/tests/moveRobotInSim.cpp | 90 + Legacy/Aria/tests/moveRobotTest.cpp | 272 + Legacy/Aria/tests/mtxIOTest.cpp | 117 + .../Aria/tests/mutexLockWarning-vc2008.vcproj | 245 + Legacy/Aria/tests/mutexLockWarning.cpp | 87 + Legacy/Aria/tests/nmeaParser.cpp | 100 + Legacy/Aria/tests/optoIOtest.cpp | 275 + Legacy/Aria/tests/p2osSlamTest.cpp | 144 + Legacy/Aria/tests/poseTest.cpp | 75 + Legacy/Aria/tests/ptzTest.cpp | 160 + .../tests/robotConfigPacketReaderTest.cpp | 76 + Legacy/Aria/tests/robotListTest.cpp | 110 + Legacy/Aria/tests/robotPacketHandlerTest.cpp | 65 + Legacy/Aria/tests/rotVelActionExample.cpp | 310 + Legacy/Aria/tests/runtimeTest.cpp | 373 + Legacy/Aria/tests/samePriorityActionTest.cpp | 100 + Legacy/Aria/tests/serialDump.cpp | 91 + Legacy/Aria/tests/serialTest.cpp | 104 + Legacy/Aria/tests/serialTest2.cpp | 87 + Legacy/Aria/tests/showFirmwareParameters.cpp | 127 + Legacy/Aria/tests/sickMiddleTest.cpp | 112 + Legacy/Aria/tests/sickQuadrantReadings.cpp | 108 + Legacy/Aria/tests/sickSafeAutoLogger.cpp | 269 + Legacy/Aria/tests/sickSimpleTest.cpp | 168 + Legacy/Aria/tests/sickTest.cpp | 127 + Legacy/Aria/tests/sickTestAll.cpp | 124 + Legacy/Aria/tests/signalTest.cpp | 137 + Legacy/Aria/tests/sonarAutoDisablerTest.cpp | 83 + Legacy/Aria/tests/sonarDeviceTest.cpp | 123 + Legacy/Aria/tests/sonarMonitor.cpp | 115 + Legacy/Aria/tests/sonarQuadrantReadings.cpp | 101 + Legacy/Aria/tests/sonarTest.cpp | 93 + Legacy/Aria/tests/soundPlayer.cpp | 97 + Legacy/Aria/tests/stallTest.cpp | 72 + Legacy/Aria/tests/stressTest.cpp | 155 + Legacy/Aria/tests/stripQuoteTest.cpp | 56 + Legacy/Aria/tests/systemCallTest.cpp | 159 + Legacy/Aria/tests/systemStatusBasic.cpp | 63 + Legacy/Aria/tests/systemStatusThread.cpp | 45 + Legacy/Aria/tests/tcm2Test.cpp | 101 + Legacy/Aria/tests/tcpConnectionTest.cpp | 70 + .../Aria/tests/testAbsoluteMaxesCommand.cpp | 151 + Legacy/Aria/tests/testCOM.cpp | 466 + Legacy/Aria/tests/testMobileSim.cpp | 812 + Legacy/Aria/tests/testsound.sw.raw | Bin 0 -> 54180 bytes Legacy/Aria/tests/threadTest.cpp | 138 + Legacy/Aria/tests/timePrinter.cpp | 46 + Legacy/Aria/tests/timeTest.cpp | 156 + Legacy/Aria/tests/timingTest-vc2008.vcproj | 180 + Legacy/Aria/tests/timingTest.cpp | 70 + Legacy/Aria/tests/transformTest.cpp | 50 + Legacy/Aria/tests/triangleAccuracyTest.cpp | 232 + Legacy/Aria/tests/usertasktest.cpp | 127 + Legacy/Aria/tests/vcc4Test.cpp | 492 + Legacy/Aria/tests/velTest.cpp | 218 + Legacy/Aria/tests/wanderAndLogBumps.cpp | 223 + Legacy/Aria/utils/Makefile | 12 + Legacy/Aria/utils/addSfWorldLinesToArMap.cpp | 104 + Legacy/Aria/utils/convertSfWorldToArMap.cpp | 117 + .../Aria/utils/genCommandLineOptionDocs.cpp | 400 + .../utils/genCommandLineOptionDocs.vcxproj | 91 + ...mmandLineOptionDocsForArNetworking.vcxproj | 91 + Legacy/Aria/utils/makeParams | Bin 0 -> 14872 bytes Legacy/Aria/utils/makeParams.cpp | 91 + Legacy/Aria/utils/makeParams.vcproj | 175 + Legacy/Aria/utils/makeParams.vcxproj | 91 + Legacy/Aria/version.txt | 5 + Legacy/Dockerfile | 11 + Legacy/entrypoint.sh | 26 + Legacy/ws_linux/.catkin_workspace | 1 + Legacy/ws_linux/build/CATKIN_IGNORE | 0 Legacy/ws_linux/build/CMakeCache.txt | 572 + .../build/CMakeFiles/CMakeCCompiler.cmake | 49 + .../build/CMakeFiles/CMakeCXXCompiler.cmake | 50 + .../CMakeDetermineCompilerABI_C.bin | Bin 0 -> 8413 bytes .../CMakeDetermineCompilerABI_CXX.bin | Bin 0 -> 8426 bytes .../CMakeDirectoryInformation.cmake | 22 + .../ws_linux/build/CMakeFiles/CMakeError.log | 19 + .../ws_linux/build/CMakeFiles/CMakeOutput.log | 293 + .../build/CMakeFiles/CMakeRuleHashes.txt | 84 + .../build/CMakeFiles/CMakeSystem.cmake | 15 + .../CMakeFiles/CompilerIdC/CMakeCCompilerId.c | 232 + .../build/CMakeFiles/CompilerIdC/a.out | Bin 0 -> 8472 bytes .../CompilerIdCXX/CMakeCXXCompilerId.cpp | 215 + .../build/CMakeFiles/CompilerIdCXX/a.out | Bin 0 -> 8476 bytes .../ws_linux/build/CMakeFiles/Makefile.cmake | 324 + Legacy/ws_linux/build/CMakeFiles/Makefile2 | 2482 + .../build/CMakeFiles/TargetDirectories.txt | 72 + .../clean_test_results.dir/DependInfo.cmake | 13 + .../clean_test_results.dir/build.make | 63 + .../clean_test_results.dir/cmake_clean.cmake | 8 + .../clean_test_results.dir/progress.make | 1 + .../build/CMakeFiles/cmake.check_cache | 1 + .../CMakeFiles/doxygen.dir/DependInfo.cmake | 13 + .../build/CMakeFiles/doxygen.dir/build.make | 64 + .../CMakeFiles/doxygen.dir/cmake_clean.cmake | 8 + .../CMakeFiles/doxygen.dir/progress.make | 2 + .../ws_linux/build/CMakeFiles/progress.marks | 1 + .../CMakeFiles/run_tests.dir/DependInfo.cmake | 13 + .../build/CMakeFiles/run_tests.dir/build.make | 62 + .../run_tests.dir/cmake_clean.cmake | 8 + .../CMakeFiles/run_tests.dir/progress.make | 1 + .../CMakeFiles/tests.dir/DependInfo.cmake | 13 + .../build/CMakeFiles/tests.dir/build.make | 62 + .../CMakeFiles/tests.dir/cmake_clean.cmake | 8 + .../build/CMakeFiles/tests.dir/progress.make | 1 + Legacy/ws_linux/build/CTestTestfile.cmake | 11 + Legacy/ws_linux/build/Makefile | 1183 + .../catkin_generated/version/package.cmake | 9 + .../build/catkin_generated/env_cached.sh | 16 + .../catkin_generated/generate_cached_setup.py | 29 + .../catkin_generated/installspace/.rosinstall | 2 + .../installspace/_setup_util.py | 280 + .../catkin_generated/installspace/env.sh | 16 + .../catkin_generated/installspace/setup.bash | 8 + .../catkin_generated/installspace/setup.sh | 87 + .../catkin_generated/installspace/setup.zsh | 8 + .../catkin_generated/order_packages.cmake | 26 + .../build/catkin_generated/order_packages.py | 5 + .../build/catkin_generated/setup_cached.sh | 12 + .../Project/interrogate_setup_dot_py.py.stamp | 250 + .../Project/order_packages.cmake.em.stamp | 56 + .../stamps/Project/package.xml.stamp | 36 + Legacy/ws_linux/build/catkin_make.cache | 1 + Legacy/ws_linux/build/cmake_install.cmake | 108 + .../CMakeDirectoryInformation.cmake | 24 + .../CMakeFiles/gtest.dir/DependInfo.cmake | 18 + .../gtest/CMakeFiles/gtest.dir/build.make | 99 + .../CMakeFiles/gtest.dir/cmake_clean.cmake | 10 + .../gtest/CMakeFiles/gtest.dir/depend.make | 2 + .../gtest/CMakeFiles/gtest.dir/flags.make | 10 + .../build/gtest/CMakeFiles/gtest.dir/link.txt | 1 + .../gtest/CMakeFiles/gtest.dir/progress.make | 2 + .../gtest_main.dir/DependInfo.cmake | 19 + .../CMakeFiles/gtest_main.dir/build.make | 100 + .../gtest_main.dir/cmake_clean.cmake | 10 + .../CMakeFiles/gtest_main.dir/depend.make | 2 + .../CMakeFiles/gtest_main.dir/flags.make | 10 + .../gtest/CMakeFiles/gtest_main.dir/link.txt | 1 + .../CMakeFiles/gtest_main.dir/progress.make | 2 + .../build/gtest/CMakeFiles/progress.marks | 1 + .../ws_linux/build/gtest/CTestTestfile.cmake | 6 + Legacy/ws_linux/build/gtest/Makefile | 259 + .../ws_linux/build/gtest/cmake_install.cmake | 34 + .../CMakeDirectoryInformation.cmake | 25 + .../CMakeFiles/RosAria.dir/CXX.includecache | 3750 + .../CMakeFiles/RosAria.dir/DependInfo.cmake | 21 + .../CMakeFiles/RosAria.dir/RosAria.cpp.o | Bin 0 -> 3018152 bytes .../rosaria/CMakeFiles/RosAria.dir/build.make | 126 + .../CMakeFiles/RosAria.dir/cmake_clean.cmake | 10 + .../CMakeFiles/RosAria.dir/depend.internal | 302 + .../CMakeFiles/RosAria.dir/depend.make | 302 + .../rosaria/CMakeFiles/RosAria.dir/flags.make | 10 + .../rosaria/CMakeFiles/RosAria.dir/link.txt | 1 + .../CMakeFiles/RosAria.dir/progress.make | 2 + .../DependInfo.cmake | 16 + .../build.make | 62 + .../cmake_clean.cmake | 8 + .../progress.make | 1 + .../DependInfo.cmake | 16 + .../build.make | 62 + .../cmake_clean.cmake | 8 + .../progress.make | 1 + .../DependInfo.cmake | 16 + .../build.make | 62 + .../cmake_clean.cmake | 8 + .../progress.make | 1 + .../DependInfo.cmake | 16 + .../build.make | 62 + .../cmake_clean.cmake | 8 + .../progress.make | 1 + .../DependInfo.cmake | 16 + .../build.make | 62 + .../cmake_clean.cmake | 8 + .../progress.make | 1 + .../DependInfo.cmake | 16 + .../build.make | 62 + .../cmake_clean.cmake | 8 + .../progress.make | 1 + .../DependInfo.cmake | 16 + .../dynamic_reconfigure_gencfg.dir/build.make | 62 + .../cmake_clean.cmake | 8 + .../progress.make | 1 + .../DependInfo.cmake | 16 + .../build.make | 62 + .../cmake_clean.cmake | 8 + .../progress.make | 1 + .../DependInfo.cmake | 16 + .../build.make | 62 + .../cmake_clean.cmake | 8 + .../progress.make | 1 + .../DependInfo.cmake | 16 + .../build.make | 62 + .../cmake_clean.cmake | 8 + .../progress.make | 1 + .../DependInfo.cmake | 16 + .../build.make | 62 + .../cmake_clean.cmake | 8 + .../progress.make | 1 + .../DependInfo.cmake | 16 + .../build.make | 62 + .../cmake_clean.cmake | 8 + .../progress.make | 1 + .../DependInfo.cmake | 16 + .../build.make | 62 + .../cmake_clean.cmake | 8 + .../progress.make | 1 + .../build/rosaria/CMakeFiles/progress.marks | 1 + .../rosaria_gencfg.dir/DependInfo.cmake | 25 + .../CMakeFiles/rosaria_gencfg.dir/build.make | 83 + .../rosaria_gencfg.dir/cmake_clean.cmake | 13 + .../rosaria_gencfg.dir/depend.internal | 3 + .../CMakeFiles/rosaria_gencfg.dir/depend.make | 3 + .../rosaria_gencfg.dir/progress.make | 2 + .../rosaria_gencpp.dir/DependInfo.cmake | 16 + .../CMakeFiles/rosaria_gencpp.dir/build.make | 62 + .../rosaria_gencpp.dir/cmake_clean.cmake | 8 + .../rosaria_gencpp.dir/depend.internal | 3 + .../CMakeFiles/rosaria_gencpp.dir/depend.make | 3 + .../rosaria_gencpp.dir/progress.make | 1 + .../DependInfo.cmake | 16 + .../rosaria_generate_messages.dir/build.make | 62 + .../cmake_clean.cmake | 8 + .../depend.internal | 3 + .../rosaria_generate_messages.dir/depend.make | 3 + .../progress.make | 1 + .../DependInfo.cmake | 16 + .../build.make | 71 + .../cmake_clean.cmake | 9 + .../depend.internal | 3 + .../depend.make | 3 + .../progress.make | 2 + .../DependInfo.cmake | 16 + .../build.make | 70 + .../cmake_clean.cmake | 9 + .../depend.internal | 3 + .../depend.make | 3 + .../progress.make | 2 + .../DependInfo.cmake | 16 + .../build.make | 78 + .../cmake_clean.cmake | 10 + .../depend.internal | 3 + .../depend.make | 3 + .../progress.make | 3 + .../rosaria_genlisp.dir/DependInfo.cmake | 16 + .../CMakeFiles/rosaria_genlisp.dir/build.make | 62 + .../rosaria_genlisp.dir/cmake_clean.cmake | 8 + .../rosaria_genlisp.dir/progress.make | 1 + .../rosaria_genpy.dir/DependInfo.cmake | 16 + .../CMakeFiles/rosaria_genpy.dir/build.make | 62 + .../rosaria_genpy.dir/cmake_clean.cmake | 8 + .../rosaria_genpy.dir/progress.make | 1 + .../DependInfo.cmake | 16 + .../build.make | 62 + .../cmake_clean.cmake | 8 + .../progress.make | 1 + .../DependInfo.cmake | 16 + .../build.make | 62 + .../cmake_clean.cmake | 8 + .../progress.make | 1 + .../DependInfo.cmake | 16 + .../build.make | 62 + .../cmake_clean.cmake | 8 + .../progress.make | 1 + .../DependInfo.cmake | 16 + .../build.make | 62 + .../cmake_clean.cmake | 8 + .../progress.make | 1 + .../DependInfo.cmake | 16 + .../build.make | 62 + .../cmake_clean.cmake | 8 + .../progress.make | 1 + .../DependInfo.cmake | 16 + .../build.make | 62 + .../cmake_clean.cmake | 8 + .../progress.make | 1 + .../DependInfo.cmake | 16 + .../build.make | 62 + .../cmake_clean.cmake | 8 + .../progress.make | 1 + .../DependInfo.cmake | 16 + .../build.make | 62 + .../cmake_clean.cmake | 8 + .../progress.make | 1 + .../DependInfo.cmake | 16 + .../build.make | 62 + .../cmake_clean.cmake | 8 + .../progress.make | 1 + .../DependInfo.cmake | 16 + .../build.make | 62 + .../cmake_clean.cmake | 8 + .../progress.make | 1 + .../DependInfo.cmake | 16 + .../build.make | 62 + .../cmake_clean.cmake | 8 + .../progress.make | 1 + .../DependInfo.cmake | 16 + .../build.make | 62 + .../cmake_clean.cmake | 8 + .../progress.make | 1 + .../DependInfo.cmake | 16 + .../tf_generate_messages_cpp.dir/build.make | 62 + .../cmake_clean.cmake | 8 + .../progress.make | 1 + .../DependInfo.cmake | 16 + .../tf_generate_messages_lisp.dir/build.make | 62 + .../cmake_clean.cmake | 8 + .../progress.make | 1 + .../DependInfo.cmake | 16 + .../tf_generate_messages_py.dir/build.make | 62 + .../cmake_clean.cmake | 8 + .../tf_generate_messages_py.dir/progress.make | 1 + .../build/rosaria/CTestTestfile.cmake | 6 + Legacy/ws_linux/build/rosaria/Makefile | 757 + .../installspace/rosaria-msg-extras.cmake | 2 + .../installspace/rosaria-msg-paths-context.py | 8 + .../installspace/rosaria-msg-paths.cmake | 5 + .../catkin_generated/installspace/rosaria.pc | 8 + .../installspace/rosariaConfig-version.cmake | 14 + .../installspace/rosariaConfig.cmake | 191 + .../catkin_generated/ordered_paths.cmake | 1 + .../rosaria/catkin_generated/package.cmake | 7 + .../pkg.develspace.context.pc.py | 8 + .../pkg.installspace.context.pc.py | 8 + .../rosaria-msg-extras.cmake.develspace.in | 2 + .../rosaria-msg-extras.cmake.installspace.in | 2 + .../rosaria-msg-paths-context.py | 8 + .../stamps/rosaria/package.xml.stamp | 0 .../stamps/rosaria/pkg-genmsg.cmake.em.stamp | 141 + .../rosaria/pkg-msg-paths.cmake.em.stamp | 10 + .../stamps/rosaria/pkg.pc.em.stamp | 8 + .../rosaria/cmake/rosaria-genmsg-context.py | 10 + .../build/rosaria/cmake/rosaria-genmsg.cmake | 136 + .../build/rosaria/cmake_install.cmake | 111 + .../CMakeDirectoryInformation.cmake | 24 + .../DependInfo.cmake | 13 + .../build.make | 62 + .../cmake_clean.cmake | 8 + .../depend.internal | 3 + .../depend.make | 3 + .../progress.make | 1 + .../DependInfo.cmake | 13 + .../build.make | 62 + .../cmake_clean.cmake | 8 + .../depend.internal | 3 + .../depend.make | 3 + .../progress.make | 1 + .../DependInfo.cmake | 13 + .../build.make | 62 + .../cmake_clean.cmake | 8 + .../depend.internal | 3 + .../depend.make | 3 + .../progress.make | 1 + .../rosaria_msgs/CMakeFiles/progress.marks | 1 + .../rosaria_msgs_gencpp.dir/DependInfo.cmake | 13 + .../rosaria_msgs_gencpp.dir/build.make | 62 + .../rosaria_msgs_gencpp.dir/cmake_clean.cmake | 8 + .../rosaria_msgs_gencpp.dir/progress.make | 1 + .../DependInfo.cmake | 13 + .../build.make | 62 + .../cmake_clean.cmake | 8 + .../depend.internal | 3 + .../depend.make | 3 + .../progress.make | 1 + .../DependInfo.cmake | 13 + .../build.make | 85 + .../cmake_clean.cmake | 10 + .../depend.internal | 3 + .../depend.make | 3 + .../progress.make | 3 + .../DependInfo.cmake | 13 + .../build.make | 83 + .../cmake_clean.cmake | 10 + .../depend.internal | 3 + .../depend.make | 3 + .../progress.make | 3 + .../DependInfo.cmake | 13 + .../build.make | 92 + .../cmake_clean.cmake | 11 + .../depend.internal | 3 + .../depend.make | 3 + .../progress.make | 4 + .../rosaria_msgs_genlisp.dir/DependInfo.cmake | 13 + .../rosaria_msgs_genlisp.dir/build.make | 62 + .../cmake_clean.cmake | 8 + .../rosaria_msgs_genlisp.dir/progress.make | 1 + .../rosaria_msgs_genpy.dir/DependInfo.cmake | 13 + .../rosaria_msgs_genpy.dir/build.make | 62 + .../rosaria_msgs_genpy.dir/cmake_clean.cmake | 8 + .../rosaria_msgs_genpy.dir/progress.make | 1 + .../DependInfo.cmake | 13 + .../build.make | 62 + .../cmake_clean.cmake | 8 + .../depend.internal | 3 + .../depend.make | 3 + .../progress.make | 1 + .../DependInfo.cmake | 13 + .../build.make | 62 + .../cmake_clean.cmake | 8 + .../depend.internal | 3 + .../depend.make | 3 + .../progress.make | 1 + .../DependInfo.cmake | 13 + .../build.make | 62 + .../cmake_clean.cmake | 8 + .../depend.internal | 3 + .../depend.make | 3 + .../progress.make | 1 + .../build/rosaria_msgs/CTestTestfile.cmake | 6 + Legacy/ws_linux/build/rosaria_msgs/Makefile | 370 + .../rosaria_msgs-msg-extras.cmake | 2 + .../rosaria_msgs-msg-paths-context.py | 8 + .../installspace/rosaria_msgs-msg-paths.cmake | 5 + .../installspace/rosaria_msgs.pc | 8 + .../rosaria_msgsConfig-version.cmake | 14 + .../installspace/rosaria_msgsConfig.cmake | 191 + .../catkin_generated/ordered_paths.cmake | 1 + .../catkin_generated/package.cmake | 7 + .../pkg.develspace.context.pc.py | 8 + .../pkg.installspace.context.pc.py | 8 + ...osaria_msgs-msg-extras.cmake.develspace.in | 2 + ...aria_msgs-msg-extras.cmake.installspace.in | 2 + .../rosaria_msgs-msg-paths-context.py | 8 + .../stamps/rosaria_msgs/package.xml.stamp | 21 + .../rosaria_msgs/pkg-genmsg.cmake.em.stamp | 141 + .../rosaria_msgs/pkg-msg-paths.cmake.em.stamp | 10 + .../stamps/rosaria_msgs/pkg.pc.em.stamp | 8 + .../cmake/rosaria_msgs-genmsg-context.py | 10 + .../cmake/rosaria_msgs-genmsg.cmake | 154 + .../build/rosaria_msgs/cmake_install.cmake | 80 + .../CMakeDirectoryInformation.cmake | 25 + .../cloud_reader.dir/CXX.includecache | 1026 + .../cloud_reader.dir/DependInfo.cmake | 20 + .../CMakeFiles/cloud_reader.dir/build.make | 121 + .../cloud_reader.dir/cmake_clean.cmake | 10 + .../cloud_reader.dir/depend.internal | 83 + .../CMakeFiles/cloud_reader.dir/depend.make | 83 + .../CMakeFiles/cloud_reader.dir/flags.make | 8 + .../CMakeFiles/cloud_reader.dir/link.txt | 1 + .../CMakeFiles/cloud_reader.dir/progress.make | 2 + .../cloud_reader.dir/src/cloud_reader.cpp.o | Bin 0 -> 681648 bytes .../build/safety/CMakeFiles/progress.marks | 1 + .../safety_gencpp.dir/DependInfo.cmake | 15 + .../CMakeFiles/safety_gencpp.dir/build.make | 62 + .../safety_gencpp.dir/cmake_clean.cmake | 8 + .../safety_gencpp.dir/progress.make | 1 + .../DependInfo.cmake | 15 + .../safety_generate_messages.dir/build.make | 62 + .../cmake_clean.cmake | 8 + .../depend.internal | 3 + .../safety_generate_messages.dir/depend.make | 3 + .../progress.make | 1 + .../DependInfo.cmake | 15 + .../build.make | 62 + .../cmake_clean.cmake | 8 + .../depend.internal | 3 + .../depend.make | 3 + .../progress.make | 1 + .../DependInfo.cmake | 15 + .../build.make | 62 + .../cmake_clean.cmake | 8 + .../depend.internal | 3 + .../depend.make | 3 + .../progress.make | 1 + .../DependInfo.cmake | 15 + .../build.make | 62 + .../cmake_clean.cmake | 8 + .../depend.internal | 3 + .../depend.make | 3 + .../progress.make | 1 + .../safety_genlisp.dir/DependInfo.cmake | 15 + .../CMakeFiles/safety_genlisp.dir/build.make | 62 + .../safety_genlisp.dir/cmake_clean.cmake | 8 + .../safety_genlisp.dir/progress.make | 1 + .../safety_genpy.dir/DependInfo.cmake | 15 + .../CMakeFiles/safety_genpy.dir/build.make | 62 + .../safety_genpy.dir/cmake_clean.cmake | 8 + .../CMakeFiles/safety_genpy.dir/progress.make | 1 + .../ws_linux/build/safety/CTestTestfile.cmake | 6 + Legacy/ws_linux/build/safety/Makefile | 322 + .../installspace/safety-msg-extras.cmake | 2 + .../installspace/safety-msg-paths-context.py | 8 + .../installspace/safety-msg-paths.cmake | 5 + .../catkin_generated/installspace/safety.pc | 8 + .../installspace/safetyConfig-version.cmake | 14 + .../installspace/safetyConfig.cmake | 191 + .../catkin_generated/ordered_paths.cmake | 1 + .../safety/catkin_generated/package.cmake | 7 + .../pkg.develspace.context.pc.py | 8 + .../pkg.installspace.context.pc.py | 8 + .../safety-msg-extras.cmake.develspace.in | 2 + .../safety-msg-extras.cmake.installspace.in | 2 + .../safety-msg-paths-context.py | 8 + .../stamps/safety/package.xml.stamp | 24 + .../stamps/safety/pkg-genmsg.cmake.em.stamp | 141 + .../safety/pkg-msg-paths.cmake.em.stamp | 10 + .../stamps/safety/pkg.pc.em.stamp | 8 + .../safety/cmake/safety-genmsg-context.py | 10 + .../build/safety/cmake/safety-genmsg.cmake | 117 + .../ws_linux/build/safety/cmake_install.cmake | 65 + .../CMakeDirectoryInformation.cmake | 23 + .../videostream/CMakeFiles/progress.marks | 1 + .../videostream.dir/CXX.includecache | 82 + .../videostream.dir/DependInfo.cmake | 20 + .../CMakeFiles/videostream.dir/build.make | 116 + .../videostream.dir/cmake_clean.cmake | 10 + .../videostream.dir/depend.internal | 9 + .../CMakeFiles/videostream.dir/depend.make | 9 + .../CMakeFiles/videostream.dir/flags.make | 8 + .../CMakeFiles/videostream.dir/link.txt | 1 + .../CMakeFiles/videostream.dir/progress.make | 2 + .../videostream.dir/src/videostream.cpp.o | Bin 0 -> 441808 bytes .../videostream_gencpp.dir/DependInfo.cmake | 15 + .../videostream_gencpp.dir/build.make | 62 + .../videostream_gencpp.dir/cmake_clean.cmake | 8 + .../videostream_gencpp.dir/progress.make | 1 + .../DependInfo.cmake | 15 + .../build.make | 62 + .../cmake_clean.cmake | 8 + .../depend.internal | 3 + .../depend.make | 3 + .../progress.make | 1 + .../DependInfo.cmake | 15 + .../build.make | 71 + .../cmake_clean.cmake | 9 + .../depend.internal | 3 + .../depend.make | 3 + .../progress.make | 2 + .../DependInfo.cmake | 15 + .../build.make | 69 + .../cmake_clean.cmake | 9 + .../depend.internal | 3 + .../depend.make | 3 + .../progress.make | 2 + .../DependInfo.cmake | 15 + .../build.make | 77 + .../cmake_clean.cmake | 10 + .../depend.internal | 3 + .../depend.make | 3 + .../progress.make | 3 + .../videostream_genlisp.dir/DependInfo.cmake | 15 + .../videostream_genlisp.dir/build.make | 62 + .../videostream_genlisp.dir/cmake_clean.cmake | 8 + .../videostream_genlisp.dir/progress.make | 1 + .../videostream_genpy.dir/DependInfo.cmake | 15 + .../videostream_genpy.dir/build.make | 62 + .../videostream_genpy.dir/cmake_clean.cmake | 8 + .../videostream_genpy.dir/progress.make | 1 + .../build/videostream/CTestTestfile.cmake | 6 + Legacy/ws_linux/build/videostream/Makefile | 322 + .../installspace/videostream-msg-extras.cmake | 2 + .../videostream-msg-paths-context.py | 8 + .../installspace/videostream-msg-paths.cmake | 5 + .../installspace/videostream.pc | 8 + .../videostreamConfig-version.cmake | 14 + .../installspace/videostreamConfig.cmake | 191 + .../catkin_generated/ordered_paths.cmake | 1 + .../catkin_generated/package.cmake | 7 + .../pkg.develspace.context.pc.py | 8 + .../pkg.installspace.context.pc.py | 8 + .../stamps/videostream/package.xml.stamp | 59 + .../videostream/pkg-genmsg.cmake.em.stamp | 141 + .../videostream/pkg-msg-paths.cmake.em.stamp | 10 + .../stamps/videostream/pkg.pc.em.stamp | 8 + ...videostream-msg-extras.cmake.develspace.in | 2 + ...deostream-msg-extras.cmake.installspace.in | 2 + .../videostream-msg-paths-context.py | 8 + .../cmake/videostream-genmsg-context.py | 10 + .../cmake/videostream-genmsg.cmake | 133 + .../build/videostream/cmake_install.cmake | 77 + Legacy/ws_linux/devel/.catkin | 1 + Legacy/ws_linux/devel/.rosinstall | 2 + Legacy/ws_linux/devel/_setup_util.py | 280 + Legacy/ws_linux/devel/env.sh | 16 + .../profile.d/05.catkin-test-results.sh | 4 + .../etc/catkin/profile.d/05.catkin_make.bash | 64 + .../profile.d/05.catkin_make_isolated.bash | 62 + .../devel/include/rosaria/BumperState.h | 265 + .../devel/include/rosaria/RosAriaConfig.h | 621 + .../include/rosaria_msgs/RestrictionsMsg.h | 246 + .../devel/include/rosaria_msgs/RobotInfoMsg.h | 299 + .../devel/include/videostream/ip_get.h | 156 + .../devel/include/videostream/ip_getRequest.h | 219 + .../include/videostream/ip_getResponse.h | 211 + .../ws_linux/devel/lib/pkgconfig/rosaria.pc | 8 + .../devel/lib/pkgconfig/rosaria_msgs.pc | 8 + Legacy/ws_linux/devel/lib/pkgconfig/safety.pc | 8 + .../devel/lib/pkgconfig/videostream.pc | 8 + .../dist-packages/rosaria/__init__.py | 0 .../rosaria/cfg/RosAriaConfig.py | 70 + .../dist-packages/rosaria/cfg/__init__.py | 0 .../dist-packages/rosaria/msg/_BumperState.py | 211 + .../dist-packages/rosaria/msg/__init__.py | 1 + .../dist-packages/rosaria_msgs/__init__.py | 0 .../dist-packages/rosaria_msgs/__init__.pyc | Bin 0 -> 170 bytes .../rosaria_msgs/msg/_RestrictionsMsg.py | 125 + .../rosaria_msgs/msg/_RestrictionsMsg.pyc | Bin 0 -> 5501 bytes .../rosaria_msgs/msg/_RobotInfoMsg.py | 176 + .../rosaria_msgs/msg/_RobotInfoMsg.pyc | Bin 0 -> 7564 bytes .../rosaria_msgs/msg/__init__.py | 2 + .../rosaria_msgs/msg/__init__.pyc | Bin 0 -> 251 bytes .../dist-packages/safety/__init__.py | 0 .../dist-packages/videostream/__init__.py | 0 .../dist-packages/videostream/srv/__init__.py | 1 + .../dist-packages/videostream/srv/_ip_get.py | 210 + Legacy/ws_linux/devel/lib/rosaria/RosAria | Bin 0 -> 1830828 bytes Legacy/ws_linux/devel/lib/safety/cloud_reader | Bin 0 -> 421469 bytes .../devel/lib/videostream/videostream | Bin 0 -> 286160 bytes Legacy/ws_linux/devel/setup.bash | 8 + Legacy/ws_linux/devel/setup.sh | 87 + Legacy/ws_linux/devel/setup.zsh | 8 + .../ros/rosaria/msg/BumperState.lisp | 120 + .../common-lisp/ros/rosaria/msg/_package.lisp | 7 + .../ros/rosaria/msg/_package_BumperState.lisp | 8 + .../ros/rosaria/msg/rosaria-msg.asd | 10 + .../ros/rosaria_msgs/msg/RestrictionsMsg.lisp | 92 + .../ros/rosaria_msgs/msg/RobotInfoMsg.lisp | 134 + .../ros/rosaria_msgs/msg/_package.lisp | 9 + .../msg/_package_RestrictionsMsg.lisp | 8 + .../msg/_package_RobotInfoMsg.lisp | 14 + .../ros/rosaria_msgs/msg/rosaria_msgs-msg.asd | 13 + .../ros/videostream/srv/_package.lisp | 10 + .../ros/videostream/srv/_package_ip_get.lisp | 4 + .../ros/videostream/srv/ip_get.lisp | 128 + .../ros/videostream/srv/videostream-srv.asd | 9 + .../rosaria/cmake/rosaria-msg-extras.cmake | 2 + .../rosaria/cmake/rosaria-msg-paths.cmake | 5 + .../rosaria/cmake/rosariaConfig-version.cmake | 14 + .../share/rosaria/cmake/rosariaConfig.cmake | 191 + .../rosaria/docs/RosAriaConfig-usage.dox | 15 + .../share/rosaria/docs/RosAriaConfig.dox | 14 + .../share/rosaria/docs/RosAriaConfig.wikidoc | 44 + .../cmake/rosaria_msgs-msg-extras.cmake | 2 + .../cmake/rosaria_msgs-msg-paths.cmake | 5 + .../cmake/rosaria_msgsConfig-version.cmake | 14 + .../cmake/rosaria_msgsConfig.cmake | 191 + .../safety/cmake/safety-msg-extras.cmake | 2 + .../share/safety/cmake/safety-msg-paths.cmake | 5 + .../safety/cmake/safetyConfig-version.cmake | 14 + .../share/safety/cmake/safetyConfig.cmake | 191 + .../cmake/videostream-msg-extras.cmake | 2 + .../cmake/videostream-msg-paths.cmake | 5 + .../cmake/videostreamConfig-version.cmake | 14 + .../videostream/cmake/videostreamConfig.cmake | 191 + Legacy/ws_linux/src/CMakeLists.txt | 64 + Legacy/ws_linux/src/rosaria/.RosAria.cpp.swp | Bin 0 -> 16384 bytes .../ws_linux/src/rosaria/CMakeLists.txt | 0 .../ws_linux/src/rosaria/RosAria.cpp | 4 - Legacy/ws_linux/src/rosaria/RosAria.cpp.old | 899 + .../ws_linux/src/rosaria/RosAria.cpp.old.save | 900 + .../ws_linux/src/rosaria/cfg}/RosAria.cfg | 0 .../ws_linux/src/rosaria/libaria.rdmanifest | 0 .../ws_linux/src/rosaria/mainpage.dox | 0 .../ws_linux/src/rosaria/msg}/BumperState.msg | 0 Legacy/ws_linux/src/rosaria/package.xml | 56 + .../ws_linux/src/rosaria_msgs/CMakeLists.txt | 202 + .../src/rosaria_msgs/msg/RestrictionsMsg.msg | 3 + .../src/rosaria_msgs/msg/RobotInfoMsg.msg | 6 + Legacy/ws_linux/src/rosaria_msgs/package.xml | 21 + Legacy/ws_linux/src/safety/.gitignore | 3 + Legacy/ws_linux/src/safety/CMakeLists.txt | 34 + Legacy/ws_linux/src/safety/README.txt | 29 + Legacy/ws_linux/src/safety/gnu_licence.txt | 674 + Legacy/ws_linux/src/safety/package.xml | 24 + .../ws_linux/src/safety/src/cloud_reader.cpp | 198 + Legacy/ws_linux/src/videostream/.gitignore | 2 + .../ws_linux/src/videostream/CMakeLists.txt | 160 + .../src/videostream/include/Videostream.h | 51 + Legacy/ws_linux/src/videostream/package.xml | 59 + .../src/videostream/src/videostream.cpp | 216 + .../ws_linux/src/videostream/srv/ip_get.srv | 2 + ros.desktop | 7 - run.sh | 19 - 1536 files changed, 415070 insertions(+), 30 deletions(-) create mode 100644 Legacy/Aria/ArNetworking/ArNetworking-Reference.html create mode 100644 Legacy/Aria/ArNetworking/CommandLineOptions.txt create mode 100644 Legacy/Aria/ArNetworking/CommandLineOptions.txt.in create mode 100644 Legacy/Aria/ArNetworking/Makefile create mode 100644 Legacy/Aria/ArNetworking/Makefile.dep create mode 100644 Legacy/Aria/ArNetworking/docs/figures/ArNetworking_overview.png create mode 100644 Legacy/Aria/ArNetworking/doxygen.conf create mode 100644 Legacy/Aria/ArNetworking/doxygen.conf.in create mode 100644 Legacy/Aria/ArNetworking/examples/ArNetworking_Examples-vc2003.sln create mode 100644 Legacy/Aria/ArNetworking/examples/ArNetworking_Examples-vc2008.sln create mode 100644 Legacy/Aria/ArNetworking/examples/Makefile create mode 100644 Legacy/Aria/ArNetworking/examples/README.txt create mode 100644 Legacy/Aria/ArNetworking/examples/clientCommandLister.cpp create mode 100644 Legacy/Aria/ArNetworking/examples/clientDemo-vc2003.vcproj create mode 100644 Legacy/Aria/ArNetworking/examples/clientDemo-vc2008.vcproj create mode 100644 Legacy/Aria/ArNetworking/examples/clientDemo-vc2010.vcxproj create mode 100644 Legacy/Aria/ArNetworking/examples/clientDemo.cpp create mode 100644 Legacy/Aria/ArNetworking/examples/clientDemoStatic-vc2003.vcproj create mode 100644 Legacy/Aria/ArNetworking/examples/clientDemoStatic-vc2008.vcproj create mode 100644 Legacy/Aria/ArNetworking/examples/clientDemoStatic-vc2010.vcxproj create mode 100644 Legacy/Aria/ArNetworking/examples/configClient.cpp create mode 100644 Legacy/Aria/ArNetworking/examples/configClientToServer.cpp create mode 100644 Legacy/Aria/ArNetworking/examples/configServer.cpp create mode 100644 Legacy/Aria/ArNetworking/examples/configServerRobot.cpp create mode 100644 Legacy/Aria/ArNetworking/examples/drawingsExample.cpp create mode 100644 Legacy/Aria/ArNetworking/examples/drawingsExampleWithRobot.cpp create mode 100644 Legacy/Aria/ArNetworking/examples/getVideoExample.cpp create mode 100644 Legacy/Aria/ArNetworking/examples/popupExample.cpp create mode 100644 Legacy/Aria/ArNetworking/examples/ptzCameraClientExample.cpp create mode 100644 Legacy/Aria/ArNetworking/examples/serverDemo-vc2003.vcproj create mode 100644 Legacy/Aria/ArNetworking/examples/serverDemo-vc2008.vcproj create mode 100644 Legacy/Aria/ArNetworking/examples/serverDemo-vc2010.vcxproj create mode 100644 Legacy/Aria/ArNetworking/examples/serverDemo.cpp create mode 100644 Legacy/Aria/ArNetworking/examples/serverDemo.userInfo create mode 100644 Legacy/Aria/ArNetworking/examples/serverDemoStatic-vc2003.vcproj create mode 100644 Legacy/Aria/ArNetworking/examples/serverDemoStatic-vc2008.vcproj create mode 100644 Legacy/Aria/ArNetworking/examples/serverDemoStatic-vc2010.vcxproj create mode 100644 Legacy/Aria/ArNetworking/examples/simpleServerExample.cpp create mode 100644 Legacy/Aria/ArNetworking/include/ArCentralForwarder.h create mode 100644 Legacy/Aria/ArNetworking/include/ArCentralManager.h create mode 100644 Legacy/Aria/ArNetworking/include/ArClientArgUtils.h create mode 100644 Legacy/Aria/ArNetworking/include/ArClientBase.h create mode 100644 Legacy/Aria/ArNetworking/include/ArClientCommands.h create mode 100644 Legacy/Aria/ArNetworking/include/ArClientData.h create mode 100644 Legacy/Aria/ArNetworking/include/ArClientFileUtils.h create mode 100644 Legacy/Aria/ArNetworking/include/ArClientHandlerConfig.h create mode 100644 Legacy/Aria/ArNetworking/include/ArClientSimpleConnector.h create mode 100644 Legacy/Aria/ArNetworking/include/ArClientSwitchManager.h create mode 100644 Legacy/Aria/ArNetworking/include/ArHybridForwarderVideo.h create mode 100644 Legacy/Aria/ArNetworking/include/ArMapChanger.h create mode 100644 Legacy/Aria/ArNetworking/include/ArNetPacket.h create mode 100644 Legacy/Aria/ArNetworking/include/ArNetPacketReceiverTcp.h create mode 100644 Legacy/Aria/ArNetworking/include/ArNetPacketReceiverUdp.h create mode 100644 Legacy/Aria/ArNetworking/include/ArNetPacketSenderTcp.h create mode 100644 Legacy/Aria/ArNetworking/include/ArNetworking.h create mode 100644 Legacy/Aria/ArNetworking/include/ArServerBase.h create mode 100644 Legacy/Aria/ArNetworking/include/ArServerClient.h create mode 100644 Legacy/Aria/ArNetworking/include/ArServerClientData.h create mode 100644 Legacy/Aria/ArNetworking/include/ArServerClientIdentifier.h create mode 100644 Legacy/Aria/ArNetworking/include/ArServerCommands.h create mode 100644 Legacy/Aria/ArNetworking/include/ArServerData.h create mode 100644 Legacy/Aria/ArNetworking/include/ArServerFileUtils.h create mode 100644 Legacy/Aria/ArNetworking/include/ArServerHandlerCamera.h create mode 100644 Legacy/Aria/ArNetworking/include/ArServerHandlerCameraCollection.h create mode 100644 Legacy/Aria/ArNetworking/include/ArServerHandlerCommMonitor.h create mode 100644 Legacy/Aria/ArNetworking/include/ArServerHandlerCommands.h create mode 100644 Legacy/Aria/ArNetworking/include/ArServerHandlerConfig.h create mode 100644 Legacy/Aria/ArNetworking/include/ArServerHandlerMap.h create mode 100644 Legacy/Aria/ArNetworking/include/ArServerHandlerMapping.h create mode 100644 Legacy/Aria/ArNetworking/include/ArServerHandlerPopup.h create mode 100644 Legacy/Aria/ArNetworking/include/ArServerInfoDrawings.h create mode 100644 Legacy/Aria/ArNetworking/include/ArServerInfoRobot.h create mode 100644 Legacy/Aria/ArNetworking/include/ArServerInfoSensor.h create mode 100644 Legacy/Aria/ArNetworking/include/ArServerInfoStrings.h create mode 100644 Legacy/Aria/ArNetworking/include/ArServerMode.h create mode 100644 Legacy/Aria/ArNetworking/include/ArServerModeDrive.h create mode 100644 Legacy/Aria/ArNetworking/include/ArServerModeIdle.h create mode 100644 Legacy/Aria/ArNetworking/include/ArServerModeRatioDrive.h create mode 100644 Legacy/Aria/ArNetworking/include/ArServerModeStop.h create mode 100644 Legacy/Aria/ArNetworking/include/ArServerModeWander.h create mode 100644 Legacy/Aria/ArNetworking/include/ArServerSimpleCommands.h create mode 100644 Legacy/Aria/ArNetworking/include/ArServerSimpleOpener.h create mode 100644 Legacy/Aria/ArNetworking/include/ArServerUserInfo.h create mode 100644 Legacy/Aria/ArNetworking/include/ArTempDirectoryHelper.h create mode 100644 Legacy/Aria/ArNetworking/include/md5.h create mode 100644 Legacy/Aria/ArNetworking/include/wrapper.i create mode 100644 Legacy/Aria/ArNetworking/javaExamples/Makefile create mode 100644 Legacy/Aria/ArNetworking/javaExamples/README.txt create mode 100644 Legacy/Aria/ArNetworking/javaExamples/customClientExample.java create mode 100644 Legacy/Aria/ArNetworking/javaExamples/customServerExample.java create mode 100644 Legacy/Aria/ArNetworking/javaExamples/simple.java create mode 100644 Legacy/Aria/ArNetworking/pythonExamples/README.txt create mode 100644 Legacy/Aria/ArNetworking/pythonExamples/customClientExample.py create mode 100644 Legacy/Aria/ArNetworking/pythonExamples/customServerExample.py create mode 100644 Legacy/Aria/ArNetworking/pythonExamples/drawingsExample.py create mode 100644 Legacy/Aria/ArNetworking/pythonExamples/simple.py create mode 100644 Legacy/Aria/ArNetworking/src/ArCentralForwarder.cpp create mode 100644 Legacy/Aria/ArNetworking/src/ArCentralManager.cpp create mode 100644 Legacy/Aria/ArNetworking/src/ArClientArgUtils.cpp create mode 100644 Legacy/Aria/ArNetworking/src/ArClientBase.cpp create mode 100644 Legacy/Aria/ArNetworking/src/ArClientData.cpp create mode 100644 Legacy/Aria/ArNetworking/src/ArClientFileUtils.cpp create mode 100644 Legacy/Aria/ArNetworking/src/ArClientHandlerConfig.cpp create mode 100644 Legacy/Aria/ArNetworking/src/ArClientSimpleConnector.cpp create mode 100644 Legacy/Aria/ArNetworking/src/ArClientSwitchManager.cpp create mode 100644 Legacy/Aria/ArNetworking/src/ArHybridForwarderVideo.cpp create mode 100644 Legacy/Aria/ArNetworking/src/ArMapChanger.cpp create mode 100644 Legacy/Aria/ArNetworking/src/ArNetPacket.cpp create mode 100644 Legacy/Aria/ArNetworking/src/ArNetPacketReceiverTcp.cpp create mode 100644 Legacy/Aria/ArNetworking/src/ArNetPacketReceiverUdp.cpp create mode 100644 Legacy/Aria/ArNetworking/src/ArNetPacketSenderTcp.cpp create mode 100644 Legacy/Aria/ArNetworking/src/ArNetworkingDLL-vc2003.vcproj create mode 100644 Legacy/Aria/ArNetworking/src/ArNetworkingDLL-vc2008.vcproj create mode 100644 Legacy/Aria/ArNetworking/src/ArNetworkingDLL-vc2010.vcxproj create mode 100644 Legacy/Aria/ArNetworking/src/ArNetworkingStatic-vc2003.vcproj create mode 100644 Legacy/Aria/ArNetworking/src/ArNetworkingStatic-vc2008.vcproj create mode 100644 Legacy/Aria/ArNetworking/src/ArNetworkingStatic-vc2010.vcxproj create mode 100644 Legacy/Aria/ArNetworking/src/ArServerBase.cpp create mode 100644 Legacy/Aria/ArNetworking/src/ArServerClient.cpp create mode 100644 Legacy/Aria/ArNetworking/src/ArServerData.cpp create mode 100644 Legacy/Aria/ArNetworking/src/ArServerFileUtils.cpp create mode 100644 Legacy/Aria/ArNetworking/src/ArServerHandlerCamera.cpp create mode 100644 Legacy/Aria/ArNetworking/src/ArServerHandlerCameraCollection.cpp create mode 100644 Legacy/Aria/ArNetworking/src/ArServerHandlerCommMonitor.cpp create mode 100644 Legacy/Aria/ArNetworking/src/ArServerHandlerCommands.cpp create mode 100644 Legacy/Aria/ArNetworking/src/ArServerHandlerConfig.cpp create mode 100644 Legacy/Aria/ArNetworking/src/ArServerHandlerMap.cpp create mode 100644 Legacy/Aria/ArNetworking/src/ArServerHandlerMapping.cpp create mode 100644 Legacy/Aria/ArNetworking/src/ArServerHandlerPopup.cpp create mode 100644 Legacy/Aria/ArNetworking/src/ArServerInfoDrawings.cpp create mode 100644 Legacy/Aria/ArNetworking/src/ArServerInfoRobot.cpp create mode 100644 Legacy/Aria/ArNetworking/src/ArServerInfoSensor.cpp create mode 100644 Legacy/Aria/ArNetworking/src/ArServerInfoStrings.cpp create mode 100644 Legacy/Aria/ArNetworking/src/ArServerMode.cpp create mode 100644 Legacy/Aria/ArNetworking/src/ArServerModeDrive.cpp create mode 100644 Legacy/Aria/ArNetworking/src/ArServerModeIdle.cpp create mode 100644 Legacy/Aria/ArNetworking/src/ArServerModeRatioDrive.cpp create mode 100644 Legacy/Aria/ArNetworking/src/ArServerModeStop.cpp create mode 100644 Legacy/Aria/ArNetworking/src/ArServerModeWander.cpp create mode 100644 Legacy/Aria/ArNetworking/src/ArServerSimpleCommands.cpp create mode 100644 Legacy/Aria/ArNetworking/src/ArServerSimpleOpener.cpp create mode 100644 Legacy/Aria/ArNetworking/src/ArServerUserInfo.cpp create mode 100644 Legacy/Aria/ArNetworking/src/ArTempDirectoryHelper.cpp create mode 100644 Legacy/Aria/ArNetworking/src/md5.cpp create mode 100644 Legacy/Aria/ArNetworking/tests/Makefile create mode 100644 Legacy/Aria/ArNetworking/tests/baseTest.cpp create mode 100644 Legacy/Aria/ArNetworking/tests/cameraModeClient.cpp create mode 100644 Legacy/Aria/ArNetworking/tests/clientLoadMap.cpp create mode 100644 Legacy/Aria/ArNetworking/tests/clientLocalizeToPose.cpp create mode 100644 Legacy/Aria/ArNetworking/tests/clientPatrol.cpp create mode 100644 Legacy/Aria/ArNetworking/tests/clientTest.vcproj create mode 100644 Legacy/Aria/ArNetworking/tests/commandTestClient.cpp create mode 100644 Legacy/Aria/ArNetworking/tests/commandTestServer.cpp create mode 100644 Legacy/Aria/ArNetworking/tests/fileClient.cpp create mode 100644 Legacy/Aria/ArNetworking/tests/fileClientRaw.cpp create mode 100644 Legacy/Aria/ArNetworking/tests/fileServer.cpp create mode 100644 Legacy/Aria/ArNetworking/tests/fileToServer.cpp create mode 100644 Legacy/Aria/ArNetworking/tests/idleClient.cpp create mode 100644 Legacy/Aria/ArNetworking/tests/infoDrawingClient.cpp create mode 100644 Legacy/Aria/ArNetworking/tests/infoDrawingServer.cpp create mode 100644 Legacy/Aria/ArNetworking/tests/mapClient.cpp create mode 100644 Legacy/Aria/ArNetworking/tests/mapServer.cpp create mode 100644 Legacy/Aria/ArNetworking/tests/md5test.cpp create mode 100644 Legacy/Aria/ArNetworking/tests/modeInfoClient.cpp create mode 100644 Legacy/Aria/ArNetworking/tests/reloadConfig.cpp create mode 100644 Legacy/Aria/ArNetworking/tests/serverTest.vcproj create mode 100644 Legacy/Aria/ArNetworking/tests/simpleServerTest.cpp create mode 100644 Legacy/Aria/ArNetworking/tests/standaloneClientDemo.cpp create mode 100644 Legacy/Aria/ArNetworking/tests/standaloneServerDemo.cpp create mode 100644 Legacy/Aria/ArNetworking/tests/switchServer.cpp create mode 100644 Legacy/Aria/ArNetworking/tests/switchWatcher.cpp create mode 100644 Legacy/Aria/ArNetworking/tests/testClient.cpp create mode 100644 Legacy/Aria/ArNetworking/tests/testRequestOnce.cpp create mode 100644 Legacy/Aria/ArNetworking/tests/testServer.cpp create mode 100644 Legacy/Aria/ArNetworking/tests/testStatic.vcproj create mode 100644 Legacy/Aria/ArNetworking/tests/userServerTest.cpp create mode 100644 Legacy/Aria/ArNetworking/tests/userServerTest.userInfo create mode 100644 Legacy/Aria/ArNetworking/tests/watchDockInfo.cpp create mode 100644 Legacy/Aria/Aria-Reference.html create mode 100644 Legacy/Aria/Changes.txt create mode 100644 Legacy/Aria/CommandLineOptions.txt create mode 100644 Legacy/Aria/INSTALL.txt create mode 100644 Legacy/Aria/LICENSE.txt create mode 100644 Legacy/Aria/Makefile create mode 100644 Legacy/Aria/Makefile.dep create mode 100644 Legacy/Aria/README.txt create mode 100644 Legacy/Aria/advanced/Makefile create mode 100644 Legacy/Aria/advanced/README.txt create mode 100644 Legacy/Aria/advanced/actsDemo.cpp create mode 100644 Legacy/Aria/advanced/actsDemoSimple.cpp create mode 100644 Legacy/Aria/advanced/amptuDemo.cpp create mode 100644 Legacy/Aria/advanced/amptuDemo.vcproj create mode 100644 Legacy/Aria/advanced/condition.cpp create mode 100644 Legacy/Aria/advanced/functorListsAndStdAlgorithms.cpp create mode 100644 Legacy/Aria/advanced/joydriveActionMod.cpp create mode 100644 Legacy/Aria/advanced/joydriveActionMod.vcproj create mode 100644 Legacy/Aria/advanced/joydriveActionModule.cpp create mode 100644 Legacy/Aria/advanced/joydriveActionModule.vcproj create mode 100644 Legacy/Aria/advanced/joydriveUserControl.cpp create mode 100644 Legacy/Aria/advanced/peoplebotDemo.cpp create mode 100644 Legacy/Aria/advanced/sickAutoLogger.cpp create mode 100644 Legacy/Aria/advanced/sickAutoLogger.vcproj create mode 100644 Legacy/Aria/advanced/sickSpinLogger.cpp create mode 100644 Legacy/Aria/advanced/sickSquareLogger.cpp create mode 100644 Legacy/Aria/bin/SIMULATOR_README.txt create mode 100644 Legacy/Aria/docs/figures/Amigobot.jpg create mode 100644 Legacy/Aria/docs/figures/ArRangeDevice_currentReadingPolar.dia create mode 100644 Legacy/Aria/docs/figures/ArRangeDevice_currentReadingPolar.png create mode 100644 Legacy/Aria/docs/figures/ArRobot_Task_Cycle.dia create mode 100644 Legacy/Aria/docs/figures/ArRobot_Task_Cycle.png create mode 100644 Legacy/Aria/docs/figures/MobileSim_with_laser.png create mode 100644 Legacy/Aria/docs/figures/Robot_Communication_Options.png create mode 100644 Legacy/Aria/docs/figures/Robot_Communications_Options.dia create mode 100644 Legacy/Aria/docs/overview.dox create mode 100644 Legacy/Aria/docs/params.dox create mode 100644 Legacy/Aria/doxygen.conf create mode 100644 Legacy/Aria/examples/All_Examples-vc2003.sln create mode 100644 Legacy/Aria/examples/All_Examples-vc2008.sln create mode 100644 Legacy/Aria/examples/All_Examples-vc2010.sln create mode 100644 Legacy/Aria/examples/Makefile create mode 100644 Legacy/Aria/examples/README.txt create mode 100644 Legacy/Aria/examples/actionExample-vc2003.vcproj create mode 100644 Legacy/Aria/examples/actionExample-vc2008.vcproj create mode 100644 Legacy/Aria/examples/actionExample-vc2010.vcxproj create mode 100644 Legacy/Aria/examples/actionExample.cpp create mode 100644 Legacy/Aria/examples/actionExample.vcproj create mode 100644 Legacy/Aria/examples/actionGroupExample-vc2003.vcproj create mode 100644 Legacy/Aria/examples/actionGroupExample-vc2008.vcproj create mode 100644 Legacy/Aria/examples/actionGroupExample-vc2010.vcxproj create mode 100644 Legacy/Aria/examples/actionGroupExample.cpp create mode 100644 Legacy/Aria/examples/actionGroupExample.vcproj create mode 100644 Legacy/Aria/examples/actsColorFollowingExample-vc2003.vcproj create mode 100644 Legacy/Aria/examples/actsColorFollowingExample-vc2008.vcproj create mode 100644 Legacy/Aria/examples/actsColorFollowingExample-vc2010.vcxproj create mode 100644 Legacy/Aria/examples/actsColorFollowingExample.cpp create mode 100644 Legacy/Aria/examples/armExample-vc2003.vcproj create mode 100644 Legacy/Aria/examples/armExample-vc2008.vcproj create mode 100644 Legacy/Aria/examples/armExample-vc2010.vcxproj create mode 100644 Legacy/Aria/examples/armExample.cpp create mode 100644 Legacy/Aria/examples/auxSerialExample-vc2003.vcproj create mode 100644 Legacy/Aria/examples/auxSerialExample-vc2008.vcproj create mode 100644 Legacy/Aria/examples/auxSerialExample-vc2010.vcxproj create mode 100644 Legacy/Aria/examples/auxSerialExample.cpp create mode 100644 Legacy/Aria/examples/cameraPTZExample.cpp create mode 100644 Legacy/Aria/examples/cameraPTZExample.vcxproj create mode 100644 Legacy/Aria/examples/configExample.cpp create mode 100755 Legacy/Aria/examples/demo create mode 100644 Legacy/Aria/examples/demo-vc2003.vcproj create mode 100644 Legacy/Aria/examples/demo-vc2008.vcproj create mode 100644 Legacy/Aria/examples/demo-vc2010.vcxproj create mode 100644 Legacy/Aria/examples/demo.cpp create mode 100644 Legacy/Aria/examples/demoStatic-vc2003.vcproj create mode 100644 Legacy/Aria/examples/demoStatic-vc2008.vcproj create mode 100644 Legacy/Aria/examples/demoStatic-vc2010.vcxproj create mode 100644 Legacy/Aria/examples/directMotionExample-vc2003.vcproj create mode 100644 Legacy/Aria/examples/directMotionExample-vc2008.vcproj create mode 100644 Legacy/Aria/examples/directMotionExample-vc2010.vcxproj create mode 100644 Legacy/Aria/examples/directMotionExample.cpp create mode 100644 Legacy/Aria/examples/dpptuExample-vc2003.vcproj create mode 100644 Legacy/Aria/examples/dpptuExample-vc2008.vcproj create mode 100644 Legacy/Aria/examples/dpptuExample-vc2010.vcxproj create mode 100644 Legacy/Aria/examples/dpptuExample.cpp create mode 100644 Legacy/Aria/examples/functorExample-vc2003.vcproj create mode 100644 Legacy/Aria/examples/functorExample-vc2008.vcproj create mode 100644 Legacy/Aria/examples/functorExample-vc2010.vcxproj create mode 100644 Legacy/Aria/examples/functorExample.cpp create mode 100644 Legacy/Aria/examples/gotoActionExample-vc2003.vcproj create mode 100644 Legacy/Aria/examples/gotoActionExample-vc2008.vcproj create mode 100644 Legacy/Aria/examples/gotoActionExample-vc2010.vcxproj create mode 100644 Legacy/Aria/examples/gotoActionExample.cpp create mode 100644 Legacy/Aria/examples/gpsExample-vc2003.vcproj create mode 100644 Legacy/Aria/examples/gpsExample-vc2008.vcproj create mode 100644 Legacy/Aria/examples/gpsExample-vc2010.vcxproj create mode 100644 Legacy/Aria/examples/gpsExample.cpp create mode 100644 Legacy/Aria/examples/gpsRobotTaskExample.cpp create mode 100644 Legacy/Aria/examples/gripperExample-vc2003.vcproj create mode 100644 Legacy/Aria/examples/gripperExample-vc2008.vcproj create mode 100644 Legacy/Aria/examples/gripperExample-vc2010.vcxproj create mode 100644 Legacy/Aria/examples/gripperExample.cpp create mode 100644 Legacy/Aria/examples/gyroExample-vc2003.vcproj create mode 100644 Legacy/Aria/examples/gyroExample-vc2008.vcproj create mode 100644 Legacy/Aria/examples/gyroExample-vc2010.vcxproj create mode 100644 Legacy/Aria/examples/gyroExample.cpp create mode 100644 Legacy/Aria/examples/imuExample.cpp create mode 100644 Legacy/Aria/examples/ipthru-vc2003.vcproj create mode 100644 Legacy/Aria/examples/ipthru-vc2008.vcproj create mode 100644 Legacy/Aria/examples/ipthru-vc2010.vcxproj create mode 100644 Legacy/Aria/examples/ipthru.cpp create mode 100644 Legacy/Aria/examples/joydriveActionExample-vc2003.vcproj create mode 100644 Legacy/Aria/examples/joydriveActionExample-vc2008.vcproj create mode 100644 Legacy/Aria/examples/joydriveActionExample-vc2010.vcproj create mode 100644 Legacy/Aria/examples/joydriveActionExample.cpp create mode 100644 Legacy/Aria/examples/joydriveThreaded-vc2003.vcproj create mode 100644 Legacy/Aria/examples/joydriveThreaded-vc2008.vcproj create mode 100644 Legacy/Aria/examples/joydriveThreaded-vc2010.vcxproj create mode 100644 Legacy/Aria/examples/joydriveThreaded.cpp create mode 100644 Legacy/Aria/examples/joydriveUserTask-vc2003.vcproj create mode 100644 Legacy/Aria/examples/joydriveUserTask-vc2008.vcproj create mode 100644 Legacy/Aria/examples/joydriveUserTask.cpp create mode 100644 Legacy/Aria/examples/laserConnect.cpp create mode 100644 Legacy/Aria/examples/lasers.cpp create mode 100644 Legacy/Aria/examples/lineFinderExample.cpp create mode 100644 Legacy/Aria/examples/moduleExample.cpp create mode 100644 Legacy/Aria/examples/moduleExample.vcproj create mode 100644 Legacy/Aria/examples/moduleExample_Mod.cpp create mode 100644 Legacy/Aria/examples/moduleExample_Mod.vcproj create mode 100644 Legacy/Aria/examples/mtxIO.cpp create mode 100644 Legacy/Aria/examples/mtxLCDDisplay.cpp create mode 100644 Legacy/Aria/examples/mtxPowerControl.cpp create mode 100644 Legacy/Aria/examples/mtxWheelLights.cpp create mode 100644 Legacy/Aria/examples/netServerExample-vc2003.vcproj create mode 100644 Legacy/Aria/examples/netServerExample-vc2008.vcproj create mode 100644 Legacy/Aria/examples/netServerExample-vc2010.vcxproj create mode 100644 Legacy/Aria/examples/netServerExample.cpp create mode 100644 Legacy/Aria/examples/robotConnectionCallbacks.cpp create mode 100644 Legacy/Aria/examples/robotSyncTaskExample-vc2003.vcproj create mode 100644 Legacy/Aria/examples/robotSyncTaskExample-vc2008.vcproj create mode 100644 Legacy/Aria/examples/robotSyncTaskExample-vc2010.vcxproj create mode 100644 Legacy/Aria/examples/robotSyncTaskExample.cpp create mode 100644 Legacy/Aria/examples/seekurPower.cpp create mode 100644 Legacy/Aria/examples/sickLogger-vc2003.vcproj create mode 100644 Legacy/Aria/examples/sickLogger-vc2008.vcproj create mode 100644 Legacy/Aria/examples/sickLogger-vc2010.vcxproj create mode 100644 Legacy/Aria/examples/sickLogger.cpp create mode 100644 Legacy/Aria/examples/sickLoggerStatic-vc2003.vcproj create mode 100644 Legacy/Aria/examples/sickRobotExample.cpp create mode 100644 Legacy/Aria/examples/sickTeleop-vc2003.vcproj create mode 100644 Legacy/Aria/examples/sickTeleop-vc2008.vcproj create mode 100644 Legacy/Aria/examples/sickTeleop.cpp create mode 100644 Legacy/Aria/examples/simpleConnect-vc2003.vcproj create mode 100644 Legacy/Aria/examples/simpleConnect-vc2008.vcproj create mode 100644 Legacy/Aria/examples/simpleConnect-vc2010.vcxproj create mode 100644 Legacy/Aria/examples/simpleConnect.cpp create mode 100644 Legacy/Aria/examples/simpleMotionCommands.cpp create mode 100644 Legacy/Aria/examples/socketClientExample-vc2003.vcproj create mode 100644 Legacy/Aria/examples/socketClientExample-vc2008.vcproj create mode 100644 Legacy/Aria/examples/socketClientExample-vc2010.vcxproj create mode 100644 Legacy/Aria/examples/socketClientExample.cpp create mode 100644 Legacy/Aria/examples/socketServerExample-vc2003.vcproj create mode 100644 Legacy/Aria/examples/socketServerExample-vc2008.vcproj create mode 100644 Legacy/Aria/examples/socketServerExample-vc2010.vcxproj create mode 100644 Legacy/Aria/examples/socketServerExample.cpp create mode 100644 Legacy/Aria/examples/sound-computers.wav create mode 100644 Legacy/Aria/examples/sound-impressed.wav create mode 100644 Legacy/Aria/examples/sound-ping.wav create mode 100644 Legacy/Aria/examples/sound-r2a.wav create mode 100644 Legacy/Aria/examples/sound-r2b.wav create mode 100644 Legacy/Aria/examples/soundsQueueExample-vc2003.vcproj create mode 100644 Legacy/Aria/examples/soundsQueueExample-vc2008.vcproj create mode 100644 Legacy/Aria/examples/soundsQueueExample-vc2010.vcxproj create mode 100644 Legacy/Aria/examples/soundsQueueExample.cpp create mode 100644 Legacy/Aria/examples/teleopActionsExample-vc2003.vcproj create mode 100644 Legacy/Aria/examples/teleopActionsExample-vc2008.vcproj create mode 100644 Legacy/Aria/examples/teleopActionsExample-vc2010.vcxproj create mode 100644 Legacy/Aria/examples/teleopActionsExample.cpp create mode 100644 Legacy/Aria/examples/threadExample-vc2003.vcproj create mode 100644 Legacy/Aria/examples/threadExample-vc2008.vcproj create mode 100644 Legacy/Aria/examples/threadExample-vc2010.vcxproj create mode 100644 Legacy/Aria/examples/threadExample.cpp create mode 100644 Legacy/Aria/examples/triangleDriveToActionExample.cpp create mode 100644 Legacy/Aria/examples/twoRobotWander-vc2003.vcproj create mode 100644 Legacy/Aria/examples/twoRobotWander-vc2008.vcproj create mode 100644 Legacy/Aria/examples/twoRobotWander-vc2010.vcxproj create mode 100644 Legacy/Aria/examples/twoRobotWander.cpp create mode 100644 Legacy/Aria/examples/wander-vc2003.vcproj create mode 100644 Legacy/Aria/examples/wander-vc2008.vcproj create mode 100644 Legacy/Aria/examples/wander-vc2010.vcxproj create mode 100644 Legacy/Aria/examples/wander.cpp create mode 100644 Legacy/Aria/examples/wanderAndLogData-vc2003.vcproj create mode 100644 Legacy/Aria/examples/wanderAndLogData-vc2008.vcproj create mode 100644 Legacy/Aria/examples/wanderAndLogData-vc2010.vcxproj create mode 100644 Legacy/Aria/examples/wanderAndLogData.cpp create mode 100644 Legacy/Aria/icon.png create mode 100644 Legacy/Aria/include/ArACTS.h create mode 100644 Legacy/Aria/include/ArAMPTU.h create mode 100644 Legacy/Aria/include/ArASyncTask.h create mode 100644 Legacy/Aria/include/ArAction.h create mode 100644 Legacy/Aria/include/ArActionAvoidFront.h create mode 100644 Legacy/Aria/include/ArActionAvoidSide.h create mode 100644 Legacy/Aria/include/ArActionBumpers.h create mode 100644 Legacy/Aria/include/ArActionColorFollow.h create mode 100644 Legacy/Aria/include/ArActionConstantVelocity.h create mode 100644 Legacy/Aria/include/ArActionDeceleratingLimiter.h create mode 100644 Legacy/Aria/include/ArActionDesired.h create mode 100644 Legacy/Aria/include/ArActionDriveDistance.h create mode 100644 Legacy/Aria/include/ArActionGoto.h create mode 100644 Legacy/Aria/include/ArActionGotoStraight.h create mode 100644 Legacy/Aria/include/ArActionGroup.h create mode 100644 Legacy/Aria/include/ArActionGroups.h create mode 100644 Legacy/Aria/include/ArActionIRs.h create mode 100644 Legacy/Aria/include/ArActionInput.h create mode 100644 Legacy/Aria/include/ArActionJoydrive.h create mode 100644 Legacy/Aria/include/ArActionKeydrive.h create mode 100644 Legacy/Aria/include/ArActionLimiterBackwards.h create mode 100644 Legacy/Aria/include/ArActionLimiterForwards.h create mode 100644 Legacy/Aria/include/ArActionLimiterRot.h create mode 100644 Legacy/Aria/include/ArActionLimiterTableSensor.h create mode 100644 Legacy/Aria/include/ArActionMovementParameters.h create mode 100644 Legacy/Aria/include/ArActionMovementParametersDebugging.h create mode 100644 Legacy/Aria/include/ArActionRatioInput.h create mode 100644 Legacy/Aria/include/ArActionRobotJoydrive.h create mode 100644 Legacy/Aria/include/ArActionStallRecover.h create mode 100644 Legacy/Aria/include/ArActionStop.h create mode 100644 Legacy/Aria/include/ArActionTriangleDriveTo.h create mode 100644 Legacy/Aria/include/ArActionTurn.h create mode 100644 Legacy/Aria/include/ArAnalogGyro.h create mode 100644 Legacy/Aria/include/ArArg.h create mode 100644 Legacy/Aria/include/ArArgumentBuilder.h create mode 100644 Legacy/Aria/include/ArArgumentParser.h create mode 100644 Legacy/Aria/include/ArBasePacket.h create mode 100644 Legacy/Aria/include/ArBatteryConnector.h create mode 100644 Legacy/Aria/include/ArBatteryMTX.h create mode 100644 Legacy/Aria/include/ArBumpers.h create mode 100644 Legacy/Aria/include/ArCameraCollection.h create mode 100644 Legacy/Aria/include/ArCameraCommands.h create mode 100644 Legacy/Aria/include/ArCommands.h create mode 100644 Legacy/Aria/include/ArCondition.h create mode 100644 Legacy/Aria/include/ArConfig.h create mode 100644 Legacy/Aria/include/ArConfigArg.h create mode 100644 Legacy/Aria/include/ArConfigGroup.h create mode 100644 Legacy/Aria/include/ArDPPTU.h create mode 100644 Legacy/Aria/include/ArDataLogger.h create mode 100644 Legacy/Aria/include/ArDeviceConnection.h create mode 100644 Legacy/Aria/include/ArDrawingData.h create mode 100644 Legacy/Aria/include/ArExitErrorSource.h create mode 100644 Legacy/Aria/include/ArExport.h create mode 100644 Legacy/Aria/include/ArFileParser.h create mode 100644 Legacy/Aria/include/ArForbiddenRangeDevice.h create mode 100644 Legacy/Aria/include/ArFunctor.h create mode 100644 Legacy/Aria/include/ArFunctorASyncTask.h create mode 100644 Legacy/Aria/include/ArGPS.h create mode 100644 Legacy/Aria/include/ArGPSConnector.h create mode 100644 Legacy/Aria/include/ArGPSCoords.h create mode 100644 Legacy/Aria/include/ArGripper.h create mode 100644 Legacy/Aria/include/ArHasFileName.h create mode 100644 Legacy/Aria/include/ArIRs.h create mode 100644 Legacy/Aria/include/ArInterpolation.h create mode 100644 Legacy/Aria/include/ArIrrfDevice.h create mode 100644 Legacy/Aria/include/ArJoyHandler.h create mode 100644 Legacy/Aria/include/ArKeyHandler.h create mode 100644 Legacy/Aria/include/ArLCDConnector.h create mode 100644 Legacy/Aria/include/ArLCDMTX.h create mode 100644 Legacy/Aria/include/ArLMS1XX.h create mode 100644 Legacy/Aria/include/ArLMS2xx.h create mode 100644 Legacy/Aria/include/ArLMS2xxPacket.h create mode 100644 Legacy/Aria/include/ArLMS2xxPacketReceiver.h create mode 100644 Legacy/Aria/include/ArLaser.h create mode 100644 Legacy/Aria/include/ArLaserConnector.h create mode 100644 Legacy/Aria/include/ArLaserFilter.h create mode 100644 Legacy/Aria/include/ArLaserLogger.h create mode 100644 Legacy/Aria/include/ArLaserReflectorDevice.h create mode 100644 Legacy/Aria/include/ArLineFinder.h create mode 100644 Legacy/Aria/include/ArLog.h create mode 100644 Legacy/Aria/include/ArLogFileConnection.h create mode 100644 Legacy/Aria/include/ArMD5Calculator.h create mode 100644 Legacy/Aria/include/ArMTXIO.h create mode 100644 Legacy/Aria/include/ArMap.h create mode 100644 Legacy/Aria/include/ArMapComponents.h create mode 100644 Legacy/Aria/include/ArMapInterface.h create mode 100644 Legacy/Aria/include/ArMapObject.h create mode 100644 Legacy/Aria/include/ArMapUtils.h create mode 100644 Legacy/Aria/include/ArMode.h create mode 100644 Legacy/Aria/include/ArModes.h create mode 100644 Legacy/Aria/include/ArModule.h create mode 100644 Legacy/Aria/include/ArModuleLoader.h create mode 100644 Legacy/Aria/include/ArMutex.h create mode 100644 Legacy/Aria/include/ArNMEAParser.h create mode 100644 Legacy/Aria/include/ArNetServer.h create mode 100644 Legacy/Aria/include/ArNovatelGPS.h create mode 100644 Legacy/Aria/include/ArP2Arm.h create mode 100644 Legacy/Aria/include/ArPTZ.h create mode 100644 Legacy/Aria/include/ArPTZConnector.h create mode 100644 Legacy/Aria/include/ArPixelDevice.h create mode 100644 Legacy/Aria/include/ArPriorityResolver.h create mode 100644 Legacy/Aria/include/ArRVisionPTZ.h create mode 100644 Legacy/Aria/include/ArRangeBuffer.h create mode 100644 Legacy/Aria/include/ArRangeDevice.h create mode 100644 Legacy/Aria/include/ArRangeDeviceThreaded.h create mode 100644 Legacy/Aria/include/ArRatioInputJoydrive.h create mode 100644 Legacy/Aria/include/ArRatioInputKeydrive.h create mode 100644 Legacy/Aria/include/ArRatioInputRobotJoydrive.h create mode 100644 Legacy/Aria/include/ArRecurrentTask.h create mode 100644 Legacy/Aria/include/ArResolver.h create mode 100644 Legacy/Aria/include/ArRingQueue.h create mode 100644 Legacy/Aria/include/ArRobot.h create mode 100644 Legacy/Aria/include/ArRobotBatteryPacketReader.h create mode 100644 Legacy/Aria/include/ArRobotConfig.h create mode 100644 Legacy/Aria/include/ArRobotConfigPacketReader.h create mode 100644 Legacy/Aria/include/ArRobotConnector.h create mode 100644 Legacy/Aria/include/ArRobotJoyHandler.h create mode 100644 Legacy/Aria/include/ArRobotPacket.h create mode 100644 Legacy/Aria/include/ArRobotPacketReaderThread.h create mode 100644 Legacy/Aria/include/ArRobotPacketReceiver.h create mode 100644 Legacy/Aria/include/ArRobotPacketSender.h create mode 100644 Legacy/Aria/include/ArRobotParams.h create mode 100644 Legacy/Aria/include/ArRobotTypes.h create mode 100644 Legacy/Aria/include/ArS3Series.h create mode 100644 Legacy/Aria/include/ArSZSeries.h create mode 100644 Legacy/Aria/include/ArSensorReading.h create mode 100644 Legacy/Aria/include/ArSerialConnection.h create mode 100644 Legacy/Aria/include/ArSick.h create mode 100644 Legacy/Aria/include/ArSignalHandler.h create mode 100644 Legacy/Aria/include/ArSimpleConnector.h create mode 100644 Legacy/Aria/include/ArSimulatedLaser.h create mode 100644 Legacy/Aria/include/ArSocket.h create mode 100644 Legacy/Aria/include/ArSonarAutoDisabler.h create mode 100644 Legacy/Aria/include/ArSonarConnector.h create mode 100644 Legacy/Aria/include/ArSonarDevice.h create mode 100644 Legacy/Aria/include/ArSonarMTX.h create mode 100644 Legacy/Aria/include/ArSonyPTZ.h create mode 100644 Legacy/Aria/include/ArSoundPlayer.h create mode 100644 Legacy/Aria/include/ArSoundsQueue.h create mode 100644 Legacy/Aria/include/ArSpeech.h create mode 100644 Legacy/Aria/include/ArStringInfoGroup.h create mode 100644 Legacy/Aria/include/ArSyncLoop.h create mode 100644 Legacy/Aria/include/ArSyncTask.h create mode 100644 Legacy/Aria/include/ArSystemStatus.h create mode 100644 Legacy/Aria/include/ArTCM2.h create mode 100644 Legacy/Aria/include/ArTCMCompassDirect.h create mode 100644 Legacy/Aria/include/ArTCMCompassRobot.h create mode 100644 Legacy/Aria/include/ArTaskState.h create mode 100644 Legacy/Aria/include/ArTcpConnection.h create mode 100644 Legacy/Aria/include/ArThread.h create mode 100644 Legacy/Aria/include/ArTransform.h create mode 100644 Legacy/Aria/include/ArTrimbleGPS.h create mode 100644 Legacy/Aria/include/ArUrg.h create mode 100644 Legacy/Aria/include/ArUrg_2_0.h create mode 100644 Legacy/Aria/include/ArVCC4.h create mode 100644 Legacy/Aria/include/ArVersalogicIO.h create mode 100644 Legacy/Aria/include/ArZippable.h create mode 100644 Legacy/Aria/include/Aria.h create mode 100644 Legacy/Aria/include/ariaInternal.h create mode 100644 Legacy/Aria/include/ariaOSDef.h create mode 100644 Legacy/Aria/include/ariaTypedefs.h create mode 100644 Legacy/Aria/include/ariaUtil.h create mode 100644 Legacy/Aria/include/md5.h create mode 100644 Legacy/Aria/include/wrapper.i create mode 100644 Legacy/Aria/include/wrapper_ExtraClasses.h create mode 100644 Legacy/Aria/include/wrapper_Functors.h create mode 100644 Legacy/Aria/include/wrapper_std_list_java.i create mode 100644 Legacy/Aria/java/ArNetworkingJava.vcproj create mode 100644 Legacy/Aria/java/ArNetworkingSwigJava.vcproj create mode 100644 Legacy/Aria/java/AriaJava-vc2010.sln create mode 100644 Legacy/Aria/java/AriaJava.sln create mode 100644 Legacy/Aria/java/AriaJava.vcproj create mode 100644 Legacy/Aria/java/AriaSwigJava.vcproj create mode 100644 Legacy/Aria/javaExamples/Makefile create mode 100644 Legacy/Aria/javaExamples/README.txt create mode 100644 Legacy/Aria/javaExamples/actionExample.java create mode 100644 Legacy/Aria/javaExamples/joyHandler.java create mode 100644 Legacy/Aria/javaExamples/laserWander.java create mode 100644 Legacy/Aria/javaExamples/map.java create mode 100644 Legacy/Aria/javaExamples/robotSyncTaskExample.java create mode 100644 Legacy/Aria/javaExamples/simple.java create mode 100644 Legacy/Aria/javaExamples/socket.java create mode 100644 Legacy/Aria/lib/libAria.so create mode 100644 Legacy/Aria/maps/ActivMediaLab.map create mode 100644 Legacy/Aria/maps/columbia.map create mode 100644 Legacy/Aria/maps/office.map create mode 100644 Legacy/Aria/maps/triangle.map create mode 100644 Legacy/Aria/params/amigo-sh.p create mode 100644 Legacy/Aria/params/amigo.p create mode 100644 Legacy/Aria/params/mt400.p create mode 100644 Legacy/Aria/params/p2at.p create mode 100644 Legacy/Aria/params/p2at8+.p create mode 100644 Legacy/Aria/params/p2at8.p create mode 100644 Legacy/Aria/params/p2ce.p create mode 100644 Legacy/Aria/params/p2d8+.p create mode 100644 Legacy/Aria/params/p2d8.p create mode 100644 Legacy/Aria/params/p2de.p create mode 100644 Legacy/Aria/params/p2df.p create mode 100644 Legacy/Aria/params/p2dx.p create mode 100644 Legacy/Aria/params/p2it.p create mode 100644 Legacy/Aria/params/p2pb.p create mode 100644 Legacy/Aria/params/p2pp.p create mode 100644 Legacy/Aria/params/p3at-sh-lms1xx.p create mode 100644 Legacy/Aria/params/p3at-sh-lms500.p create mode 100644 Legacy/Aria/params/p3at-sh.p create mode 100644 Legacy/Aria/params/p3at.p create mode 100644 Legacy/Aria/params/p3atiw-sh.p create mode 100644 Legacy/Aria/params/p3dx-sh-lms1xx.p create mode 100644 Legacy/Aria/params/p3dx-sh-lms500.p create mode 100644 Legacy/Aria/params/p3dx-sh.p create mode 100644 Legacy/Aria/params/p3dx.p create mode 100644 Legacy/Aria/params/patrolbot-sh.p create mode 100644 Legacy/Aria/params/peoplebot-sh-lms1xx.p create mode 100644 Legacy/Aria/params/peoplebot-sh-lms500.p create mode 100644 Legacy/Aria/params/peoplebot-sh.p create mode 100644 Legacy/Aria/params/perfpb+.p create mode 100644 Legacy/Aria/params/perfpb.p create mode 100644 Legacy/Aria/params/pion1m.p create mode 100644 Legacy/Aria/params/pion1x.p create mode 100644 Legacy/Aria/params/pionat.p create mode 100644 Legacy/Aria/params/pioneer-lx.p create mode 100644 Legacy/Aria/params/powerbot-sh-lms500.p create mode 100644 Legacy/Aria/params/powerbot-sh-uarcs.p create mode 100644 Legacy/Aria/params/powerbot-sh.p create mode 100644 Legacy/Aria/params/powerbot.p create mode 100644 Legacy/Aria/params/psos1m.p create mode 100644 Legacy/Aria/params/psos1x.p create mode 100644 Legacy/Aria/params/psos43m.p create mode 100644 Legacy/Aria/params/researchPB-lms500.p create mode 100644 Legacy/Aria/params/researchPB.p create mode 100644 Legacy/Aria/params/seekur.p create mode 100644 Legacy/Aria/params/seekurjr.p create mode 100644 Legacy/Aria/params/wheelchair-sh.p create mode 100644 Legacy/Aria/python/ArNetworkingPy.vcxproj create mode 100644 Legacy/Aria/python/ArNetworkingPython.vcproj create mode 100644 Legacy/Aria/python/ArNetworkingPython.vcxproj create mode 100644 Legacy/Aria/python/ArNetworkingSwigPython.vcproj create mode 100644 Legacy/Aria/python/ArNetworkingSwigPython.vcxproj create mode 100644 Legacy/Aria/python/AriaPy-vc2003.sln create mode 100644 Legacy/Aria/python/AriaPy-vc2010.sln create mode 100644 Legacy/Aria/python/AriaPy.vcproj create mode 100644 Legacy/Aria/python/AriaPy.vcxproj create mode 100644 Legacy/Aria/python/AriaSwigPython.vcproj create mode 100644 Legacy/Aria/python/AriaSwigPython.vcxproj create mode 100644 Legacy/Aria/pythonExamples/README.txt create mode 100644 Legacy/Aria/pythonExamples/basicActions.py create mode 100644 Legacy/Aria/pythonExamples/configExample.cfg create mode 100644 Legacy/Aria/pythonExamples/configExample.py create mode 100644 Legacy/Aria/pythonExamples/customActions.py create mode 100644 Legacy/Aria/pythonExamples/pythonThreadTest.py create mode 100644 Legacy/Aria/pythonExamples/rangeDeviceReading.py create mode 100644 Legacy/Aria/pythonExamples/robotSyncTaskExample.py create mode 100644 Legacy/Aria/pythonExamples/simple.py create mode 100644 Legacy/Aria/pythonExamples/teleop.py create mode 100644 Legacy/Aria/src/ArACTS.cpp create mode 100644 Legacy/Aria/src/ArAMPTU.cpp create mode 100644 Legacy/Aria/src/ArASyncTask.cpp create mode 100644 Legacy/Aria/src/ArAction.cpp create mode 100644 Legacy/Aria/src/ArActionAvoidFront.cpp create mode 100644 Legacy/Aria/src/ArActionAvoidSide.cpp create mode 100644 Legacy/Aria/src/ArActionBumpers.cpp create mode 100644 Legacy/Aria/src/ArActionColorFollow.cpp create mode 100644 Legacy/Aria/src/ArActionConstantVelocity.cpp create mode 100644 Legacy/Aria/src/ArActionDeceleratingLimiter.cpp create mode 100644 Legacy/Aria/src/ArActionDesired.cpp create mode 100644 Legacy/Aria/src/ArActionDriveDistance.cpp create mode 100644 Legacy/Aria/src/ArActionGoto.cpp create mode 100644 Legacy/Aria/src/ArActionGotoStraight.cpp create mode 100644 Legacy/Aria/src/ArActionGroup.cpp create mode 100644 Legacy/Aria/src/ArActionGroups.cpp create mode 100644 Legacy/Aria/src/ArActionIRs.cpp create mode 100644 Legacy/Aria/src/ArActionInput.cpp create mode 100644 Legacy/Aria/src/ArActionJoydrive.cpp create mode 100644 Legacy/Aria/src/ArActionKeydrive.cpp create mode 100644 Legacy/Aria/src/ArActionLimiterBackwards.cpp create mode 100644 Legacy/Aria/src/ArActionLimiterForwards.cpp create mode 100644 Legacy/Aria/src/ArActionLimiterRot.cpp create mode 100644 Legacy/Aria/src/ArActionLimiterTableSensor.cpp create mode 100644 Legacy/Aria/src/ArActionMovementParameters.cpp create mode 100644 Legacy/Aria/src/ArActionMovementParametersDebugging.cpp create mode 100644 Legacy/Aria/src/ArActionRatioInput.cpp create mode 100644 Legacy/Aria/src/ArActionRobotJoydrive.cpp create mode 100644 Legacy/Aria/src/ArActionStallRecover.cpp create mode 100644 Legacy/Aria/src/ArActionStop.cpp create mode 100644 Legacy/Aria/src/ArActionTriangleDriveTo.cpp create mode 100644 Legacy/Aria/src/ArActionTurn.cpp create mode 100644 Legacy/Aria/src/ArAnalogGyro.cpp create mode 100644 Legacy/Aria/src/ArArg.cpp create mode 100644 Legacy/Aria/src/ArArgumentBuilder.cpp create mode 100644 Legacy/Aria/src/ArArgumentParser.cpp create mode 100644 Legacy/Aria/src/ArBasePacket.cpp create mode 100644 Legacy/Aria/src/ArBatteryConnector.cpp create mode 100644 Legacy/Aria/src/ArBatteryMTX.cpp create mode 100644 Legacy/Aria/src/ArBumpers.cpp create mode 100644 Legacy/Aria/src/ArCameraCollection.cpp create mode 100644 Legacy/Aria/src/ArCameraCommands.cpp create mode 100644 Legacy/Aria/src/ArCondition_LIN.cpp create mode 100644 Legacy/Aria/src/ArCondition_WIN.cpp create mode 100644 Legacy/Aria/src/ArConfig.cpp create mode 100644 Legacy/Aria/src/ArConfigArg.cpp create mode 100644 Legacy/Aria/src/ArConfigGroup.cpp create mode 100644 Legacy/Aria/src/ArDPPTU.cpp create mode 100644 Legacy/Aria/src/ArDataLogger.cpp create mode 100644 Legacy/Aria/src/ArDeviceConnection.cpp create mode 100644 Legacy/Aria/src/ArFileParser.cpp create mode 100644 Legacy/Aria/src/ArForbiddenRangeDevice.cpp create mode 100644 Legacy/Aria/src/ArFunctorASyncTask.cpp create mode 100644 Legacy/Aria/src/ArGPS.cpp create mode 100644 Legacy/Aria/src/ArGPSConnector.cpp create mode 100644 Legacy/Aria/src/ArGPSCoords.cpp create mode 100644 Legacy/Aria/src/ArGripper.cpp create mode 100644 Legacy/Aria/src/ArIRs.cpp create mode 100644 Legacy/Aria/src/ArInterpolation.cpp create mode 100644 Legacy/Aria/src/ArIrrfDevice.cpp create mode 100644 Legacy/Aria/src/ArJoyHandler.cpp create mode 100644 Legacy/Aria/src/ArJoyHandler_LIN.cpp create mode 100644 Legacy/Aria/src/ArJoyHandler_WIN.cpp create mode 100644 Legacy/Aria/src/ArKeyHandler.cpp create mode 100644 Legacy/Aria/src/ArLCDConnector.cpp create mode 100644 Legacy/Aria/src/ArLCDMTX.cpp create mode 100644 Legacy/Aria/src/ArLMS1XX.cpp create mode 100644 Legacy/Aria/src/ArLMS2xx.cpp create mode 100644 Legacy/Aria/src/ArLMS2xxPacket.cpp create mode 100644 Legacy/Aria/src/ArLMS2xxPacketReceiver.cpp create mode 100644 Legacy/Aria/src/ArLaser.cpp create mode 100644 Legacy/Aria/src/ArLaserConnector.cpp create mode 100644 Legacy/Aria/src/ArLaserFilter.cpp create mode 100644 Legacy/Aria/src/ArLaserLogger.cpp create mode 100644 Legacy/Aria/src/ArLaserReflectorDevice.cpp create mode 100644 Legacy/Aria/src/ArLineFinder.cpp create mode 100644 Legacy/Aria/src/ArLog.cpp create mode 100644 Legacy/Aria/src/ArLogFileConnection.cpp create mode 100644 Legacy/Aria/src/ArMD5Calculator.cpp create mode 100644 Legacy/Aria/src/ArMTXIO.cpp create mode 100644 Legacy/Aria/src/ArMap.cpp create mode 100644 Legacy/Aria/src/ArMapComponents.cpp create mode 100644 Legacy/Aria/src/ArMapInterface.cpp create mode 100644 Legacy/Aria/src/ArMapObject.cpp create mode 100644 Legacy/Aria/src/ArMapUtils.cpp create mode 100644 Legacy/Aria/src/ArMode.cpp create mode 100644 Legacy/Aria/src/ArModes.cpp create mode 100644 Legacy/Aria/src/ArModule.cpp create mode 100644 Legacy/Aria/src/ArModuleLoader.cpp create mode 100644 Legacy/Aria/src/ArMutex.cpp create mode 100644 Legacy/Aria/src/ArMutex_LIN.cpp create mode 100644 Legacy/Aria/src/ArMutex_WIN.cpp create mode 100644 Legacy/Aria/src/ArNMEAParser.cpp create mode 100644 Legacy/Aria/src/ArNetServer.cpp create mode 100644 Legacy/Aria/src/ArNovatelGPS.cpp create mode 100644 Legacy/Aria/src/ArP2Arm.cpp create mode 100644 Legacy/Aria/src/ArPTZ.cpp create mode 100644 Legacy/Aria/src/ArPTZConnector.cpp create mode 100644 Legacy/Aria/src/ArPriorityResolver.cpp create mode 100644 Legacy/Aria/src/ArRVisionPTZ.cpp create mode 100644 Legacy/Aria/src/ArRangeBuffer.cpp create mode 100644 Legacy/Aria/src/ArRangeDevice.cpp create mode 100644 Legacy/Aria/src/ArRangeDeviceThreaded.cpp create mode 100644 Legacy/Aria/src/ArRatioInputJoydrive.cpp create mode 100644 Legacy/Aria/src/ArRatioInputKeydrive.cpp create mode 100644 Legacy/Aria/src/ArRatioInputRobotJoydrive.cpp create mode 100644 Legacy/Aria/src/ArRecurrentTask.cpp create mode 100644 Legacy/Aria/src/ArRobot.cpp create mode 100644 Legacy/Aria/src/ArRobotBatteryPacketReader.cpp create mode 100644 Legacy/Aria/src/ArRobotConfig.cpp create mode 100644 Legacy/Aria/src/ArRobotConfigPacketReader.cpp create mode 100644 Legacy/Aria/src/ArRobotConnector.cpp create mode 100644 Legacy/Aria/src/ArRobotJoyHandler.cpp create mode 100644 Legacy/Aria/src/ArRobotPacket.cpp create mode 100644 Legacy/Aria/src/ArRobotPacketReaderThread.cpp create mode 100644 Legacy/Aria/src/ArRobotPacketReceiver.cpp create mode 100644 Legacy/Aria/src/ArRobotPacketSender.cpp create mode 100644 Legacy/Aria/src/ArRobotParams.cpp create mode 100644 Legacy/Aria/src/ArRobotTypes.cpp create mode 100644 Legacy/Aria/src/ArS3Series.cpp create mode 100644 Legacy/Aria/src/ArSZSeries.cpp create mode 100644 Legacy/Aria/src/ArSensorReading.cpp create mode 100644 Legacy/Aria/src/ArSerialConnection_LIN.cpp create mode 100644 Legacy/Aria/src/ArSerialConnection_WIN.cpp create mode 100644 Legacy/Aria/src/ArSick.cpp create mode 100644 Legacy/Aria/src/ArSignalHandler_LIN.cpp create mode 100644 Legacy/Aria/src/ArSignalHandler_WIN.cpp create mode 100644 Legacy/Aria/src/ArSimpleConnector.cpp create mode 100644 Legacy/Aria/src/ArSimulatedLaser.cpp create mode 100644 Legacy/Aria/src/ArSocket.cpp create mode 100644 Legacy/Aria/src/ArSocket_LIN.cpp create mode 100644 Legacy/Aria/src/ArSocket_WIN.cpp create mode 100644 Legacy/Aria/src/ArSonarAutoDisabler.cpp create mode 100644 Legacy/Aria/src/ArSonarConnector.cpp create mode 100644 Legacy/Aria/src/ArSonarDevice.cpp create mode 100644 Legacy/Aria/src/ArSonarMTX.cpp create mode 100644 Legacy/Aria/src/ArSonyPTZ.cpp create mode 100644 Legacy/Aria/src/ArSoundPlayer.cpp create mode 100644 Legacy/Aria/src/ArSoundsQueue.cpp create mode 100644 Legacy/Aria/src/ArSpeech.cpp create mode 100644 Legacy/Aria/src/ArStringInfoGroup.cpp create mode 100644 Legacy/Aria/src/ArSyncLoop.cpp create mode 100644 Legacy/Aria/src/ArSyncTask.cpp create mode 100644 Legacy/Aria/src/ArSystemStatus.cpp create mode 100644 Legacy/Aria/src/ArTCM2.cpp create mode 100644 Legacy/Aria/src/ArTCMCompassDirect.cpp create mode 100644 Legacy/Aria/src/ArTCMCompassRobot.cpp create mode 100644 Legacy/Aria/src/ArTcpConnection.cpp create mode 100644 Legacy/Aria/src/ArThread.cpp create mode 100644 Legacy/Aria/src/ArThread_LIN.cpp create mode 100644 Legacy/Aria/src/ArThread_WIN.cpp create mode 100644 Legacy/Aria/src/ArTransform.cpp create mode 100644 Legacy/Aria/src/ArTrimbleGPS.cpp create mode 100644 Legacy/Aria/src/ArUrg.cpp create mode 100644 Legacy/Aria/src/ArUrg_2_0.cpp create mode 100644 Legacy/Aria/src/ArVCC4.cpp create mode 100644 Legacy/Aria/src/ArVersalogicIO.cpp create mode 100644 Legacy/Aria/src/Aria.cpp create mode 100644 Legacy/Aria/src/AriaDLL-vc2003.vcproj create mode 100644 Legacy/Aria/src/AriaDLL-vc2008.vcproj create mode 100644 Legacy/Aria/src/AriaDLL-vc2010.vcxproj create mode 100644 Legacy/Aria/src/AriaStatic-vc2003.sln create mode 100644 Legacy/Aria/src/AriaStatic-vc2003.vcproj create mode 100644 Legacy/Aria/src/AriaStatic-vc2008.vcproj create mode 100644 Legacy/Aria/src/AriaStatic-vc2010.vcxproj create mode 100644 Legacy/Aria/src/AriaStatic.sln create mode 100644 Legacy/Aria/src/Makefile create mode 100644 Legacy/Aria/src/ariaUtil.cpp create mode 100644 Legacy/Aria/src/md5.cpp create mode 100644 Legacy/Aria/tests/ArTestConfig.cpp create mode 100644 Legacy/Aria/tests/ArTestConfig.h create mode 100644 Legacy/Aria/tests/AriaTests-vc2003.sln create mode 100644 Legacy/Aria/tests/AriaTests-vc2008.sln create mode 100644 Legacy/Aria/tests/Makefile create mode 100644 Legacy/Aria/tests/README.txt create mode 100644 Legacy/Aria/tests/absoluteHeadingActionTest.cpp create mode 100644 Legacy/Aria/tests/accDecelMaxTest.cpp create mode 100644 Legacy/Aria/tests/actionArgumentTest.cpp create mode 100644 Legacy/Aria/tests/actionAverageTest.cpp create mode 100644 Legacy/Aria/tests/actionManagementTest-vc2008.vcproj create mode 100644 Legacy/Aria/tests/actionManagementTest.cpp create mode 100644 Legacy/Aria/tests/actsTest.cpp create mode 100644 Legacy/Aria/tests/angleBetweenTest.cpp create mode 100644 Legacy/Aria/tests/angleFixTest.cpp create mode 100644 Legacy/Aria/tests/angleTest.cpp create mode 100644 Legacy/Aria/tests/asyncConnectTest.cpp create mode 100644 Legacy/Aria/tests/auxSerialTest.cpp create mode 100644 Legacy/Aria/tests/batteryTest.cpp create mode 100644 Legacy/Aria/tests/callbackTest.cpp create mode 100644 Legacy/Aria/tests/chargeTest.cpp create mode 100644 Legacy/Aria/tests/compassDirect.cpp create mode 100644 Legacy/Aria/tests/compassDirectCalib.cpp create mode 100644 Legacy/Aria/tests/configSectionTest-vc2008.vcproj create mode 100644 Legacy/Aria/tests/configSectionTest.cpp create mode 100644 Legacy/Aria/tests/configTest-vc2008.vcproj create mode 100644 Legacy/Aria/tests/configTest.cpp create mode 100644 Legacy/Aria/tests/configTest.txt create mode 100644 Legacy/Aria/tests/connectTest.cpp create mode 100644 Legacy/Aria/tests/connectionTest.cpp create mode 100644 Legacy/Aria/tests/dcdTest.cpp create mode 100644 Legacy/Aria/tests/deleteArgs.cpp create mode 100644 Legacy/Aria/tests/driveFast.cpp create mode 100644 Legacy/Aria/tests/driveHardDirect.cpp create mode 100644 Legacy/Aria/tests/encoderCorrectionTest.cpp create mode 100644 Legacy/Aria/tests/encoderTest.cpp create mode 100644 Legacy/Aria/tests/fileParserTest.cpp create mode 100644 Legacy/Aria/tests/fileParserTestBad.txt create mode 100644 Legacy/Aria/tests/fileParserTestGood.txt create mode 100644 Legacy/Aria/tests/functorTest.cpp create mode 100644 Legacy/Aria/tests/gotoTest.cpp create mode 100644 Legacy/Aria/tests/gpsCoordsTest.cpp create mode 100644 Legacy/Aria/tests/gpsInternals.cpp create mode 100644 Legacy/Aria/tests/gripperStateFlagsTest.cpp create mode 100644 Legacy/Aria/tests/gyroDrive-vc2008.vcproj create mode 100644 Legacy/Aria/tests/gyroDrive.cpp create mode 100644 Legacy/Aria/tests/gyroDrive.vcproj create mode 100644 Legacy/Aria/tests/hardDriveWander.cpp create mode 100644 Legacy/Aria/tests/interpolationTest.cpp create mode 100644 Legacy/Aria/tests/ioTest.cpp create mode 100644 Legacy/Aria/tests/joytest-vc2008.vcproj create mode 100644 Legacy/Aria/tests/joytest.cpp create mode 100644 Legacy/Aria/tests/joytest.vcproj create mode 100644 Legacy/Aria/tests/keyHandlerTest.cpp create mode 100644 Legacy/Aria/tests/keys.cpp create mode 100644 Legacy/Aria/tests/lineTest.cpp create mode 100644 Legacy/Aria/tests/lms2xxTest.cpp create mode 100644 Legacy/Aria/tests/logRobotJoystick.cpp create mode 100644 Legacy/Aria/tests/logSIPData.cpp create mode 100644 Legacy/Aria/tests/logSIPs.cpp create mode 100644 Legacy/Aria/tests/mapTest-vc2003.vcproj create mode 100644 Legacy/Aria/tests/mapTest.cpp create mode 100644 Legacy/Aria/tests/mathTests.cpp create mode 100644 Legacy/Aria/tests/moduleActionExample.cpp create mode 100644 Legacy/Aria/tests/moduleActionExample2_Mod.cpp create mode 100644 Legacy/Aria/tests/moduleActionExample_Mod.cpp create mode 100644 Legacy/Aria/tests/moveCommandTest.cpp create mode 100644 Legacy/Aria/tests/moveRobotInSim.cpp create mode 100644 Legacy/Aria/tests/moveRobotTest.cpp create mode 100644 Legacy/Aria/tests/mtxIOTest.cpp create mode 100644 Legacy/Aria/tests/mutexLockWarning-vc2008.vcproj create mode 100644 Legacy/Aria/tests/mutexLockWarning.cpp create mode 100644 Legacy/Aria/tests/nmeaParser.cpp create mode 100644 Legacy/Aria/tests/optoIOtest.cpp create mode 100644 Legacy/Aria/tests/p2osSlamTest.cpp create mode 100644 Legacy/Aria/tests/poseTest.cpp create mode 100644 Legacy/Aria/tests/ptzTest.cpp create mode 100644 Legacy/Aria/tests/robotConfigPacketReaderTest.cpp create mode 100644 Legacy/Aria/tests/robotListTest.cpp create mode 100644 Legacy/Aria/tests/robotPacketHandlerTest.cpp create mode 100644 Legacy/Aria/tests/rotVelActionExample.cpp create mode 100644 Legacy/Aria/tests/runtimeTest.cpp create mode 100644 Legacy/Aria/tests/samePriorityActionTest.cpp create mode 100644 Legacy/Aria/tests/serialDump.cpp create mode 100644 Legacy/Aria/tests/serialTest.cpp create mode 100644 Legacy/Aria/tests/serialTest2.cpp create mode 100644 Legacy/Aria/tests/showFirmwareParameters.cpp create mode 100644 Legacy/Aria/tests/sickMiddleTest.cpp create mode 100644 Legacy/Aria/tests/sickQuadrantReadings.cpp create mode 100644 Legacy/Aria/tests/sickSafeAutoLogger.cpp create mode 100644 Legacy/Aria/tests/sickSimpleTest.cpp create mode 100644 Legacy/Aria/tests/sickTest.cpp create mode 100644 Legacy/Aria/tests/sickTestAll.cpp create mode 100644 Legacy/Aria/tests/signalTest.cpp create mode 100644 Legacy/Aria/tests/sonarAutoDisablerTest.cpp create mode 100644 Legacy/Aria/tests/sonarDeviceTest.cpp create mode 100644 Legacy/Aria/tests/sonarMonitor.cpp create mode 100644 Legacy/Aria/tests/sonarQuadrantReadings.cpp create mode 100644 Legacy/Aria/tests/sonarTest.cpp create mode 100644 Legacy/Aria/tests/soundPlayer.cpp create mode 100644 Legacy/Aria/tests/stallTest.cpp create mode 100644 Legacy/Aria/tests/stressTest.cpp create mode 100644 Legacy/Aria/tests/stripQuoteTest.cpp create mode 100644 Legacy/Aria/tests/systemCallTest.cpp create mode 100644 Legacy/Aria/tests/systemStatusBasic.cpp create mode 100644 Legacy/Aria/tests/systemStatusThread.cpp create mode 100644 Legacy/Aria/tests/tcm2Test.cpp create mode 100644 Legacy/Aria/tests/tcpConnectionTest.cpp create mode 100644 Legacy/Aria/tests/testAbsoluteMaxesCommand.cpp create mode 100644 Legacy/Aria/tests/testCOM.cpp create mode 100644 Legacy/Aria/tests/testMobileSim.cpp create mode 100644 Legacy/Aria/tests/testsound.sw.raw create mode 100644 Legacy/Aria/tests/threadTest.cpp create mode 100644 Legacy/Aria/tests/timePrinter.cpp create mode 100644 Legacy/Aria/tests/timeTest.cpp create mode 100644 Legacy/Aria/tests/timingTest-vc2008.vcproj create mode 100644 Legacy/Aria/tests/timingTest.cpp create mode 100644 Legacy/Aria/tests/transformTest.cpp create mode 100644 Legacy/Aria/tests/triangleAccuracyTest.cpp create mode 100644 Legacy/Aria/tests/usertasktest.cpp create mode 100644 Legacy/Aria/tests/vcc4Test.cpp create mode 100644 Legacy/Aria/tests/velTest.cpp create mode 100644 Legacy/Aria/tests/wanderAndLogBumps.cpp create mode 100644 Legacy/Aria/utils/Makefile create mode 100644 Legacy/Aria/utils/addSfWorldLinesToArMap.cpp create mode 100644 Legacy/Aria/utils/convertSfWorldToArMap.cpp create mode 100644 Legacy/Aria/utils/genCommandLineOptionDocs.cpp create mode 100644 Legacy/Aria/utils/genCommandLineOptionDocs.vcxproj create mode 100644 Legacy/Aria/utils/genCommandLineOptionDocsForArNetworking.vcxproj create mode 100755 Legacy/Aria/utils/makeParams create mode 100644 Legacy/Aria/utils/makeParams.cpp create mode 100644 Legacy/Aria/utils/makeParams.vcproj create mode 100644 Legacy/Aria/utils/makeParams.vcxproj create mode 100644 Legacy/Aria/version.txt create mode 100644 Legacy/Dockerfile create mode 100755 Legacy/entrypoint.sh create mode 100644 Legacy/ws_linux/.catkin_workspace create mode 100644 Legacy/ws_linux/build/CATKIN_IGNORE create mode 100644 Legacy/ws_linux/build/CMakeCache.txt create mode 100644 Legacy/ws_linux/build/CMakeFiles/CMakeCCompiler.cmake create mode 100644 Legacy/ws_linux/build/CMakeFiles/CMakeCXXCompiler.cmake create mode 100755 Legacy/ws_linux/build/CMakeFiles/CMakeDetermineCompilerABI_C.bin create mode 100755 Legacy/ws_linux/build/CMakeFiles/CMakeDetermineCompilerABI_CXX.bin create mode 100644 Legacy/ws_linux/build/CMakeFiles/CMakeDirectoryInformation.cmake create mode 100644 Legacy/ws_linux/build/CMakeFiles/CMakeError.log create mode 100644 Legacy/ws_linux/build/CMakeFiles/CMakeOutput.log create mode 100644 Legacy/ws_linux/build/CMakeFiles/CMakeRuleHashes.txt create mode 100644 Legacy/ws_linux/build/CMakeFiles/CMakeSystem.cmake create mode 100644 Legacy/ws_linux/build/CMakeFiles/CompilerIdC/CMakeCCompilerId.c create mode 100755 Legacy/ws_linux/build/CMakeFiles/CompilerIdC/a.out create mode 100644 Legacy/ws_linux/build/CMakeFiles/CompilerIdCXX/CMakeCXXCompilerId.cpp create mode 100755 Legacy/ws_linux/build/CMakeFiles/CompilerIdCXX/a.out create mode 100644 Legacy/ws_linux/build/CMakeFiles/Makefile.cmake create mode 100644 Legacy/ws_linux/build/CMakeFiles/Makefile2 create mode 100644 Legacy/ws_linux/build/CMakeFiles/TargetDirectories.txt create mode 100644 Legacy/ws_linux/build/CMakeFiles/clean_test_results.dir/DependInfo.cmake create mode 100644 Legacy/ws_linux/build/CMakeFiles/clean_test_results.dir/build.make create mode 100644 Legacy/ws_linux/build/CMakeFiles/clean_test_results.dir/cmake_clean.cmake create mode 100644 Legacy/ws_linux/build/CMakeFiles/clean_test_results.dir/progress.make create mode 100644 Legacy/ws_linux/build/CMakeFiles/cmake.check_cache create mode 100644 Legacy/ws_linux/build/CMakeFiles/doxygen.dir/DependInfo.cmake create mode 100644 Legacy/ws_linux/build/CMakeFiles/doxygen.dir/build.make create mode 100644 Legacy/ws_linux/build/CMakeFiles/doxygen.dir/cmake_clean.cmake create mode 100644 Legacy/ws_linux/build/CMakeFiles/doxygen.dir/progress.make create mode 100644 Legacy/ws_linux/build/CMakeFiles/progress.marks create mode 100644 Legacy/ws_linux/build/CMakeFiles/run_tests.dir/DependInfo.cmake create mode 100644 Legacy/ws_linux/build/CMakeFiles/run_tests.dir/build.make create mode 100644 Legacy/ws_linux/build/CMakeFiles/run_tests.dir/cmake_clean.cmake create mode 100644 Legacy/ws_linux/build/CMakeFiles/run_tests.dir/progress.make create mode 100644 Legacy/ws_linux/build/CMakeFiles/tests.dir/DependInfo.cmake create mode 100644 Legacy/ws_linux/build/CMakeFiles/tests.dir/build.make create mode 100644 Legacy/ws_linux/build/CMakeFiles/tests.dir/cmake_clean.cmake create mode 100644 Legacy/ws_linux/build/CMakeFiles/tests.dir/progress.make create mode 100644 Legacy/ws_linux/build/CTestTestfile.cmake create mode 100644 Legacy/ws_linux/build/Makefile create mode 100644 Legacy/ws_linux/build/catkin/catkin_generated/version/package.cmake create mode 100755 Legacy/ws_linux/build/catkin_generated/env_cached.sh create mode 100644 Legacy/ws_linux/build/catkin_generated/generate_cached_setup.py create mode 100644 Legacy/ws_linux/build/catkin_generated/installspace/.rosinstall create mode 100755 Legacy/ws_linux/build/catkin_generated/installspace/_setup_util.py create mode 100755 Legacy/ws_linux/build/catkin_generated/installspace/env.sh create mode 100644 Legacy/ws_linux/build/catkin_generated/installspace/setup.bash create mode 100644 Legacy/ws_linux/build/catkin_generated/installspace/setup.sh create mode 100644 Legacy/ws_linux/build/catkin_generated/installspace/setup.zsh create mode 100644 Legacy/ws_linux/build/catkin_generated/order_packages.cmake create mode 100644 Legacy/ws_linux/build/catkin_generated/order_packages.py create mode 100755 Legacy/ws_linux/build/catkin_generated/setup_cached.sh create mode 100644 Legacy/ws_linux/build/catkin_generated/stamps/Project/interrogate_setup_dot_py.py.stamp create mode 100644 Legacy/ws_linux/build/catkin_generated/stamps/Project/order_packages.cmake.em.stamp create mode 100644 Legacy/ws_linux/build/catkin_generated/stamps/Project/package.xml.stamp create mode 100644 Legacy/ws_linux/build/catkin_make.cache create mode 100644 Legacy/ws_linux/build/cmake_install.cmake create mode 100644 Legacy/ws_linux/build/gtest/CMakeFiles/CMakeDirectoryInformation.cmake create mode 100644 Legacy/ws_linux/build/gtest/CMakeFiles/gtest.dir/DependInfo.cmake create mode 100644 Legacy/ws_linux/build/gtest/CMakeFiles/gtest.dir/build.make create mode 100644 Legacy/ws_linux/build/gtest/CMakeFiles/gtest.dir/cmake_clean.cmake create mode 100644 Legacy/ws_linux/build/gtest/CMakeFiles/gtest.dir/depend.make create mode 100644 Legacy/ws_linux/build/gtest/CMakeFiles/gtest.dir/flags.make create mode 100644 Legacy/ws_linux/build/gtest/CMakeFiles/gtest.dir/link.txt create mode 100644 Legacy/ws_linux/build/gtest/CMakeFiles/gtest.dir/progress.make create mode 100644 Legacy/ws_linux/build/gtest/CMakeFiles/gtest_main.dir/DependInfo.cmake create mode 100644 Legacy/ws_linux/build/gtest/CMakeFiles/gtest_main.dir/build.make create mode 100644 Legacy/ws_linux/build/gtest/CMakeFiles/gtest_main.dir/cmake_clean.cmake create mode 100644 Legacy/ws_linux/build/gtest/CMakeFiles/gtest_main.dir/depend.make create mode 100644 Legacy/ws_linux/build/gtest/CMakeFiles/gtest_main.dir/flags.make create mode 100644 Legacy/ws_linux/build/gtest/CMakeFiles/gtest_main.dir/link.txt create mode 100644 Legacy/ws_linux/build/gtest/CMakeFiles/gtest_main.dir/progress.make create mode 100644 Legacy/ws_linux/build/gtest/CMakeFiles/progress.marks create mode 100644 Legacy/ws_linux/build/gtest/CTestTestfile.cmake create mode 100644 Legacy/ws_linux/build/gtest/Makefile create mode 100644 Legacy/ws_linux/build/gtest/cmake_install.cmake create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/CMakeDirectoryInformation.cmake create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/RosAria.dir/CXX.includecache create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/RosAria.dir/DependInfo.cmake create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/RosAria.dir/build.make create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/RosAria.dir/cmake_clean.cmake create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/RosAria.dir/depend.internal create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/RosAria.dir/depend.make create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/RosAria.dir/flags.make create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/RosAria.dir/link.txt create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/RosAria.dir/progress.make create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_generate_messages_cpp.dir/DependInfo.cmake create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_generate_messages_cpp.dir/build.make create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_generate_messages_cpp.dir/cmake_clean.cmake create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_generate_messages_cpp.dir/progress.make create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_generate_messages_lisp.dir/DependInfo.cmake create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_generate_messages_lisp.dir/build.make create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_generate_messages_lisp.dir/cmake_clean.cmake create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_generate_messages_lisp.dir/progress.make create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_generate_messages_py.dir/DependInfo.cmake create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_generate_messages_py.dir/build.make create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_generate_messages_py.dir/cmake_clean.cmake create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_generate_messages_py.dir/progress.make create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_msgs_generate_messages_cpp.dir/DependInfo.cmake create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_msgs_generate_messages_cpp.dir/build.make create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_msgs_generate_messages_cpp.dir/cmake_clean.cmake create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_msgs_generate_messages_cpp.dir/progress.make create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_msgs_generate_messages_lisp.dir/DependInfo.cmake create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_msgs_generate_messages_lisp.dir/build.make create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_msgs_generate_messages_lisp.dir/cmake_clean.cmake create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_msgs_generate_messages_lisp.dir/progress.make create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_msgs_generate_messages_py.dir/DependInfo.cmake create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_msgs_generate_messages_py.dir/build.make create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_msgs_generate_messages_py.dir/cmake_clean.cmake create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_msgs_generate_messages_py.dir/progress.make create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/dynamic_reconfigure_gencfg.dir/DependInfo.cmake create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/dynamic_reconfigure_gencfg.dir/build.make create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/dynamic_reconfigure_gencfg.dir/cmake_clean.cmake create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/dynamic_reconfigure_gencfg.dir/progress.make create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_cpp.dir/DependInfo.cmake create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_cpp.dir/build.make create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_cpp.dir/cmake_clean.cmake create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_cpp.dir/progress.make create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_lisp.dir/DependInfo.cmake create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_lisp.dir/build.make create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_lisp.dir/cmake_clean.cmake create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_lisp.dir/progress.make create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_py.dir/DependInfo.cmake create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_py.dir/build.make create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_py.dir/cmake_clean.cmake create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_py.dir/progress.make create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/nav_msgs_generate_messages_cpp.dir/DependInfo.cmake create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/nav_msgs_generate_messages_cpp.dir/build.make create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/nav_msgs_generate_messages_cpp.dir/cmake_clean.cmake create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/nav_msgs_generate_messages_cpp.dir/progress.make create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/nav_msgs_generate_messages_lisp.dir/DependInfo.cmake create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/nav_msgs_generate_messages_lisp.dir/build.make create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/nav_msgs_generate_messages_lisp.dir/cmake_clean.cmake create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/nav_msgs_generate_messages_lisp.dir/progress.make create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/nav_msgs_generate_messages_py.dir/DependInfo.cmake create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/nav_msgs_generate_messages_py.dir/build.make create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/nav_msgs_generate_messages_py.dir/cmake_clean.cmake create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/nav_msgs_generate_messages_py.dir/progress.make create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/progress.marks create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_gencfg.dir/DependInfo.cmake create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_gencfg.dir/build.make create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_gencfg.dir/cmake_clean.cmake create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_gencfg.dir/depend.internal create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_gencfg.dir/depend.make create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_gencfg.dir/progress.make create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_gencpp.dir/DependInfo.cmake create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_gencpp.dir/build.make create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_gencpp.dir/cmake_clean.cmake create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_gencpp.dir/depend.internal create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_gencpp.dir/depend.make create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_gencpp.dir/progress.make create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages.dir/DependInfo.cmake create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages.dir/build.make create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages.dir/cmake_clean.cmake create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages.dir/depend.internal create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages.dir/depend.make create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages.dir/progress.make create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages_cpp.dir/DependInfo.cmake create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages_cpp.dir/build.make create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages_cpp.dir/cmake_clean.cmake create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages_cpp.dir/depend.internal create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages_cpp.dir/depend.make create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages_cpp.dir/progress.make create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages_lisp.dir/DependInfo.cmake create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages_lisp.dir/build.make create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages_lisp.dir/cmake_clean.cmake create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages_lisp.dir/depend.internal create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages_lisp.dir/depend.make create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages_lisp.dir/progress.make create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages_py.dir/DependInfo.cmake create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages_py.dir/build.make create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages_py.dir/cmake_clean.cmake create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages_py.dir/depend.internal create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages_py.dir/depend.make create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages_py.dir/progress.make create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_genlisp.dir/DependInfo.cmake create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_genlisp.dir/build.make create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_genlisp.dir/cmake_clean.cmake create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_genlisp.dir/progress.make create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_genpy.dir/DependInfo.cmake create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_genpy.dir/build.make create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_genpy.dir/cmake_clean.cmake create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_genpy.dir/progress.make create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/roscpp_generate_messages_cpp.dir/DependInfo.cmake create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/roscpp_generate_messages_cpp.dir/build.make create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/roscpp_generate_messages_cpp.dir/cmake_clean.cmake create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/roscpp_generate_messages_cpp.dir/progress.make create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/roscpp_generate_messages_lisp.dir/DependInfo.cmake create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/roscpp_generate_messages_lisp.dir/build.make create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/roscpp_generate_messages_lisp.dir/cmake_clean.cmake create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/roscpp_generate_messages_lisp.dir/progress.make create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/roscpp_generate_messages_py.dir/DependInfo.cmake create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/roscpp_generate_messages_py.dir/build.make create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/roscpp_generate_messages_py.dir/cmake_clean.cmake create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/roscpp_generate_messages_py.dir/progress.make create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/rosgraph_msgs_generate_messages_cpp.dir/DependInfo.cmake create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/rosgraph_msgs_generate_messages_cpp.dir/build.make create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/rosgraph_msgs_generate_messages_cpp.dir/cmake_clean.cmake create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/rosgraph_msgs_generate_messages_cpp.dir/progress.make create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/rosgraph_msgs_generate_messages_lisp.dir/DependInfo.cmake create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/rosgraph_msgs_generate_messages_lisp.dir/build.make create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/rosgraph_msgs_generate_messages_lisp.dir/cmake_clean.cmake create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/rosgraph_msgs_generate_messages_lisp.dir/progress.make create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/rosgraph_msgs_generate_messages_py.dir/DependInfo.cmake create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/rosgraph_msgs_generate_messages_py.dir/build.make create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/rosgraph_msgs_generate_messages_py.dir/cmake_clean.cmake create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/rosgraph_msgs_generate_messages_py.dir/progress.make create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/sensor_msgs_generate_messages_cpp.dir/DependInfo.cmake create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/sensor_msgs_generate_messages_cpp.dir/build.make create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/sensor_msgs_generate_messages_cpp.dir/cmake_clean.cmake create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/sensor_msgs_generate_messages_cpp.dir/progress.make create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/sensor_msgs_generate_messages_lisp.dir/DependInfo.cmake create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/sensor_msgs_generate_messages_lisp.dir/build.make create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/sensor_msgs_generate_messages_lisp.dir/cmake_clean.cmake create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/sensor_msgs_generate_messages_lisp.dir/progress.make create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/sensor_msgs_generate_messages_py.dir/DependInfo.cmake create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/sensor_msgs_generate_messages_py.dir/build.make create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/sensor_msgs_generate_messages_py.dir/cmake_clean.cmake create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/sensor_msgs_generate_messages_py.dir/progress.make create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/tf2_msgs_generate_messages_cpp.dir/DependInfo.cmake create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/tf2_msgs_generate_messages_cpp.dir/build.make create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/tf2_msgs_generate_messages_cpp.dir/cmake_clean.cmake create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/tf2_msgs_generate_messages_cpp.dir/progress.make create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/tf2_msgs_generate_messages_lisp.dir/DependInfo.cmake create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/tf2_msgs_generate_messages_lisp.dir/build.make create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/tf2_msgs_generate_messages_lisp.dir/cmake_clean.cmake create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/tf2_msgs_generate_messages_lisp.dir/progress.make create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/tf2_msgs_generate_messages_py.dir/DependInfo.cmake create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/tf2_msgs_generate_messages_py.dir/build.make create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/tf2_msgs_generate_messages_py.dir/cmake_clean.cmake create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/tf2_msgs_generate_messages_py.dir/progress.make create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/tf_generate_messages_cpp.dir/DependInfo.cmake create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/tf_generate_messages_cpp.dir/build.make create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/tf_generate_messages_cpp.dir/cmake_clean.cmake create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/tf_generate_messages_cpp.dir/progress.make create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/tf_generate_messages_lisp.dir/DependInfo.cmake create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/tf_generate_messages_lisp.dir/build.make create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/tf_generate_messages_lisp.dir/cmake_clean.cmake create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/tf_generate_messages_lisp.dir/progress.make create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/tf_generate_messages_py.dir/DependInfo.cmake create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/tf_generate_messages_py.dir/build.make create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/tf_generate_messages_py.dir/cmake_clean.cmake create mode 100644 Legacy/ws_linux/build/rosaria/CMakeFiles/tf_generate_messages_py.dir/progress.make create mode 100644 Legacy/ws_linux/build/rosaria/CTestTestfile.cmake create mode 100644 Legacy/ws_linux/build/rosaria/Makefile create mode 100644 Legacy/ws_linux/build/rosaria/catkin_generated/installspace/rosaria-msg-extras.cmake create mode 100644 Legacy/ws_linux/build/rosaria/catkin_generated/installspace/rosaria-msg-paths-context.py create mode 100644 Legacy/ws_linux/build/rosaria/catkin_generated/installspace/rosaria-msg-paths.cmake create mode 100644 Legacy/ws_linux/build/rosaria/catkin_generated/installspace/rosaria.pc create mode 100644 Legacy/ws_linux/build/rosaria/catkin_generated/installspace/rosariaConfig-version.cmake create mode 100644 Legacy/ws_linux/build/rosaria/catkin_generated/installspace/rosariaConfig.cmake create mode 100644 Legacy/ws_linux/build/rosaria/catkin_generated/ordered_paths.cmake create mode 100644 Legacy/ws_linux/build/rosaria/catkin_generated/package.cmake create mode 100644 Legacy/ws_linux/build/rosaria/catkin_generated/pkg.develspace.context.pc.py create mode 100644 Legacy/ws_linux/build/rosaria/catkin_generated/pkg.installspace.context.pc.py create mode 100644 Legacy/ws_linux/build/rosaria/catkin_generated/rosaria-msg-extras.cmake.develspace.in create mode 100644 Legacy/ws_linux/build/rosaria/catkin_generated/rosaria-msg-extras.cmake.installspace.in create mode 100644 Legacy/ws_linux/build/rosaria/catkin_generated/rosaria-msg-paths-context.py rename package.xml => Legacy/ws_linux/build/rosaria/catkin_generated/stamps/rosaria/package.xml.stamp (100%) create mode 100644 Legacy/ws_linux/build/rosaria/catkin_generated/stamps/rosaria/pkg-genmsg.cmake.em.stamp create mode 100644 Legacy/ws_linux/build/rosaria/catkin_generated/stamps/rosaria/pkg-msg-paths.cmake.em.stamp create mode 100644 Legacy/ws_linux/build/rosaria/catkin_generated/stamps/rosaria/pkg.pc.em.stamp create mode 100644 Legacy/ws_linux/build/rosaria/cmake/rosaria-genmsg-context.py create mode 100644 Legacy/ws_linux/build/rosaria/cmake/rosaria-genmsg.cmake create mode 100644 Legacy/ws_linux/build/rosaria/cmake_install.cmake create mode 100644 Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/CMakeDirectoryInformation.cmake create mode 100644 Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_cpp.dir/DependInfo.cmake create mode 100644 Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_cpp.dir/build.make create mode 100644 Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_cpp.dir/cmake_clean.cmake create mode 100644 Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_cpp.dir/depend.internal create mode 100644 Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_cpp.dir/depend.make create mode 100644 Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_cpp.dir/progress.make create mode 100644 Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_lisp.dir/DependInfo.cmake create mode 100644 Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_lisp.dir/build.make create mode 100644 Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_lisp.dir/cmake_clean.cmake create mode 100644 Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_lisp.dir/depend.internal create mode 100644 Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_lisp.dir/depend.make create mode 100644 Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_lisp.dir/progress.make create mode 100644 Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_py.dir/DependInfo.cmake create mode 100644 Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_py.dir/build.make create mode 100644 Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_py.dir/cmake_clean.cmake create mode 100644 Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_py.dir/depend.internal create mode 100644 Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_py.dir/depend.make create mode 100644 Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_py.dir/progress.make create mode 100644 Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/progress.marks create mode 100644 Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_gencpp.dir/DependInfo.cmake create mode 100644 Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_gencpp.dir/build.make create mode 100644 Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_gencpp.dir/cmake_clean.cmake create mode 100644 Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_gencpp.dir/progress.make create mode 100644 Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages.dir/DependInfo.cmake create mode 100644 Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages.dir/build.make create mode 100644 Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages.dir/cmake_clean.cmake create mode 100644 Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages.dir/depend.internal create mode 100644 Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages.dir/depend.make create mode 100644 Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages.dir/progress.make create mode 100644 Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_cpp.dir/DependInfo.cmake create mode 100644 Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_cpp.dir/build.make create mode 100644 Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_cpp.dir/cmake_clean.cmake create mode 100644 Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_cpp.dir/depend.internal create mode 100644 Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_cpp.dir/depend.make create mode 100644 Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_cpp.dir/progress.make create mode 100644 Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_lisp.dir/DependInfo.cmake create mode 100644 Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_lisp.dir/build.make create mode 100644 Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_lisp.dir/cmake_clean.cmake create mode 100644 Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_lisp.dir/depend.internal create mode 100644 Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_lisp.dir/depend.make create mode 100644 Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_lisp.dir/progress.make create mode 100644 Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_py.dir/DependInfo.cmake create mode 100644 Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_py.dir/build.make create mode 100644 Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_py.dir/cmake_clean.cmake create mode 100644 Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_py.dir/depend.internal create mode 100644 Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_py.dir/depend.make create mode 100644 Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_py.dir/progress.make create mode 100644 Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_genlisp.dir/DependInfo.cmake create mode 100644 Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_genlisp.dir/build.make create mode 100644 Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_genlisp.dir/cmake_clean.cmake create mode 100644 Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_genlisp.dir/progress.make create mode 100644 Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_genpy.dir/DependInfo.cmake create mode 100644 Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_genpy.dir/build.make create mode 100644 Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_genpy.dir/cmake_clean.cmake create mode 100644 Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_genpy.dir/progress.make create mode 100644 Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/std_msgs_generate_messages_cpp.dir/DependInfo.cmake create mode 100644 Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/std_msgs_generate_messages_cpp.dir/build.make create mode 100644 Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/std_msgs_generate_messages_cpp.dir/cmake_clean.cmake create mode 100644 Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/std_msgs_generate_messages_cpp.dir/depend.internal create mode 100644 Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/std_msgs_generate_messages_cpp.dir/depend.make create mode 100644 Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/std_msgs_generate_messages_cpp.dir/progress.make create mode 100644 Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/std_msgs_generate_messages_lisp.dir/DependInfo.cmake create mode 100644 Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/std_msgs_generate_messages_lisp.dir/build.make create mode 100644 Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/std_msgs_generate_messages_lisp.dir/cmake_clean.cmake create mode 100644 Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/std_msgs_generate_messages_lisp.dir/depend.internal create mode 100644 Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/std_msgs_generate_messages_lisp.dir/depend.make create mode 100644 Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/std_msgs_generate_messages_lisp.dir/progress.make create mode 100644 Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/std_msgs_generate_messages_py.dir/DependInfo.cmake create mode 100644 Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/std_msgs_generate_messages_py.dir/build.make create mode 100644 Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/std_msgs_generate_messages_py.dir/cmake_clean.cmake create mode 100644 Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/std_msgs_generate_messages_py.dir/depend.internal create mode 100644 Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/std_msgs_generate_messages_py.dir/depend.make create mode 100644 Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/std_msgs_generate_messages_py.dir/progress.make create mode 100644 Legacy/ws_linux/build/rosaria_msgs/CTestTestfile.cmake create mode 100644 Legacy/ws_linux/build/rosaria_msgs/Makefile create mode 100644 Legacy/ws_linux/build/rosaria_msgs/catkin_generated/installspace/rosaria_msgs-msg-extras.cmake create mode 100644 Legacy/ws_linux/build/rosaria_msgs/catkin_generated/installspace/rosaria_msgs-msg-paths-context.py create mode 100644 Legacy/ws_linux/build/rosaria_msgs/catkin_generated/installspace/rosaria_msgs-msg-paths.cmake create mode 100644 Legacy/ws_linux/build/rosaria_msgs/catkin_generated/installspace/rosaria_msgs.pc create mode 100644 Legacy/ws_linux/build/rosaria_msgs/catkin_generated/installspace/rosaria_msgsConfig-version.cmake create mode 100644 Legacy/ws_linux/build/rosaria_msgs/catkin_generated/installspace/rosaria_msgsConfig.cmake create mode 100644 Legacy/ws_linux/build/rosaria_msgs/catkin_generated/ordered_paths.cmake create mode 100644 Legacy/ws_linux/build/rosaria_msgs/catkin_generated/package.cmake create mode 100644 Legacy/ws_linux/build/rosaria_msgs/catkin_generated/pkg.develspace.context.pc.py create mode 100644 Legacy/ws_linux/build/rosaria_msgs/catkin_generated/pkg.installspace.context.pc.py create mode 100644 Legacy/ws_linux/build/rosaria_msgs/catkin_generated/rosaria_msgs-msg-extras.cmake.develspace.in create mode 100644 Legacy/ws_linux/build/rosaria_msgs/catkin_generated/rosaria_msgs-msg-extras.cmake.installspace.in create mode 100644 Legacy/ws_linux/build/rosaria_msgs/catkin_generated/rosaria_msgs-msg-paths-context.py create mode 100644 Legacy/ws_linux/build/rosaria_msgs/catkin_generated/stamps/rosaria_msgs/package.xml.stamp create mode 100644 Legacy/ws_linux/build/rosaria_msgs/catkin_generated/stamps/rosaria_msgs/pkg-genmsg.cmake.em.stamp create mode 100644 Legacy/ws_linux/build/rosaria_msgs/catkin_generated/stamps/rosaria_msgs/pkg-msg-paths.cmake.em.stamp create mode 100644 Legacy/ws_linux/build/rosaria_msgs/catkin_generated/stamps/rosaria_msgs/pkg.pc.em.stamp create mode 100644 Legacy/ws_linux/build/rosaria_msgs/cmake/rosaria_msgs-genmsg-context.py create mode 100644 Legacy/ws_linux/build/rosaria_msgs/cmake/rosaria_msgs-genmsg.cmake create mode 100644 Legacy/ws_linux/build/rosaria_msgs/cmake_install.cmake create mode 100644 Legacy/ws_linux/build/safety/CMakeFiles/CMakeDirectoryInformation.cmake create mode 100644 Legacy/ws_linux/build/safety/CMakeFiles/cloud_reader.dir/CXX.includecache create mode 100644 Legacy/ws_linux/build/safety/CMakeFiles/cloud_reader.dir/DependInfo.cmake create mode 100644 Legacy/ws_linux/build/safety/CMakeFiles/cloud_reader.dir/build.make create mode 100644 Legacy/ws_linux/build/safety/CMakeFiles/cloud_reader.dir/cmake_clean.cmake create mode 100644 Legacy/ws_linux/build/safety/CMakeFiles/cloud_reader.dir/depend.internal create mode 100644 Legacy/ws_linux/build/safety/CMakeFiles/cloud_reader.dir/depend.make create mode 100644 Legacy/ws_linux/build/safety/CMakeFiles/cloud_reader.dir/flags.make create mode 100644 Legacy/ws_linux/build/safety/CMakeFiles/cloud_reader.dir/link.txt create mode 100644 Legacy/ws_linux/build/safety/CMakeFiles/cloud_reader.dir/progress.make create mode 100644 Legacy/ws_linux/build/safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o create mode 100644 Legacy/ws_linux/build/safety/CMakeFiles/progress.marks create mode 100644 Legacy/ws_linux/build/safety/CMakeFiles/safety_gencpp.dir/DependInfo.cmake create mode 100644 Legacy/ws_linux/build/safety/CMakeFiles/safety_gencpp.dir/build.make create mode 100644 Legacy/ws_linux/build/safety/CMakeFiles/safety_gencpp.dir/cmake_clean.cmake create mode 100644 Legacy/ws_linux/build/safety/CMakeFiles/safety_gencpp.dir/progress.make create mode 100644 Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages.dir/DependInfo.cmake create mode 100644 Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages.dir/build.make create mode 100644 Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages.dir/cmake_clean.cmake create mode 100644 Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages.dir/depend.internal create mode 100644 Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages.dir/depend.make create mode 100644 Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages.dir/progress.make create mode 100644 Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages_cpp.dir/DependInfo.cmake create mode 100644 Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages_cpp.dir/build.make create mode 100644 Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages_cpp.dir/cmake_clean.cmake create mode 100644 Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages_cpp.dir/depend.internal create mode 100644 Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages_cpp.dir/depend.make create mode 100644 Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages_cpp.dir/progress.make create mode 100644 Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages_lisp.dir/DependInfo.cmake create mode 100644 Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages_lisp.dir/build.make create mode 100644 Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages_lisp.dir/cmake_clean.cmake create mode 100644 Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages_lisp.dir/depend.internal create mode 100644 Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages_lisp.dir/depend.make create mode 100644 Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages_lisp.dir/progress.make create mode 100644 Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages_py.dir/DependInfo.cmake create mode 100644 Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages_py.dir/build.make create mode 100644 Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages_py.dir/cmake_clean.cmake create mode 100644 Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages_py.dir/depend.internal create mode 100644 Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages_py.dir/depend.make create mode 100644 Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages_py.dir/progress.make create mode 100644 Legacy/ws_linux/build/safety/CMakeFiles/safety_genlisp.dir/DependInfo.cmake create mode 100644 Legacy/ws_linux/build/safety/CMakeFiles/safety_genlisp.dir/build.make create mode 100644 Legacy/ws_linux/build/safety/CMakeFiles/safety_genlisp.dir/cmake_clean.cmake create mode 100644 Legacy/ws_linux/build/safety/CMakeFiles/safety_genlisp.dir/progress.make create mode 100644 Legacy/ws_linux/build/safety/CMakeFiles/safety_genpy.dir/DependInfo.cmake create mode 100644 Legacy/ws_linux/build/safety/CMakeFiles/safety_genpy.dir/build.make create mode 100644 Legacy/ws_linux/build/safety/CMakeFiles/safety_genpy.dir/cmake_clean.cmake create mode 100644 Legacy/ws_linux/build/safety/CMakeFiles/safety_genpy.dir/progress.make create mode 100644 Legacy/ws_linux/build/safety/CTestTestfile.cmake create mode 100644 Legacy/ws_linux/build/safety/Makefile create mode 100644 Legacy/ws_linux/build/safety/catkin_generated/installspace/safety-msg-extras.cmake create mode 100644 Legacy/ws_linux/build/safety/catkin_generated/installspace/safety-msg-paths-context.py create mode 100644 Legacy/ws_linux/build/safety/catkin_generated/installspace/safety-msg-paths.cmake create mode 100644 Legacy/ws_linux/build/safety/catkin_generated/installspace/safety.pc create mode 100644 Legacy/ws_linux/build/safety/catkin_generated/installspace/safetyConfig-version.cmake create mode 100644 Legacy/ws_linux/build/safety/catkin_generated/installspace/safetyConfig.cmake create mode 100644 Legacy/ws_linux/build/safety/catkin_generated/ordered_paths.cmake create mode 100644 Legacy/ws_linux/build/safety/catkin_generated/package.cmake create mode 100644 Legacy/ws_linux/build/safety/catkin_generated/pkg.develspace.context.pc.py create mode 100644 Legacy/ws_linux/build/safety/catkin_generated/pkg.installspace.context.pc.py create mode 100644 Legacy/ws_linux/build/safety/catkin_generated/safety-msg-extras.cmake.develspace.in create mode 100644 Legacy/ws_linux/build/safety/catkin_generated/safety-msg-extras.cmake.installspace.in create mode 100644 Legacy/ws_linux/build/safety/catkin_generated/safety-msg-paths-context.py create mode 100644 Legacy/ws_linux/build/safety/catkin_generated/stamps/safety/package.xml.stamp create mode 100644 Legacy/ws_linux/build/safety/catkin_generated/stamps/safety/pkg-genmsg.cmake.em.stamp create mode 100644 Legacy/ws_linux/build/safety/catkin_generated/stamps/safety/pkg-msg-paths.cmake.em.stamp create mode 100644 Legacy/ws_linux/build/safety/catkin_generated/stamps/safety/pkg.pc.em.stamp create mode 100644 Legacy/ws_linux/build/safety/cmake/safety-genmsg-context.py create mode 100644 Legacy/ws_linux/build/safety/cmake/safety-genmsg.cmake create mode 100644 Legacy/ws_linux/build/safety/cmake_install.cmake create mode 100644 Legacy/ws_linux/build/videostream/CMakeFiles/CMakeDirectoryInformation.cmake create mode 100644 Legacy/ws_linux/build/videostream/CMakeFiles/progress.marks create mode 100644 Legacy/ws_linux/build/videostream/CMakeFiles/videostream.dir/CXX.includecache create mode 100644 Legacy/ws_linux/build/videostream/CMakeFiles/videostream.dir/DependInfo.cmake create mode 100644 Legacy/ws_linux/build/videostream/CMakeFiles/videostream.dir/build.make create mode 100644 Legacy/ws_linux/build/videostream/CMakeFiles/videostream.dir/cmake_clean.cmake create mode 100644 Legacy/ws_linux/build/videostream/CMakeFiles/videostream.dir/depend.internal create mode 100644 Legacy/ws_linux/build/videostream/CMakeFiles/videostream.dir/depend.make create mode 100644 Legacy/ws_linux/build/videostream/CMakeFiles/videostream.dir/flags.make create mode 100644 Legacy/ws_linux/build/videostream/CMakeFiles/videostream.dir/link.txt create mode 100644 Legacy/ws_linux/build/videostream/CMakeFiles/videostream.dir/progress.make create mode 100644 Legacy/ws_linux/build/videostream/CMakeFiles/videostream.dir/src/videostream.cpp.o create mode 100644 Legacy/ws_linux/build/videostream/CMakeFiles/videostream_gencpp.dir/DependInfo.cmake create mode 100644 Legacy/ws_linux/build/videostream/CMakeFiles/videostream_gencpp.dir/build.make create mode 100644 Legacy/ws_linux/build/videostream/CMakeFiles/videostream_gencpp.dir/cmake_clean.cmake create mode 100644 Legacy/ws_linux/build/videostream/CMakeFiles/videostream_gencpp.dir/progress.make create mode 100644 Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages.dir/DependInfo.cmake create mode 100644 Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages.dir/build.make create mode 100644 Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages.dir/cmake_clean.cmake create mode 100644 Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages.dir/depend.internal create mode 100644 Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages.dir/depend.make create mode 100644 Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages.dir/progress.make create mode 100644 Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages_cpp.dir/DependInfo.cmake create mode 100644 Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages_cpp.dir/build.make create mode 100644 Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages_cpp.dir/cmake_clean.cmake create mode 100644 Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages_cpp.dir/depend.internal create mode 100644 Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages_cpp.dir/depend.make create mode 100644 Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages_cpp.dir/progress.make create mode 100644 Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages_lisp.dir/DependInfo.cmake create mode 100644 Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages_lisp.dir/build.make create mode 100644 Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages_lisp.dir/cmake_clean.cmake create mode 100644 Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages_lisp.dir/depend.internal create mode 100644 Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages_lisp.dir/depend.make create mode 100644 Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages_lisp.dir/progress.make create mode 100644 Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages_py.dir/DependInfo.cmake create mode 100644 Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages_py.dir/build.make create mode 100644 Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages_py.dir/cmake_clean.cmake create mode 100644 Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages_py.dir/depend.internal create mode 100644 Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages_py.dir/depend.make create mode 100644 Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages_py.dir/progress.make create mode 100644 Legacy/ws_linux/build/videostream/CMakeFiles/videostream_genlisp.dir/DependInfo.cmake create mode 100644 Legacy/ws_linux/build/videostream/CMakeFiles/videostream_genlisp.dir/build.make create mode 100644 Legacy/ws_linux/build/videostream/CMakeFiles/videostream_genlisp.dir/cmake_clean.cmake create mode 100644 Legacy/ws_linux/build/videostream/CMakeFiles/videostream_genlisp.dir/progress.make create mode 100644 Legacy/ws_linux/build/videostream/CMakeFiles/videostream_genpy.dir/DependInfo.cmake create mode 100644 Legacy/ws_linux/build/videostream/CMakeFiles/videostream_genpy.dir/build.make create mode 100644 Legacy/ws_linux/build/videostream/CMakeFiles/videostream_genpy.dir/cmake_clean.cmake create mode 100644 Legacy/ws_linux/build/videostream/CMakeFiles/videostream_genpy.dir/progress.make create mode 100644 Legacy/ws_linux/build/videostream/CTestTestfile.cmake create mode 100644 Legacy/ws_linux/build/videostream/Makefile create mode 100644 Legacy/ws_linux/build/videostream/catkin_generated/installspace/videostream-msg-extras.cmake create mode 100644 Legacy/ws_linux/build/videostream/catkin_generated/installspace/videostream-msg-paths-context.py create mode 100644 Legacy/ws_linux/build/videostream/catkin_generated/installspace/videostream-msg-paths.cmake create mode 100644 Legacy/ws_linux/build/videostream/catkin_generated/installspace/videostream.pc create mode 100644 Legacy/ws_linux/build/videostream/catkin_generated/installspace/videostreamConfig-version.cmake create mode 100644 Legacy/ws_linux/build/videostream/catkin_generated/installspace/videostreamConfig.cmake create mode 100644 Legacy/ws_linux/build/videostream/catkin_generated/ordered_paths.cmake create mode 100644 Legacy/ws_linux/build/videostream/catkin_generated/package.cmake create mode 100644 Legacy/ws_linux/build/videostream/catkin_generated/pkg.develspace.context.pc.py create mode 100644 Legacy/ws_linux/build/videostream/catkin_generated/pkg.installspace.context.pc.py create mode 100644 Legacy/ws_linux/build/videostream/catkin_generated/stamps/videostream/package.xml.stamp create mode 100644 Legacy/ws_linux/build/videostream/catkin_generated/stamps/videostream/pkg-genmsg.cmake.em.stamp create mode 100644 Legacy/ws_linux/build/videostream/catkin_generated/stamps/videostream/pkg-msg-paths.cmake.em.stamp create mode 100644 Legacy/ws_linux/build/videostream/catkin_generated/stamps/videostream/pkg.pc.em.stamp create mode 100644 Legacy/ws_linux/build/videostream/catkin_generated/videostream-msg-extras.cmake.develspace.in create mode 100644 Legacy/ws_linux/build/videostream/catkin_generated/videostream-msg-extras.cmake.installspace.in create mode 100644 Legacy/ws_linux/build/videostream/catkin_generated/videostream-msg-paths-context.py create mode 100644 Legacy/ws_linux/build/videostream/cmake/videostream-genmsg-context.py create mode 100644 Legacy/ws_linux/build/videostream/cmake/videostream-genmsg.cmake create mode 100644 Legacy/ws_linux/build/videostream/cmake_install.cmake create mode 100644 Legacy/ws_linux/devel/.catkin create mode 100644 Legacy/ws_linux/devel/.rosinstall create mode 100755 Legacy/ws_linux/devel/_setup_util.py create mode 100755 Legacy/ws_linux/devel/env.sh create mode 100644 Legacy/ws_linux/devel/etc/catkin/profile.d/05.catkin-test-results.sh create mode 100644 Legacy/ws_linux/devel/etc/catkin/profile.d/05.catkin_make.bash create mode 100644 Legacy/ws_linux/devel/etc/catkin/profile.d/05.catkin_make_isolated.bash create mode 100644 Legacy/ws_linux/devel/include/rosaria/BumperState.h create mode 100644 Legacy/ws_linux/devel/include/rosaria/RosAriaConfig.h create mode 100644 Legacy/ws_linux/devel/include/rosaria_msgs/RestrictionsMsg.h create mode 100644 Legacy/ws_linux/devel/include/rosaria_msgs/RobotInfoMsg.h create mode 100644 Legacy/ws_linux/devel/include/videostream/ip_get.h create mode 100644 Legacy/ws_linux/devel/include/videostream/ip_getRequest.h create mode 100644 Legacy/ws_linux/devel/include/videostream/ip_getResponse.h create mode 100644 Legacy/ws_linux/devel/lib/pkgconfig/rosaria.pc create mode 100644 Legacy/ws_linux/devel/lib/pkgconfig/rosaria_msgs.pc create mode 100644 Legacy/ws_linux/devel/lib/pkgconfig/safety.pc create mode 100644 Legacy/ws_linux/devel/lib/pkgconfig/videostream.pc create mode 100644 Legacy/ws_linux/devel/lib/python2.7/dist-packages/rosaria/__init__.py create mode 100644 Legacy/ws_linux/devel/lib/python2.7/dist-packages/rosaria/cfg/RosAriaConfig.py create mode 100644 Legacy/ws_linux/devel/lib/python2.7/dist-packages/rosaria/cfg/__init__.py create mode 100644 Legacy/ws_linux/devel/lib/python2.7/dist-packages/rosaria/msg/_BumperState.py create mode 100644 Legacy/ws_linux/devel/lib/python2.7/dist-packages/rosaria/msg/__init__.py create mode 100644 Legacy/ws_linux/devel/lib/python2.7/dist-packages/rosaria_msgs/__init__.py create mode 100644 Legacy/ws_linux/devel/lib/python2.7/dist-packages/rosaria_msgs/__init__.pyc create mode 100644 Legacy/ws_linux/devel/lib/python2.7/dist-packages/rosaria_msgs/msg/_RestrictionsMsg.py create mode 100644 Legacy/ws_linux/devel/lib/python2.7/dist-packages/rosaria_msgs/msg/_RestrictionsMsg.pyc create mode 100644 Legacy/ws_linux/devel/lib/python2.7/dist-packages/rosaria_msgs/msg/_RobotInfoMsg.py create mode 100644 Legacy/ws_linux/devel/lib/python2.7/dist-packages/rosaria_msgs/msg/_RobotInfoMsg.pyc create mode 100644 Legacy/ws_linux/devel/lib/python2.7/dist-packages/rosaria_msgs/msg/__init__.py create mode 100644 Legacy/ws_linux/devel/lib/python2.7/dist-packages/rosaria_msgs/msg/__init__.pyc create mode 100644 Legacy/ws_linux/devel/lib/python2.7/dist-packages/safety/__init__.py create mode 100644 Legacy/ws_linux/devel/lib/python2.7/dist-packages/videostream/__init__.py create mode 100644 Legacy/ws_linux/devel/lib/python2.7/dist-packages/videostream/srv/__init__.py create mode 100644 Legacy/ws_linux/devel/lib/python2.7/dist-packages/videostream/srv/_ip_get.py create mode 100755 Legacy/ws_linux/devel/lib/rosaria/RosAria create mode 100755 Legacy/ws_linux/devel/lib/safety/cloud_reader create mode 100755 Legacy/ws_linux/devel/lib/videostream/videostream create mode 100644 Legacy/ws_linux/devel/setup.bash create mode 100644 Legacy/ws_linux/devel/setup.sh create mode 100644 Legacy/ws_linux/devel/setup.zsh create mode 100644 Legacy/ws_linux/devel/share/common-lisp/ros/rosaria/msg/BumperState.lisp create mode 100644 Legacy/ws_linux/devel/share/common-lisp/ros/rosaria/msg/_package.lisp create mode 100644 Legacy/ws_linux/devel/share/common-lisp/ros/rosaria/msg/_package_BumperState.lisp create mode 100644 Legacy/ws_linux/devel/share/common-lisp/ros/rosaria/msg/rosaria-msg.asd create mode 100644 Legacy/ws_linux/devel/share/common-lisp/ros/rosaria_msgs/msg/RestrictionsMsg.lisp create mode 100644 Legacy/ws_linux/devel/share/common-lisp/ros/rosaria_msgs/msg/RobotInfoMsg.lisp create mode 100644 Legacy/ws_linux/devel/share/common-lisp/ros/rosaria_msgs/msg/_package.lisp create mode 100644 Legacy/ws_linux/devel/share/common-lisp/ros/rosaria_msgs/msg/_package_RestrictionsMsg.lisp create mode 100644 Legacy/ws_linux/devel/share/common-lisp/ros/rosaria_msgs/msg/_package_RobotInfoMsg.lisp create mode 100644 Legacy/ws_linux/devel/share/common-lisp/ros/rosaria_msgs/msg/rosaria_msgs-msg.asd create mode 100644 Legacy/ws_linux/devel/share/common-lisp/ros/videostream/srv/_package.lisp create mode 100644 Legacy/ws_linux/devel/share/common-lisp/ros/videostream/srv/_package_ip_get.lisp create mode 100644 Legacy/ws_linux/devel/share/common-lisp/ros/videostream/srv/ip_get.lisp create mode 100644 Legacy/ws_linux/devel/share/common-lisp/ros/videostream/srv/videostream-srv.asd create mode 100644 Legacy/ws_linux/devel/share/rosaria/cmake/rosaria-msg-extras.cmake create mode 100644 Legacy/ws_linux/devel/share/rosaria/cmake/rosaria-msg-paths.cmake create mode 100644 Legacy/ws_linux/devel/share/rosaria/cmake/rosariaConfig-version.cmake create mode 100644 Legacy/ws_linux/devel/share/rosaria/cmake/rosariaConfig.cmake create mode 100644 Legacy/ws_linux/devel/share/rosaria/docs/RosAriaConfig-usage.dox create mode 100644 Legacy/ws_linux/devel/share/rosaria/docs/RosAriaConfig.dox create mode 100644 Legacy/ws_linux/devel/share/rosaria/docs/RosAriaConfig.wikidoc create mode 100644 Legacy/ws_linux/devel/share/rosaria_msgs/cmake/rosaria_msgs-msg-extras.cmake create mode 100644 Legacy/ws_linux/devel/share/rosaria_msgs/cmake/rosaria_msgs-msg-paths.cmake create mode 100644 Legacy/ws_linux/devel/share/rosaria_msgs/cmake/rosaria_msgsConfig-version.cmake create mode 100644 Legacy/ws_linux/devel/share/rosaria_msgs/cmake/rosaria_msgsConfig.cmake create mode 100644 Legacy/ws_linux/devel/share/safety/cmake/safety-msg-extras.cmake create mode 100644 Legacy/ws_linux/devel/share/safety/cmake/safety-msg-paths.cmake create mode 100644 Legacy/ws_linux/devel/share/safety/cmake/safetyConfig-version.cmake create mode 100644 Legacy/ws_linux/devel/share/safety/cmake/safetyConfig.cmake create mode 100644 Legacy/ws_linux/devel/share/videostream/cmake/videostream-msg-extras.cmake create mode 100644 Legacy/ws_linux/devel/share/videostream/cmake/videostream-msg-paths.cmake create mode 100644 Legacy/ws_linux/devel/share/videostream/cmake/videostreamConfig-version.cmake create mode 100644 Legacy/ws_linux/devel/share/videostream/cmake/videostreamConfig.cmake create mode 100644 Legacy/ws_linux/src/CMakeLists.txt create mode 100644 Legacy/ws_linux/src/rosaria/.RosAria.cpp.swp rename CMakeLists.txt => Legacy/ws_linux/src/rosaria/CMakeLists.txt (100%) rename RosAria.cpp => Legacy/ws_linux/src/rosaria/RosAria.cpp (99%) create mode 100644 Legacy/ws_linux/src/rosaria/RosAria.cpp.old create mode 100644 Legacy/ws_linux/src/rosaria/RosAria.cpp.old.save rename {cfg => Legacy/ws_linux/src/rosaria/cfg}/RosAria.cfg (100%) rename libaria.rdmanifest => Legacy/ws_linux/src/rosaria/libaria.rdmanifest (100%) rename mainpage.dox => Legacy/ws_linux/src/rosaria/mainpage.dox (100%) rename {msg => Legacy/ws_linux/src/rosaria/msg}/BumperState.msg (100%) create mode 100644 Legacy/ws_linux/src/rosaria/package.xml create mode 100644 Legacy/ws_linux/src/rosaria_msgs/CMakeLists.txt create mode 100644 Legacy/ws_linux/src/rosaria_msgs/msg/RestrictionsMsg.msg create mode 100644 Legacy/ws_linux/src/rosaria_msgs/msg/RobotInfoMsg.msg create mode 100644 Legacy/ws_linux/src/rosaria_msgs/package.xml create mode 100644 Legacy/ws_linux/src/safety/.gitignore create mode 100644 Legacy/ws_linux/src/safety/CMakeLists.txt create mode 100644 Legacy/ws_linux/src/safety/README.txt create mode 100644 Legacy/ws_linux/src/safety/gnu_licence.txt create mode 100644 Legacy/ws_linux/src/safety/package.xml create mode 100644 Legacy/ws_linux/src/safety/src/cloud_reader.cpp create mode 100644 Legacy/ws_linux/src/videostream/.gitignore create mode 100644 Legacy/ws_linux/src/videostream/CMakeLists.txt create mode 100644 Legacy/ws_linux/src/videostream/include/Videostream.h create mode 100644 Legacy/ws_linux/src/videostream/package.xml create mode 100644 Legacy/ws_linux/src/videostream/src/videostream.cpp create mode 100644 Legacy/ws_linux/src/videostream/srv/ip_get.srv delete mode 100755 ros.desktop delete mode 100755 run.sh diff --git a/Legacy/Aria/ArNetworking/ArNetworking-Reference.html b/Legacy/Aria/ArNetworking/ArNetworking-Reference.html new file mode 100644 index 0000000..dc35573 --- /dev/null +++ b/Legacy/Aria/ArNetworking/ArNetworking-Reference.html @@ -0,0 +1,16 @@ + + +ArNetworking Documentation + + + +

ArNetworking Index

+
+
+
+
+
(If the ArNetworking index isn't loaded automatically,
please click +the above hyperlink,
or locate the index.html page in +docs/.)
+ + diff --git a/Legacy/Aria/ArNetworking/CommandLineOptions.txt b/Legacy/Aria/ArNetworking/CommandLineOptions.txt new file mode 100644 index 0000000..d8d4a76 --- /dev/null +++ b/Legacy/Aria/ArNetworking/CommandLineOptions.txt @@ -0,0 +1,68 @@ + +ArNetworking 2.8.0 + +Summary of command line options + +Some classes in ARIA and ArNetworking check a program's run time options to +specify parameters and options. These options are used to configure run time +accessory device parameters (ports, speeds, etc.) used by ARIA; host names, +port numbers, etc. used by ArNetworking; and various other run time options. +Options may be given as program arguments on the command line, or globally +saved as defaults in the file /etc/Aria.args if on Linux, or in the ARIAARGS +environment variable. Arguments given on the command line may override some +internal defaults or values read from the robot parameter files. + +Note, an option will be available only in programs that instantiate an +object of the class that uses it. Some programs may also check for +program-specific command line options. + +Use the special "-help" command line option to cause a program to +print out its available options. + +A list of options used by each class follows. + + +ArClientSimpleConnector +----------------------- +Options for ArClientSimpleConnector (see docs for more details): +-host +-port +-p +-user +-u +-password +-pwd +-nopassword +-np +-logDataList +-ldl + +ArServerSimpleOpener +-------------------- +Options for ArServerSimpleOpener: +-serverPort +-sp +-serverIP +-sip +-serverTcpOnly +-userInfo +-ui +-logUserInfo +-lui +-logCommandGroups +-lcg +-serverInfoFile + + +ArClientSwitchManager +--------------------- +ArClientSwitchManager options: +-centralServer +-cs +-centralServerPort +-csp +-identifier +-id +-centralServerInfoFile + + diff --git a/Legacy/Aria/ArNetworking/CommandLineOptions.txt.in b/Legacy/Aria/ArNetworking/CommandLineOptions.txt.in new file mode 100644 index 0000000..c0d33fa --- /dev/null +++ b/Legacy/Aria/ArNetworking/CommandLineOptions.txt.in @@ -0,0 +1,68 @@ + +ArNetworking @ARIA_VERSION@ + +Summary of command line options + +Some classes in ARIA and ArNetworking check a program's run time options to +specify parameters and options. These options are used to configure run time +accessory device parameters (ports, speeds, etc.) used by ARIA; host names, +port numbers, etc. used by ArNetworking; and various other run time options. +Options may be given as program arguments on the command line, or globally +saved as defaults in the file /etc/Aria.args if on Linux, or in the ARIAARGS +environment variable. Arguments given on the command line may override some +internal defaults or values read from the robot parameter files. + +Note, an option will be available only in programs that instantiate an +object of the class that uses it. Some programs may also check for +program-specific command line options. + +Use the special "-help" command line option to cause a program to +print out its available options. + +A list of options used by each class follows. + + +ArClientSimpleConnector +----------------------- +Options for ArClientSimpleConnector (see docs for more details): +-host +-port +-p +-user +-u +-password +-pwd +-nopassword +-np +-logDataList +-ldl + +ArServerSimpleOpener +-------------------- +Options for ArServerSimpleOpener: +-serverPort +-sp +-serverIP +-sip +-serverTcpOnly +-userInfo +-ui +-logUserInfo +-lui +-logCommandGroups +-lcg +-serverInfoFile + + +ArClientSwitchManager +--------------------- +ArClientSwitchManager options: +-centralServer +-cs +-centralServerPort +-csp +-identifier +-id +-centralServerInfoFile + + diff --git a/Legacy/Aria/ArNetworking/Makefile b/Legacy/Aria/ArNetworking/Makefile new file mode 100644 index 0000000..5b44d50 --- /dev/null +++ b/Legacy/Aria/ArNetworking/Makefile @@ -0,0 +1,260 @@ +CFILEEXT:=cpp +# Make sure we're using a compiler (we probably don't need to define +# it but we have been so here it is unless it was already set) +ifndef CXX +CXX=g++ +endif +BARECXXFLAGS:=-fPIC -g -Wall -D_REENTRANT #-pg -fprofile-arcs +CXXFLAGS+=$(BARECXXFLAGS) -fno-exceptions +CXXINC:=-I../include -Iinclude +CXXLINK:=-L../lib -lAria -lArNetworking -lpthread -ldl -lrt \ + -Xlinker -Bstatic -lstdc++ -Xlinker -Bdynamic +CXXSTATICLINK:=-L../lib -Xlinker -Bstatic -lArNetworking -lAria -Xlinker -Bdynamic -lpthread -ldl -lrt -Xlinker -Bstatic -lstdc++ -Xlinker -Bdynamic + +ifdef JAVA_BIN +JAVAC:=$(JAVA_BIN)/javac +JAR:=$(JAVA_BIN)/jar +else +JAVAC:=javac +JAR:=jar +endif + +CFILES:= \ + ArCentralManager.cpp \ + ArCentralForwarder.cpp \ + ArClientBase.cpp \ + ArClientData.cpp \ + ArClientHandlerConfig.cpp \ + ArClientFileUtils.cpp \ + ArClientSimpleConnector.cpp \ + ArClientSwitchManager.cpp \ + ArClientArgUtils.cpp \ + ArHybridForwarderVideo.cpp \ + ArMapChanger.cpp \ + ArNetPacket.cpp \ + ArNetPacketReceiverUdp.cpp \ + ArNetPacketReceiverTcp.cpp \ + ArNetPacketSenderTcp.cpp \ + ArServerBase.cpp \ + ArServerClient.cpp \ + ArServerData.cpp \ + ArServerFileUtils.cpp \ + ArServerHandlerCamera.cpp \ + ArServerHandlerCameraCollection.cpp \ + ArServerHandlerCommands.cpp \ + ArServerHandlerCommMonitor.cpp \ + ArServerHandlerConfig.cpp \ + ArServerHandlerMap.cpp \ + ArServerHandlerMapping.cpp \ + ArServerHandlerPopup.cpp \ + ArServerMode.cpp \ + ArServerModeDrive.cpp \ + ArServerModeIdle.cpp \ + ArServerModeRatioDrive.cpp \ + ArServerModeStop.cpp \ + ArServerModeWander.cpp \ + ArServerInfoDrawings.cpp \ + ArServerInfoRobot.cpp \ + ArServerInfoSensor.cpp \ + ArServerInfoStrings.cpp \ + ArServerSimpleCommands.cpp \ + ArServerSimpleOpener.cpp \ + ArServerUserInfo.cpp \ + ArTempDirectoryHelper.cpp \ + md5.cpp + + +OTFILES:=$(patsubst %.$(CFILEEXT),%.o,$(CFILES)) +OFILES:=$(patsubst %,../obj/%,$(OTFILES)) + +TARGETS:=../lib/libArNetworking.so examples + +EXAMPLES_CPP:=$(shell find examples -name "*.$(CFILEEXT)" | grep -v Mod.cpp) +EXAMPLES:=$(patsubst %.$(CFILEEXT),%,$(EXAMPLES_CPP)) + +TESTS_CPP:=$(shell find tests -name "*.$(CFILEEXT)" | grep -v Mod.cpp) +TESTS:=$(patsubst %.$(CFILEEXT),%,$(TESTS_CPP)) + +SRC_FILES:=$(patsubst %,src/%,$(CFILES)) +HEADER_FILES:=$(shell find include -type f -name \*.h) + +all: dirs $(TARGETS) + +dirs: + @mkdir -p -v ../obj + @mkdir -p -v ../lib + +../lib/libArNetworking.so: $(OFILES) ../lib/libAria.so Makefile.dep + @mkdir -p -v ../obj + @mkdir -p -v ../lib + $(CXX) -shared -Xlinker -Bstatic -lstdc++ -Xlinker -Bdynamic -o $(@) $(OFILES) + +../lib/libArNetworking.a: $(OFILES) ../lib/libAria.a Makefile.dep + @mkdir -p -v ../obj + @mkdir -p -v ../lib + ar -cr $(@) $(OFILES) + ranlib $(@) + + +examples: dirs $(EXAMPLES) Makefile.dep + + +tests: dirs $(TESTS) Makefile.dep + +clean: cleanExamples + rm -f ../lib/libArNetworking.so ../lib/libArNetworking.a \ + `find . -name core` $(OFILES) `find . -name '*~'` + +cleanPython: + -rm ../python/_ArNetworkingPy.so + -rm ../python/ArNetworkingPy.py + -rm ../python/ArNetworkingPy.pyc + -rm ../python/ArNetworkingPy_wrap.cpp + -rm ../obj/ArNetworkingPy_wrap.o + +cleanExamples: + rm -f $(EXAMPLES) + +cleanDoc: + -rm -f docs/*.html docs/*.png docs/*.png + -rm -rf docs/tmp + +fullClean: clean cleanExamples cleanJava cleanPython cleanDoc + +docs: doc +doc: docs/index.html +docs/index.html: $(SRC_FILES) $(HEADER_FILES) $(EXAMPLES_CPP) doxygen.conf docs/options/all_options.dox ../docs/index.html + $(MAKE) cleanDoc + -mkdir docs + doxygen doxygen.conf + +../docs/index.html: FORCE + $(MAKE) -C .. docs/index.html + +#doxygen.conf: FORCE +# $(MAKE) -C .. ArNetworking/$@ +# +#CommandLineOptions.txt: FORCE +# $(MAKE) -C .. ArNetworking/$@ + +Makefile.dep: + $(MAKE) dep + +dep: clean + if [ -f `echo src/*.cpp | cut -d' ' -f1` ]; then \ + $(CXX) $(CXXFLAGS) $(CXXINC) -MM src/*.cpp | \ + awk '$$1 ~ /:/{printf "../obj/%s\n", $$0} $$1 !~ /:/' > Makefile.dep; fi + if [ -f `echo examples/*.cpp | cut -d' ' -f1` ]; then \ + $(CXX) $(CXXFLAGS) $(CXXINC) -MM examples/*.cpp | \ + awk '$$1 ~ /:/{printf "examples/%s\n", $$0} $$1 !~ /:/' | \ + sed 's/\.o//' >> Makefile.dep; fi + +../lib/libAria.so: FORCE + $(MAKE) -C .. dirs lib/libAria.so + +../lib/libAria.a: FORCE + $(MAKE) -C .. dirs lib/libAria.a + +../obj/%.o : src/%.cpp Makefile.dep + $(CXX) $(CXXFLAGS) $(CXXINC) -c $< -o $@ + +../obj/%.o : src/%.c Makefile.dep + $(CXX) $(CXXFLAGS) $(CXXINC) -c $< -o $@ + +# Don't build .o files if their library is up to date with respect to source files: +.INTERMEDIATE: $(OFILES) + +# But don't delete .o files if we do make them in order to make a library: +.PRECIOUS: $(OFILES) + +examples/%: examples/%.$(CFILEEXT) ../lib/libAria.so ../lib/libArNetworking.so Makefile.dep + $(CXX) $(CXXFLAGS) $(CXXINC) $< -o $@ $(CXXLINK) + +tests/%: tests/%.$(CFILEEXT) ../lib/libAria.so ../lib/libArNetworking.so Makefile.dep + $(CXX) $(CXXFLAGS) $(CXXINC) $< -o $@ $(CXXLINK) + + +examples/%Static: examples/%.$(CFILEEXT) ../lib/libAria.a ../lib/libArNetworking.a Makefile.dep + $(CXX) $(CXXFLAGS) $(CXXINC) $< -o $@ $(CXXSTATICLINK) + strip $@ + +tests/%Static: tests/%.$(CFILEEXT) ../lib/libAria.a ../lib/libArNetworking.a Makefile.dep + $(CXX) $(CXXFLAGS) $(CXXINC) $< -o $@ $(CXXSTATICLINK) + strip $@ + +CommandLineOptions.txt.in docs/options/all_options.dox: genCommandLineOptionDocs + -mkdir docs/options + ./genCommandLineOptionDocs + +genCommandLineOptionDocs: ../utils/genCommandLineOptionDocs.cpp ../lib/libAria.so ../lib/libArNetworking.so src/ArServerSimpleOpener.cpp src/ArClientSimpleConnector.cpp src/ArClientSwitchManager.cpp + $(CXX) $(CXXFLAGS) -DFOR_ARNETWORKING $(CXXINC) $< -o $@ $(CXXLINK) + +## Python SWIG wrapper ## + +ifdef PYTHON_INCLUDE +PYTHON_INCLUDE_FLAGS=-I$(PYTHON_INCLUDE) +else +ifdef DIST_INSTALL +$(warning WARNING using default value of /usr/include/python2.5 for PYTHON_INCLUDE directory. Set PYTHON_INCLUDE environment variable if you would like to use a different version of the Python C development library to build the Python ARIA wrapper.) +endif +PYTHON_INCLUDE:=/usr/include/python2.5 +PYTHON_INCLUDE_FLAGS=-I/usr/include/python2.5 +endif + +python: ariaPython ../python/_ArNetworkingPy.so + +ariaPython: + $(MAKE) -C .. python + +../python/ArNetworkingPy_wrap.cpp ../python/ArNetworkingPy.py: include/wrapper.i $(HEADER_FILES) + cd ../python; swig -c++ -python -module ArNetworkingPy -Dlinux -DAREXPORT -o ArNetworkingPy_wrap.cpp -I../include -I../ArNetworking/include ../ArNetworking/include/wrapper.i + +../python/_ArNetworkingPy.so: ../obj/ArNetworkingPy_wrap.o ../lib/libArNetworking.so Makefile.dep + $(CXX) $(BARECXXFLAGS) -shared -o $(@) ../obj/ArNetworkingPy_wrap.o -lpthread -ldl -lrt \ + -L../lib -lAria -lArNetworking + +../obj/ArNetworkingPy_wrap.o: ../python/ArNetworkingPy_wrap.cpp + @ if test -z "$(PYTHON_INCLUDE)"; then echo "*** Error: PYTHON_INCLUDE is not set, cannot build ArNetworking python wrapper! ***"; exit 1; fi + $(CXX) -c $(BARECXXFLAGS) -g $(CXXINC) -I$(PYTHON_INCLUDE) $< -o $@ + + +## Java SWIG wrapper ## + + +java: ../lib/libArNetworkingJava.so ../java/ArNetworking.jar + +../java/Aria.jar: + $(MAKE) -C .. java + +../java/ArNetworking.jar: ../java/com/mobilerobots/ArNetworking/ArServerBase.class + cd ../java ; $(JAR) cf ArNetworking.jar com/mobilerobots/ArNetworking/*.class + +../java/ArNetworkingJava_wrap.cpp ../java/com/mobilerobots/ArNetworking/ArServerBase.java: include/wrapper.i $(HEADER_FILES) + -mkdir -p ../java/com/mobilerobots/ArNetworking + rm ../java/com/mobilerobots/ArNetworking/*.java ../java/ArNetworkingJava_wrap.cpp ../java/ArNetworkingJava_wrap.h ; swig -c++ -java -package com.mobilerobots.ArNetworking -outdir ../java/com/mobilerobots/ArNetworking -module ArNetworkingJava -Dlinux -DAREXPORT -o ../java/ArNetworkingJava_wrap.cpp -I../include -Iinclude include/wrapper.i + +../java/com/mobilerobots/ArNetworking/ArServerBase.class: ../java/com/mobilerobots/ArNetworking/ArServerBase.java ../java/Aria.jar + rm ../java/com/mobilerobots/ArNetworking/*.class; $(JAVAC) -classpath ../java/Aria.jar:../java ../java/com/mobilerobots/ArNetworking/*.java + +cleanJava: + -rm ../java/ArNetworking.jar + -rm -r ../java/com/mobilerobots/ArNetworking + -rm ../java/ArNetworkingJava_wrap.* ../obj/ArNetworkingJava_wrap.o ../lib/libArNetworkingJava.so + +../lib/libArNetworkingJava.so: ../obj/ArNetworkingJava_wrap.o Makefile.dep ../lib/libArNetworking.so + $(CXX) $(BARECXXFLAGS) -shared -o $(@) ../obj/ArNetworkingJava_wrap.o -lpthread -ldl -lrt -L../lib -lAria -lArNetworking + +../obj/ArNetworkingJava_wrap.o: ../java/ArNetworkingJava_wrap.cpp + @ if test -z "$(JAVA_INCLUDE)"; then echo "*** Error: JAVA_INCLUDE is not set, building ArNetworkingPy_wrap.cpp will probably fail! ***"; fi + $(CXX) -c $(BARECXXFLAGS) $(CXXINC) -I$(JAVA_INCLUDE) -I$(JAVA_INCLUDE)/linux $< -o $@ + +FORCE: + +# Just see if there is a Makefile.dep, if so include one... there +# should be one because of the rules up in the command line parsing +# part above +ifeq (Makefile.dep,$(wildcard Makefile.dep)) +include Makefile.dep +# End of the Makefile.dep check +endif + diff --git a/Legacy/Aria/ArNetworking/Makefile.dep b/Legacy/Aria/ArNetworking/Makefile.dep new file mode 100644 index 0000000..223a7cd --- /dev/null +++ b/Legacy/Aria/ArNetworking/Makefile.dep @@ -0,0 +1,4845 @@ +../obj/ArCentralForwarder.o: src/ArCentralForwarder.cpp ../include/Aria.h \ + ../include/ariaOSDef.h ../include/ariaTypedefs.h \ + ../include/ArSerialConnection.h ../include/ArDeviceConnection.h \ + ../include/ariaUtil.h ../include/ArLog.h ../include/ArMutex.h \ + ../include/ArFunctor.h ../include/ArArgumentParser.h \ + ../include/ArArgumentBuilder.h ../include/ArBasePacket.h \ + ../include/ArTcpConnection.h ../include/ArSocket.h \ + ../include/ArSimpleConnector.h ../include/ArRobotConnector.h \ + ../include/ArLaserConnector.h ../include/ArLogFileConnection.h \ + ../include/ArRobotPacket.h ../include/ArRobotPacketSender.h \ + ../include/ArRobotPacketReceiver.h \ + ../include/ArRobotConfigPacketReader.h ../include/ArRobotTypes.h \ + ../include/ArRobotParams.h ../include/ArConfig.h \ + ../include/ArConfigArg.h ../include/ArFileParser.h \ + ../include/ArHasFileName.h ../include/ArConfigGroup.h \ + ../include/ArRobot.h ../include/ArSyncTask.h ../include/ArTaskState.h \ + ../include/ArSensorReading.h ../include/ArTransform.h \ + ../include/ArCondition.h ../include/ArSyncLoop.h \ + ../include/ArASyncTask.h ../include/ArThread.h \ + ../include/ArRobotPacketReaderThread.h ../include/ArActionDesired.h \ + ../include/ArResolver.h ../include/ArInterpolation.h \ + ../include/ArKeyHandler.h ../include/ArCommands.h \ + ../include/ArJoyHandler.h ../include/ariaInternal.h \ + ../include/ArStringInfoGroup.h ../include/ArSonarDevice.h \ + ../include/ArRangeDevice.h ../include/ArRangeBuffer.h \ + ../include/ArDrawingData.h ../include/ArPriorityResolver.h \ + ../include/ArAction.h ../include/ArArg.h ../include/ArActionGroup.h \ + ../include/ArActionGroups.h ../include/ArActionColorFollow.h \ + ../include/ArACTS.h ../include/ArPTZ.h ../include/ArPTZConnector.h \ + ../include/ArActionDeceleratingLimiter.h \ + ../include/ArActionLimiterForwards.h \ + ../include/ArActionLimiterBackwards.h \ + ../include/ArActionLimiterTableSensor.h ../include/ArActionBumpers.h \ + ../include/ArActionIRs.h ../include/ArActionStallRecover.h \ + ../include/ArActionAvoidFront.h ../include/ArActionAvoidSide.h \ + ../include/ArActionConstantVelocity.h ../include/ArActionInput.h \ + ../include/ArActionRobotJoydrive.h ../include/ArActionJoydrive.h \ + ../include/ArActionKeydrive.h ../include/ArActionTriangleDriveTo.h \ + ../include/ArLineFinder.h ../include/ArActionTurn.h \ + ../include/ArActionRatioInput.h ../include/ArActionStop.h \ + ../include/ArActionGoto.h ../include/ArModule.h \ + ../include/ArModuleLoader.h ../include/ArRecurrentTask.h \ + ../include/ArGripper.h ../include/ArSonyPTZ.h ../include/ArRVisionPTZ.h \ + ../include/ArAMPTU.h ../include/ArP2Arm.h ../include/ArSick.h \ + ../include/ArLaser.h ../include/ArRangeDeviceThreaded.h \ + ../include/ArFunctorASyncTask.h ../include/ArLMS2xx.h \ + ../include/ArLMS2xxPacket.h ../include/ArLMS2xxPacketReceiver.h \ + ../include/ArLaserLogger.h ../include/ArIrrfDevice.h \ + ../include/ArDPPTU.h ../include/ArVCC4.h ../include/ArMode.h \ + ../include/ArModes.h ../include/ArTCMCompassRobot.h ../include/ArTCM2.h \ + ../include/ArNetServer.h ../include/ArSignalHandler.h \ + ../include/ArAnalogGyro.h ../include/ArMapInterface.h \ + ../include/ArMapObject.h ../include/ArMapUtils.h ../include/ArMap.h \ + ../include/ArMapComponents.h ../include/ArBumpers.h ../include/ArIRs.h \ + ../include/ArForbiddenRangeDevice.h ../include/ArVersalogicIO.h \ + ../include/ArMTXIO.h ../include/ArActionGotoStraight.h \ + ../include/ArDataLogger.h ../include/ArRobotJoyHandler.h \ + ../include/ArRatioInputKeydrive.h ../include/ArRatioInputJoydrive.h \ + ../include/ArRatioInputRobotJoydrive.h \ + ../include/ArActionMovementParameters.h ../include/ArSoundPlayer.h \ + ../include/ArSoundsQueue.h ../include/ArSpeech.h \ + ../include/ArCameraCollection.h ../include/ArCameraCommands.h \ + ../include/ArSonarAutoDisabler.h ../include/ArActionDriveDistance.h \ + ../include/ArLaserReflectorDevice.h ../include/ArRobotConfig.h \ + ../include/ArTCMCompassDirect.h ../include/ArNMEAParser.h \ + ../include/ArLaserFilter.h ../include/ArUrg.h ../include/ArGPS.h \ + ../include/ArTrimbleGPS.h ../include/ArNovatelGPS.h \ + ../include/ArGPSCoords.h ../include/ArSonarConnector.h \ + ../include/ArBatteryConnector.h ../include/ArLCDConnector.h \ + ../include/ArSonarMTX.h ../include/ArBatteryMTX.h ../include/ArLCDMTX.h \ + ../include/ArSimulatedLaser.h ../include/ArExitErrorSource.h \ + ../include/ArActionLimiterRot.h ../include/ArRobotBatteryPacketReader.h \ + ../include/ArLMS1XX.h ../include/ArUrg_2_0.h \ + ../include/ArActionMovementParametersDebugging.h ../include/ArZippable.h \ + ../include/ArS3Series.h ../include/ArSZSeries.h ../include/ArExport.h \ + include/ArCentralForwarder.h include/ArServerBase.h \ + include/ArServerCommands.h include/ArServerClient.h \ + include/ArNetPacket.h include/ArNetPacketReceiverTcp.h \ + include/ArNetPacketSenderTcp.h include/ArServerClientData.h \ + include/ArServerClientIdentifier.h include/ArServerData.h \ + include/ArNetPacketReceiverUdp.h include/ArServerUserInfo.h \ + include/ArClientBase.h include/ArClientCommands.h include/ArClientData.h +../obj/ArCentralManager.o: src/ArCentralManager.cpp ../include/Aria.h \ + ../include/ariaOSDef.h ../include/ariaTypedefs.h \ + ../include/ArSerialConnection.h ../include/ArDeviceConnection.h \ + ../include/ariaUtil.h ../include/ArLog.h ../include/ArMutex.h \ + ../include/ArFunctor.h ../include/ArArgumentParser.h \ + ../include/ArArgumentBuilder.h ../include/ArBasePacket.h \ + ../include/ArTcpConnection.h ../include/ArSocket.h \ + ../include/ArSimpleConnector.h ../include/ArRobotConnector.h \ + ../include/ArLaserConnector.h ../include/ArLogFileConnection.h \ + ../include/ArRobotPacket.h ../include/ArRobotPacketSender.h \ + ../include/ArRobotPacketReceiver.h \ + ../include/ArRobotConfigPacketReader.h ../include/ArRobotTypes.h \ + ../include/ArRobotParams.h ../include/ArConfig.h \ + ../include/ArConfigArg.h ../include/ArFileParser.h \ + ../include/ArHasFileName.h ../include/ArConfigGroup.h \ + ../include/ArRobot.h ../include/ArSyncTask.h ../include/ArTaskState.h \ + ../include/ArSensorReading.h ../include/ArTransform.h \ + ../include/ArCondition.h ../include/ArSyncLoop.h \ + ../include/ArASyncTask.h ../include/ArThread.h \ + ../include/ArRobotPacketReaderThread.h ../include/ArActionDesired.h \ + ../include/ArResolver.h ../include/ArInterpolation.h \ + ../include/ArKeyHandler.h ../include/ArCommands.h \ + ../include/ArJoyHandler.h ../include/ariaInternal.h \ + ../include/ArStringInfoGroup.h ../include/ArSonarDevice.h \ + ../include/ArRangeDevice.h ../include/ArRangeBuffer.h \ + ../include/ArDrawingData.h ../include/ArPriorityResolver.h \ + ../include/ArAction.h ../include/ArArg.h ../include/ArActionGroup.h \ + ../include/ArActionGroups.h ../include/ArActionColorFollow.h \ + ../include/ArACTS.h ../include/ArPTZ.h ../include/ArPTZConnector.h \ + ../include/ArActionDeceleratingLimiter.h \ + ../include/ArActionLimiterForwards.h \ + ../include/ArActionLimiterBackwards.h \ + ../include/ArActionLimiterTableSensor.h ../include/ArActionBumpers.h \ + ../include/ArActionIRs.h ../include/ArActionStallRecover.h \ + ../include/ArActionAvoidFront.h ../include/ArActionAvoidSide.h \ + ../include/ArActionConstantVelocity.h ../include/ArActionInput.h \ + ../include/ArActionRobotJoydrive.h ../include/ArActionJoydrive.h \ + ../include/ArActionKeydrive.h ../include/ArActionTriangleDriveTo.h \ + ../include/ArLineFinder.h ../include/ArActionTurn.h \ + ../include/ArActionRatioInput.h ../include/ArActionStop.h \ + ../include/ArActionGoto.h ../include/ArModule.h \ + ../include/ArModuleLoader.h ../include/ArRecurrentTask.h \ + ../include/ArGripper.h ../include/ArSonyPTZ.h ../include/ArRVisionPTZ.h \ + ../include/ArAMPTU.h ../include/ArP2Arm.h ../include/ArSick.h \ + ../include/ArLaser.h ../include/ArRangeDeviceThreaded.h \ + ../include/ArFunctorASyncTask.h ../include/ArLMS2xx.h \ + ../include/ArLMS2xxPacket.h ../include/ArLMS2xxPacketReceiver.h \ + ../include/ArLaserLogger.h ../include/ArIrrfDevice.h \ + ../include/ArDPPTU.h ../include/ArVCC4.h ../include/ArMode.h \ + ../include/ArModes.h ../include/ArTCMCompassRobot.h ../include/ArTCM2.h \ + ../include/ArNetServer.h ../include/ArSignalHandler.h \ + ../include/ArAnalogGyro.h ../include/ArMapInterface.h \ + ../include/ArMapObject.h ../include/ArMapUtils.h ../include/ArMap.h \ + ../include/ArMapComponents.h ../include/ArBumpers.h ../include/ArIRs.h \ + ../include/ArForbiddenRangeDevice.h ../include/ArVersalogicIO.h \ + ../include/ArMTXIO.h ../include/ArActionGotoStraight.h \ + ../include/ArDataLogger.h ../include/ArRobotJoyHandler.h \ + ../include/ArRatioInputKeydrive.h ../include/ArRatioInputJoydrive.h \ + ../include/ArRatioInputRobotJoydrive.h \ + ../include/ArActionMovementParameters.h ../include/ArSoundPlayer.h \ + ../include/ArSoundsQueue.h ../include/ArSpeech.h \ + ../include/ArCameraCollection.h ../include/ArCameraCommands.h \ + ../include/ArSonarAutoDisabler.h ../include/ArActionDriveDistance.h \ + ../include/ArLaserReflectorDevice.h ../include/ArRobotConfig.h \ + ../include/ArTCMCompassDirect.h ../include/ArNMEAParser.h \ + ../include/ArLaserFilter.h ../include/ArUrg.h ../include/ArGPS.h \ + ../include/ArTrimbleGPS.h ../include/ArNovatelGPS.h \ + ../include/ArGPSCoords.h ../include/ArSonarConnector.h \ + ../include/ArBatteryConnector.h ../include/ArLCDConnector.h \ + ../include/ArSonarMTX.h ../include/ArBatteryMTX.h ../include/ArLCDMTX.h \ + ../include/ArSimulatedLaser.h ../include/ArExitErrorSource.h \ + ../include/ArActionLimiterRot.h ../include/ArRobotBatteryPacketReader.h \ + ../include/ArLMS1XX.h ../include/ArUrg_2_0.h \ + ../include/ArActionMovementParametersDebugging.h ../include/ArZippable.h \ + ../include/ArS3Series.h ../include/ArSZSeries.h ../include/ArExport.h \ + include/ArCentralManager.h include/ArServerBase.h \ + include/ArServerCommands.h include/ArServerClient.h \ + include/ArNetPacket.h include/ArNetPacketReceiverTcp.h \ + include/ArNetPacketSenderTcp.h include/ArServerClientData.h \ + include/ArServerClientIdentifier.h include/ArServerData.h \ + include/ArNetPacketReceiverUdp.h include/ArServerUserInfo.h \ + include/ArCentralForwarder.h include/ArClientBase.h \ + include/ArClientCommands.h include/ArClientData.h +../obj/ArClientArgUtils.o: src/ArClientArgUtils.cpp ../include/Aria.h \ + ../include/ariaOSDef.h ../include/ariaTypedefs.h \ + ../include/ArSerialConnection.h ../include/ArDeviceConnection.h \ + ../include/ariaUtil.h ../include/ArLog.h ../include/ArMutex.h \ + ../include/ArFunctor.h ../include/ArArgumentParser.h \ + ../include/ArArgumentBuilder.h ../include/ArBasePacket.h \ + ../include/ArTcpConnection.h ../include/ArSocket.h \ + ../include/ArSimpleConnector.h ../include/ArRobotConnector.h \ + ../include/ArLaserConnector.h ../include/ArLogFileConnection.h \ + ../include/ArRobotPacket.h ../include/ArRobotPacketSender.h \ + ../include/ArRobotPacketReceiver.h \ + ../include/ArRobotConfigPacketReader.h ../include/ArRobotTypes.h \ + ../include/ArRobotParams.h ../include/ArConfig.h \ + ../include/ArConfigArg.h ../include/ArFileParser.h \ + ../include/ArHasFileName.h ../include/ArConfigGroup.h \ + ../include/ArRobot.h ../include/ArSyncTask.h ../include/ArTaskState.h \ + ../include/ArSensorReading.h ../include/ArTransform.h \ + ../include/ArCondition.h ../include/ArSyncLoop.h \ + ../include/ArASyncTask.h ../include/ArThread.h \ + ../include/ArRobotPacketReaderThread.h ../include/ArActionDesired.h \ + ../include/ArResolver.h ../include/ArInterpolation.h \ + ../include/ArKeyHandler.h ../include/ArCommands.h \ + ../include/ArJoyHandler.h ../include/ariaInternal.h \ + ../include/ArStringInfoGroup.h ../include/ArSonarDevice.h \ + ../include/ArRangeDevice.h ../include/ArRangeBuffer.h \ + ../include/ArDrawingData.h ../include/ArPriorityResolver.h \ + ../include/ArAction.h ../include/ArArg.h ../include/ArActionGroup.h \ + ../include/ArActionGroups.h ../include/ArActionColorFollow.h \ + ../include/ArACTS.h ../include/ArPTZ.h ../include/ArPTZConnector.h \ + ../include/ArActionDeceleratingLimiter.h \ + ../include/ArActionLimiterForwards.h \ + ../include/ArActionLimiterBackwards.h \ + ../include/ArActionLimiterTableSensor.h ../include/ArActionBumpers.h \ + ../include/ArActionIRs.h ../include/ArActionStallRecover.h \ + ../include/ArActionAvoidFront.h ../include/ArActionAvoidSide.h \ + ../include/ArActionConstantVelocity.h ../include/ArActionInput.h \ + ../include/ArActionRobotJoydrive.h ../include/ArActionJoydrive.h \ + ../include/ArActionKeydrive.h ../include/ArActionTriangleDriveTo.h \ + ../include/ArLineFinder.h ../include/ArActionTurn.h \ + ../include/ArActionRatioInput.h ../include/ArActionStop.h \ + ../include/ArActionGoto.h ../include/ArModule.h \ + ../include/ArModuleLoader.h ../include/ArRecurrentTask.h \ + ../include/ArGripper.h ../include/ArSonyPTZ.h ../include/ArRVisionPTZ.h \ + ../include/ArAMPTU.h ../include/ArP2Arm.h ../include/ArSick.h \ + ../include/ArLaser.h ../include/ArRangeDeviceThreaded.h \ + ../include/ArFunctorASyncTask.h ../include/ArLMS2xx.h \ + ../include/ArLMS2xxPacket.h ../include/ArLMS2xxPacketReceiver.h \ + ../include/ArLaserLogger.h ../include/ArIrrfDevice.h \ + ../include/ArDPPTU.h ../include/ArVCC4.h ../include/ArMode.h \ + ../include/ArModes.h ../include/ArTCMCompassRobot.h ../include/ArTCM2.h \ + ../include/ArNetServer.h ../include/ArSignalHandler.h \ + ../include/ArAnalogGyro.h ../include/ArMapInterface.h \ + ../include/ArMapObject.h ../include/ArMapUtils.h ../include/ArMap.h \ + ../include/ArMapComponents.h ../include/ArBumpers.h ../include/ArIRs.h \ + ../include/ArForbiddenRangeDevice.h ../include/ArVersalogicIO.h \ + ../include/ArMTXIO.h ../include/ArActionGotoStraight.h \ + ../include/ArDataLogger.h ../include/ArRobotJoyHandler.h \ + ../include/ArRatioInputKeydrive.h ../include/ArRatioInputJoydrive.h \ + ../include/ArRatioInputRobotJoydrive.h \ + ../include/ArActionMovementParameters.h ../include/ArSoundPlayer.h \ + ../include/ArSoundsQueue.h ../include/ArSpeech.h \ + ../include/ArCameraCollection.h ../include/ArCameraCommands.h \ + ../include/ArSonarAutoDisabler.h ../include/ArActionDriveDistance.h \ + ../include/ArLaserReflectorDevice.h ../include/ArRobotConfig.h \ + ../include/ArTCMCompassDirect.h ../include/ArNMEAParser.h \ + ../include/ArLaserFilter.h ../include/ArUrg.h ../include/ArGPS.h \ + ../include/ArTrimbleGPS.h ../include/ArNovatelGPS.h \ + ../include/ArGPSCoords.h ../include/ArSonarConnector.h \ + ../include/ArBatteryConnector.h ../include/ArLCDConnector.h \ + ../include/ArSonarMTX.h ../include/ArBatteryMTX.h ../include/ArLCDMTX.h \ + ../include/ArSimulatedLaser.h ../include/ArExitErrorSource.h \ + ../include/ArActionLimiterRot.h ../include/ArRobotBatteryPacketReader.h \ + ../include/ArLMS1XX.h ../include/ArUrg_2_0.h \ + ../include/ArActionMovementParametersDebugging.h ../include/ArZippable.h \ + ../include/ArS3Series.h ../include/ArSZSeries.h ../include/ArExport.h \ + include/ArClientArgUtils.h ../include/ArConfigArg.h \ + include/ArNetPacket.h +../obj/ArClientBase.o: src/ArClientBase.cpp ../include/Aria.h \ + ../include/ariaOSDef.h ../include/ariaTypedefs.h \ + ../include/ArSerialConnection.h ../include/ArDeviceConnection.h \ + ../include/ariaUtil.h ../include/ArLog.h ../include/ArMutex.h \ + ../include/ArFunctor.h ../include/ArArgumentParser.h \ + ../include/ArArgumentBuilder.h ../include/ArBasePacket.h \ + ../include/ArTcpConnection.h ../include/ArSocket.h \ + ../include/ArSimpleConnector.h ../include/ArRobotConnector.h \ + ../include/ArLaserConnector.h ../include/ArLogFileConnection.h \ + ../include/ArRobotPacket.h ../include/ArRobotPacketSender.h \ + ../include/ArRobotPacketReceiver.h \ + ../include/ArRobotConfigPacketReader.h ../include/ArRobotTypes.h \ + ../include/ArRobotParams.h ../include/ArConfig.h \ + ../include/ArConfigArg.h ../include/ArFileParser.h \ + ../include/ArHasFileName.h ../include/ArConfigGroup.h \ + ../include/ArRobot.h ../include/ArSyncTask.h ../include/ArTaskState.h \ + ../include/ArSensorReading.h ../include/ArTransform.h \ + ../include/ArCondition.h ../include/ArSyncLoop.h \ + ../include/ArASyncTask.h ../include/ArThread.h \ + ../include/ArRobotPacketReaderThread.h ../include/ArActionDesired.h \ + ../include/ArResolver.h ../include/ArInterpolation.h \ + ../include/ArKeyHandler.h ../include/ArCommands.h \ + ../include/ArJoyHandler.h ../include/ariaInternal.h \ + ../include/ArStringInfoGroup.h ../include/ArSonarDevice.h \ + ../include/ArRangeDevice.h ../include/ArRangeBuffer.h \ + ../include/ArDrawingData.h ../include/ArPriorityResolver.h \ + ../include/ArAction.h ../include/ArArg.h ../include/ArActionGroup.h \ + ../include/ArActionGroups.h ../include/ArActionColorFollow.h \ + ../include/ArACTS.h ../include/ArPTZ.h ../include/ArPTZConnector.h \ + ../include/ArActionDeceleratingLimiter.h \ + ../include/ArActionLimiterForwards.h \ + ../include/ArActionLimiterBackwards.h \ + ../include/ArActionLimiterTableSensor.h ../include/ArActionBumpers.h \ + ../include/ArActionIRs.h ../include/ArActionStallRecover.h \ + ../include/ArActionAvoidFront.h ../include/ArActionAvoidSide.h \ + ../include/ArActionConstantVelocity.h ../include/ArActionInput.h \ + ../include/ArActionRobotJoydrive.h ../include/ArActionJoydrive.h \ + ../include/ArActionKeydrive.h ../include/ArActionTriangleDriveTo.h \ + ../include/ArLineFinder.h ../include/ArActionTurn.h \ + ../include/ArActionRatioInput.h ../include/ArActionStop.h \ + ../include/ArActionGoto.h ../include/ArModule.h \ + ../include/ArModuleLoader.h ../include/ArRecurrentTask.h \ + ../include/ArGripper.h ../include/ArSonyPTZ.h ../include/ArRVisionPTZ.h \ + ../include/ArAMPTU.h ../include/ArP2Arm.h ../include/ArSick.h \ + ../include/ArLaser.h ../include/ArRangeDeviceThreaded.h \ + ../include/ArFunctorASyncTask.h ../include/ArLMS2xx.h \ + ../include/ArLMS2xxPacket.h ../include/ArLMS2xxPacketReceiver.h \ + ../include/ArLaserLogger.h ../include/ArIrrfDevice.h \ + ../include/ArDPPTU.h ../include/ArVCC4.h ../include/ArMode.h \ + ../include/ArModes.h ../include/ArTCMCompassRobot.h ../include/ArTCM2.h \ + ../include/ArNetServer.h ../include/ArSignalHandler.h \ + ../include/ArAnalogGyro.h ../include/ArMapInterface.h \ + ../include/ArMapObject.h ../include/ArMapUtils.h ../include/ArMap.h \ + ../include/ArMapComponents.h ../include/ArBumpers.h ../include/ArIRs.h \ + ../include/ArForbiddenRangeDevice.h ../include/ArVersalogicIO.h \ + ../include/ArMTXIO.h ../include/ArActionGotoStraight.h \ + ../include/ArDataLogger.h ../include/ArRobotJoyHandler.h \ + ../include/ArRatioInputKeydrive.h ../include/ArRatioInputJoydrive.h \ + ../include/ArRatioInputRobotJoydrive.h \ + ../include/ArActionMovementParameters.h ../include/ArSoundPlayer.h \ + ../include/ArSoundsQueue.h ../include/ArSpeech.h \ + ../include/ArCameraCollection.h ../include/ArCameraCommands.h \ + ../include/ArSonarAutoDisabler.h ../include/ArActionDriveDistance.h \ + ../include/ArLaserReflectorDevice.h ../include/ArRobotConfig.h \ + ../include/ArTCMCompassDirect.h ../include/ArNMEAParser.h \ + ../include/ArLaserFilter.h ../include/ArUrg.h ../include/ArGPS.h \ + ../include/ArTrimbleGPS.h ../include/ArNovatelGPS.h \ + ../include/ArGPSCoords.h ../include/ArSonarConnector.h \ + ../include/ArBatteryConnector.h ../include/ArLCDConnector.h \ + ../include/ArSonarMTX.h ../include/ArBatteryMTX.h ../include/ArLCDMTX.h \ + ../include/ArSimulatedLaser.h ../include/ArExitErrorSource.h \ + ../include/ArActionLimiterRot.h ../include/ArRobotBatteryPacketReader.h \ + ../include/ArLMS1XX.h ../include/ArUrg_2_0.h \ + ../include/ArActionMovementParametersDebugging.h ../include/ArZippable.h \ + ../include/ArS3Series.h ../include/ArSZSeries.h ../include/ArExport.h \ + include/ArClientBase.h include/ArClientCommands.h \ + include/ArServerCommands.h include/ArNetPacket.h \ + include/ArNetPacketSenderTcp.h include/ArNetPacketReceiverTcp.h \ + include/ArNetPacketReceiverUdp.h include/ArClientData.h \ + include/ArServerCommands.h include/ArClientCommands.h ../include/md5.h +../obj/ArClientData.o: src/ArClientData.cpp ../include/Aria.h \ + ../include/ariaOSDef.h ../include/ariaTypedefs.h \ + ../include/ArSerialConnection.h ../include/ArDeviceConnection.h \ + ../include/ariaUtil.h ../include/ArLog.h ../include/ArMutex.h \ + ../include/ArFunctor.h ../include/ArArgumentParser.h \ + ../include/ArArgumentBuilder.h ../include/ArBasePacket.h \ + ../include/ArTcpConnection.h ../include/ArSocket.h \ + ../include/ArSimpleConnector.h ../include/ArRobotConnector.h \ + ../include/ArLaserConnector.h ../include/ArLogFileConnection.h \ + ../include/ArRobotPacket.h ../include/ArRobotPacketSender.h \ + ../include/ArRobotPacketReceiver.h \ + ../include/ArRobotConfigPacketReader.h ../include/ArRobotTypes.h \ + ../include/ArRobotParams.h ../include/ArConfig.h \ + ../include/ArConfigArg.h ../include/ArFileParser.h \ + ../include/ArHasFileName.h ../include/ArConfigGroup.h \ + ../include/ArRobot.h ../include/ArSyncTask.h ../include/ArTaskState.h \ + ../include/ArSensorReading.h ../include/ArTransform.h \ + ../include/ArCondition.h ../include/ArSyncLoop.h \ + ../include/ArASyncTask.h ../include/ArThread.h \ + ../include/ArRobotPacketReaderThread.h ../include/ArActionDesired.h \ + ../include/ArResolver.h ../include/ArInterpolation.h \ + ../include/ArKeyHandler.h ../include/ArCommands.h \ + ../include/ArJoyHandler.h ../include/ariaInternal.h \ + ../include/ArStringInfoGroup.h ../include/ArSonarDevice.h \ + ../include/ArRangeDevice.h ../include/ArRangeBuffer.h \ + ../include/ArDrawingData.h ../include/ArPriorityResolver.h \ + ../include/ArAction.h ../include/ArArg.h ../include/ArActionGroup.h \ + ../include/ArActionGroups.h ../include/ArActionColorFollow.h \ + ../include/ArACTS.h ../include/ArPTZ.h ../include/ArPTZConnector.h \ + ../include/ArActionDeceleratingLimiter.h \ + ../include/ArActionLimiterForwards.h \ + ../include/ArActionLimiterBackwards.h \ + ../include/ArActionLimiterTableSensor.h ../include/ArActionBumpers.h \ + ../include/ArActionIRs.h ../include/ArActionStallRecover.h \ + ../include/ArActionAvoidFront.h ../include/ArActionAvoidSide.h \ + ../include/ArActionConstantVelocity.h ../include/ArActionInput.h \ + ../include/ArActionRobotJoydrive.h ../include/ArActionJoydrive.h \ + ../include/ArActionKeydrive.h ../include/ArActionTriangleDriveTo.h \ + ../include/ArLineFinder.h ../include/ArActionTurn.h \ + ../include/ArActionRatioInput.h ../include/ArActionStop.h \ + ../include/ArActionGoto.h ../include/ArModule.h \ + ../include/ArModuleLoader.h ../include/ArRecurrentTask.h \ + ../include/ArGripper.h ../include/ArSonyPTZ.h ../include/ArRVisionPTZ.h \ + ../include/ArAMPTU.h ../include/ArP2Arm.h ../include/ArSick.h \ + ../include/ArLaser.h ../include/ArRangeDeviceThreaded.h \ + ../include/ArFunctorASyncTask.h ../include/ArLMS2xx.h \ + ../include/ArLMS2xxPacket.h ../include/ArLMS2xxPacketReceiver.h \ + ../include/ArLaserLogger.h ../include/ArIrrfDevice.h \ + ../include/ArDPPTU.h ../include/ArVCC4.h ../include/ArMode.h \ + ../include/ArModes.h ../include/ArTCMCompassRobot.h ../include/ArTCM2.h \ + ../include/ArNetServer.h ../include/ArSignalHandler.h \ + ../include/ArAnalogGyro.h ../include/ArMapInterface.h \ + ../include/ArMapObject.h ../include/ArMapUtils.h ../include/ArMap.h \ + ../include/ArMapComponents.h ../include/ArBumpers.h ../include/ArIRs.h \ + ../include/ArForbiddenRangeDevice.h ../include/ArVersalogicIO.h \ + ../include/ArMTXIO.h ../include/ArActionGotoStraight.h \ + ../include/ArDataLogger.h ../include/ArRobotJoyHandler.h \ + ../include/ArRatioInputKeydrive.h ../include/ArRatioInputJoydrive.h \ + ../include/ArRatioInputRobotJoydrive.h \ + ../include/ArActionMovementParameters.h ../include/ArSoundPlayer.h \ + ../include/ArSoundsQueue.h ../include/ArSpeech.h \ + ../include/ArCameraCollection.h ../include/ArCameraCommands.h \ + ../include/ArSonarAutoDisabler.h ../include/ArActionDriveDistance.h \ + ../include/ArLaserReflectorDevice.h ../include/ArRobotConfig.h \ + ../include/ArTCMCompassDirect.h ../include/ArNMEAParser.h \ + ../include/ArLaserFilter.h ../include/ArUrg.h ../include/ArGPS.h \ + ../include/ArTrimbleGPS.h ../include/ArNovatelGPS.h \ + ../include/ArGPSCoords.h ../include/ArSonarConnector.h \ + ../include/ArBatteryConnector.h ../include/ArLCDConnector.h \ + ../include/ArSonarMTX.h ../include/ArBatteryMTX.h ../include/ArLCDMTX.h \ + ../include/ArSimulatedLaser.h ../include/ArExitErrorSource.h \ + ../include/ArActionLimiterRot.h ../include/ArRobotBatteryPacketReader.h \ + ../include/ArLMS1XX.h ../include/ArUrg_2_0.h \ + ../include/ArActionMovementParametersDebugging.h ../include/ArZippable.h \ + ../include/ArS3Series.h ../include/ArSZSeries.h ../include/ArExport.h \ + include/ArClientData.h include/ArNetPacket.h +../obj/ArClientFileUtils.o: src/ArClientFileUtils.cpp ../include/Aria.h \ + ../include/ariaOSDef.h ../include/ariaTypedefs.h \ + ../include/ArSerialConnection.h ../include/ArDeviceConnection.h \ + ../include/ariaUtil.h ../include/ArLog.h ../include/ArMutex.h \ + ../include/ArFunctor.h ../include/ArArgumentParser.h \ + ../include/ArArgumentBuilder.h ../include/ArBasePacket.h \ + ../include/ArTcpConnection.h ../include/ArSocket.h \ + ../include/ArSimpleConnector.h ../include/ArRobotConnector.h \ + ../include/ArLaserConnector.h ../include/ArLogFileConnection.h \ + ../include/ArRobotPacket.h ../include/ArRobotPacketSender.h \ + ../include/ArRobotPacketReceiver.h \ + ../include/ArRobotConfigPacketReader.h ../include/ArRobotTypes.h \ + ../include/ArRobotParams.h ../include/ArConfig.h \ + ../include/ArConfigArg.h ../include/ArFileParser.h \ + ../include/ArHasFileName.h ../include/ArConfigGroup.h \ + ../include/ArRobot.h ../include/ArSyncTask.h ../include/ArTaskState.h \ + ../include/ArSensorReading.h ../include/ArTransform.h \ + ../include/ArCondition.h ../include/ArSyncLoop.h \ + ../include/ArASyncTask.h ../include/ArThread.h \ + ../include/ArRobotPacketReaderThread.h ../include/ArActionDesired.h \ + ../include/ArResolver.h ../include/ArInterpolation.h \ + ../include/ArKeyHandler.h ../include/ArCommands.h \ + ../include/ArJoyHandler.h ../include/ariaInternal.h \ + ../include/ArStringInfoGroup.h ../include/ArSonarDevice.h \ + ../include/ArRangeDevice.h ../include/ArRangeBuffer.h \ + ../include/ArDrawingData.h ../include/ArPriorityResolver.h \ + ../include/ArAction.h ../include/ArArg.h ../include/ArActionGroup.h \ + ../include/ArActionGroups.h ../include/ArActionColorFollow.h \ + ../include/ArACTS.h ../include/ArPTZ.h ../include/ArPTZConnector.h \ + ../include/ArActionDeceleratingLimiter.h \ + ../include/ArActionLimiterForwards.h \ + ../include/ArActionLimiterBackwards.h \ + ../include/ArActionLimiterTableSensor.h ../include/ArActionBumpers.h \ + ../include/ArActionIRs.h ../include/ArActionStallRecover.h \ + ../include/ArActionAvoidFront.h ../include/ArActionAvoidSide.h \ + ../include/ArActionConstantVelocity.h ../include/ArActionInput.h \ + ../include/ArActionRobotJoydrive.h ../include/ArActionJoydrive.h \ + ../include/ArActionKeydrive.h ../include/ArActionTriangleDriveTo.h \ + ../include/ArLineFinder.h ../include/ArActionTurn.h \ + ../include/ArActionRatioInput.h ../include/ArActionStop.h \ + ../include/ArActionGoto.h ../include/ArModule.h \ + ../include/ArModuleLoader.h ../include/ArRecurrentTask.h \ + ../include/ArGripper.h ../include/ArSonyPTZ.h ../include/ArRVisionPTZ.h \ + ../include/ArAMPTU.h ../include/ArP2Arm.h ../include/ArSick.h \ + ../include/ArLaser.h ../include/ArRangeDeviceThreaded.h \ + ../include/ArFunctorASyncTask.h ../include/ArLMS2xx.h \ + ../include/ArLMS2xxPacket.h ../include/ArLMS2xxPacketReceiver.h \ + ../include/ArLaserLogger.h ../include/ArIrrfDevice.h \ + ../include/ArDPPTU.h ../include/ArVCC4.h ../include/ArMode.h \ + ../include/ArModes.h ../include/ArTCMCompassRobot.h ../include/ArTCM2.h \ + ../include/ArNetServer.h ../include/ArSignalHandler.h \ + ../include/ArAnalogGyro.h ../include/ArMapInterface.h \ + ../include/ArMapObject.h ../include/ArMapUtils.h ../include/ArMap.h \ + ../include/ArMapComponents.h ../include/ArBumpers.h ../include/ArIRs.h \ + ../include/ArForbiddenRangeDevice.h ../include/ArVersalogicIO.h \ + ../include/ArMTXIO.h ../include/ArActionGotoStraight.h \ + ../include/ArDataLogger.h ../include/ArRobotJoyHandler.h \ + ../include/ArRatioInputKeydrive.h ../include/ArRatioInputJoydrive.h \ + ../include/ArRatioInputRobotJoydrive.h \ + ../include/ArActionMovementParameters.h ../include/ArSoundPlayer.h \ + ../include/ArSoundsQueue.h ../include/ArSpeech.h \ + ../include/ArCameraCollection.h ../include/ArCameraCommands.h \ + ../include/ArSonarAutoDisabler.h ../include/ArActionDriveDistance.h \ + ../include/ArLaserReflectorDevice.h ../include/ArRobotConfig.h \ + ../include/ArTCMCompassDirect.h ../include/ArNMEAParser.h \ + ../include/ArLaserFilter.h ../include/ArUrg.h ../include/ArGPS.h \ + ../include/ArTrimbleGPS.h ../include/ArNovatelGPS.h \ + ../include/ArGPSCoords.h ../include/ArSonarConnector.h \ + ../include/ArBatteryConnector.h ../include/ArLCDConnector.h \ + ../include/ArSonarMTX.h ../include/ArBatteryMTX.h ../include/ArLCDMTX.h \ + ../include/ArSimulatedLaser.h ../include/ArExitErrorSource.h \ + ../include/ArActionLimiterRot.h ../include/ArRobotBatteryPacketReader.h \ + ../include/ArLMS1XX.h ../include/ArUrg_2_0.h \ + ../include/ArActionMovementParametersDebugging.h ../include/ArZippable.h \ + ../include/ArS3Series.h ../include/ArSZSeries.h ../include/ArExport.h \ + include/ArClientFileUtils.h include/ArClientBase.h \ + include/ArClientCommands.h include/ArServerCommands.h \ + include/ArNetPacket.h include/ArNetPacketSenderTcp.h \ + include/ArNetPacketReceiverTcp.h include/ArNetPacketReceiverUdp.h \ + include/ArClientData.h +../obj/ArClientHandlerConfig.o: src/ArClientHandlerConfig.cpp ../include/Aria.h \ + ../include/ariaOSDef.h ../include/ariaTypedefs.h \ + ../include/ArSerialConnection.h ../include/ArDeviceConnection.h \ + ../include/ariaUtil.h ../include/ArLog.h ../include/ArMutex.h \ + ../include/ArFunctor.h ../include/ArArgumentParser.h \ + ../include/ArArgumentBuilder.h ../include/ArBasePacket.h \ + ../include/ArTcpConnection.h ../include/ArSocket.h \ + ../include/ArSimpleConnector.h ../include/ArRobotConnector.h \ + ../include/ArLaserConnector.h ../include/ArLogFileConnection.h \ + ../include/ArRobotPacket.h ../include/ArRobotPacketSender.h \ + ../include/ArRobotPacketReceiver.h \ + ../include/ArRobotConfigPacketReader.h ../include/ArRobotTypes.h \ + ../include/ArRobotParams.h ../include/ArConfig.h \ + ../include/ArConfigArg.h ../include/ArFileParser.h \ + ../include/ArHasFileName.h ../include/ArConfigGroup.h \ + ../include/ArRobot.h ../include/ArSyncTask.h ../include/ArTaskState.h \ + ../include/ArSensorReading.h ../include/ArTransform.h \ + ../include/ArCondition.h ../include/ArSyncLoop.h \ + ../include/ArASyncTask.h ../include/ArThread.h \ + ../include/ArRobotPacketReaderThread.h ../include/ArActionDesired.h \ + ../include/ArResolver.h ../include/ArInterpolation.h \ + ../include/ArKeyHandler.h ../include/ArCommands.h \ + ../include/ArJoyHandler.h ../include/ariaInternal.h \ + ../include/ArStringInfoGroup.h ../include/ArSonarDevice.h \ + ../include/ArRangeDevice.h ../include/ArRangeBuffer.h \ + ../include/ArDrawingData.h ../include/ArPriorityResolver.h \ + ../include/ArAction.h ../include/ArArg.h ../include/ArActionGroup.h \ + ../include/ArActionGroups.h ../include/ArActionColorFollow.h \ + ../include/ArACTS.h ../include/ArPTZ.h ../include/ArPTZConnector.h \ + ../include/ArActionDeceleratingLimiter.h \ + ../include/ArActionLimiterForwards.h \ + ../include/ArActionLimiterBackwards.h \ + ../include/ArActionLimiterTableSensor.h ../include/ArActionBumpers.h \ + ../include/ArActionIRs.h ../include/ArActionStallRecover.h \ + ../include/ArActionAvoidFront.h ../include/ArActionAvoidSide.h \ + ../include/ArActionConstantVelocity.h ../include/ArActionInput.h \ + ../include/ArActionRobotJoydrive.h ../include/ArActionJoydrive.h \ + ../include/ArActionKeydrive.h ../include/ArActionTriangleDriveTo.h \ + ../include/ArLineFinder.h ../include/ArActionTurn.h \ + ../include/ArActionRatioInput.h ../include/ArActionStop.h \ + ../include/ArActionGoto.h ../include/ArModule.h \ + ../include/ArModuleLoader.h ../include/ArRecurrentTask.h \ + ../include/ArGripper.h ../include/ArSonyPTZ.h ../include/ArRVisionPTZ.h \ + ../include/ArAMPTU.h ../include/ArP2Arm.h ../include/ArSick.h \ + ../include/ArLaser.h ../include/ArRangeDeviceThreaded.h \ + ../include/ArFunctorASyncTask.h ../include/ArLMS2xx.h \ + ../include/ArLMS2xxPacket.h ../include/ArLMS2xxPacketReceiver.h \ + ../include/ArLaserLogger.h ../include/ArIrrfDevice.h \ + ../include/ArDPPTU.h ../include/ArVCC4.h ../include/ArMode.h \ + ../include/ArModes.h ../include/ArTCMCompassRobot.h ../include/ArTCM2.h \ + ../include/ArNetServer.h ../include/ArSignalHandler.h \ + ../include/ArAnalogGyro.h ../include/ArMapInterface.h \ + ../include/ArMapObject.h ../include/ArMapUtils.h ../include/ArMap.h \ + ../include/ArMapComponents.h ../include/ArBumpers.h ../include/ArIRs.h \ + ../include/ArForbiddenRangeDevice.h ../include/ArVersalogicIO.h \ + ../include/ArMTXIO.h ../include/ArActionGotoStraight.h \ + ../include/ArDataLogger.h ../include/ArRobotJoyHandler.h \ + ../include/ArRatioInputKeydrive.h ../include/ArRatioInputJoydrive.h \ + ../include/ArRatioInputRobotJoydrive.h \ + ../include/ArActionMovementParameters.h ../include/ArSoundPlayer.h \ + ../include/ArSoundsQueue.h ../include/ArSpeech.h \ + ../include/ArCameraCollection.h ../include/ArCameraCommands.h \ + ../include/ArSonarAutoDisabler.h ../include/ArActionDriveDistance.h \ + ../include/ArLaserReflectorDevice.h ../include/ArRobotConfig.h \ + ../include/ArTCMCompassDirect.h ../include/ArNMEAParser.h \ + ../include/ArLaserFilter.h ../include/ArUrg.h ../include/ArGPS.h \ + ../include/ArTrimbleGPS.h ../include/ArNovatelGPS.h \ + ../include/ArGPSCoords.h ../include/ArSonarConnector.h \ + ../include/ArBatteryConnector.h ../include/ArLCDConnector.h \ + ../include/ArSonarMTX.h ../include/ArBatteryMTX.h ../include/ArLCDMTX.h \ + ../include/ArSimulatedLaser.h ../include/ArExitErrorSource.h \ + ../include/ArActionLimiterRot.h ../include/ArRobotBatteryPacketReader.h \ + ../include/ArLMS1XX.h ../include/ArUrg_2_0.h \ + ../include/ArActionMovementParametersDebugging.h ../include/ArZippable.h \ + ../include/ArS3Series.h ../include/ArSZSeries.h ../include/ArExport.h \ + include/ArClientHandlerConfig.h include/ArClientBase.h \ + include/ArClientCommands.h include/ArServerCommands.h \ + include/ArNetPacket.h include/ArNetPacketSenderTcp.h \ + include/ArNetPacketReceiverTcp.h include/ArNetPacketReceiverUdp.h \ + include/ArClientData.h include/ArClientArgUtils.h +../obj/ArClientSimpleConnector.o: src/ArClientSimpleConnector.cpp \ + ../include/Aria.h ../include/ariaOSDef.h ../include/ariaTypedefs.h \ + ../include/ArSerialConnection.h ../include/ArDeviceConnection.h \ + ../include/ariaUtil.h ../include/ArLog.h ../include/ArMutex.h \ + ../include/ArFunctor.h ../include/ArArgumentParser.h \ + ../include/ArArgumentBuilder.h ../include/ArBasePacket.h \ + ../include/ArTcpConnection.h ../include/ArSocket.h \ + ../include/ArSimpleConnector.h ../include/ArRobotConnector.h \ + ../include/ArLaserConnector.h ../include/ArLogFileConnection.h \ + ../include/ArRobotPacket.h ../include/ArRobotPacketSender.h \ + ../include/ArRobotPacketReceiver.h \ + ../include/ArRobotConfigPacketReader.h ../include/ArRobotTypes.h \ + ../include/ArRobotParams.h ../include/ArConfig.h \ + ../include/ArConfigArg.h ../include/ArFileParser.h \ + ../include/ArHasFileName.h ../include/ArConfigGroup.h \ + ../include/ArRobot.h ../include/ArSyncTask.h ../include/ArTaskState.h \ + ../include/ArSensorReading.h ../include/ArTransform.h \ + ../include/ArCondition.h ../include/ArSyncLoop.h \ + ../include/ArASyncTask.h ../include/ArThread.h \ + ../include/ArRobotPacketReaderThread.h ../include/ArActionDesired.h \ + ../include/ArResolver.h ../include/ArInterpolation.h \ + ../include/ArKeyHandler.h ../include/ArCommands.h \ + ../include/ArJoyHandler.h ../include/ariaInternal.h \ + ../include/ArStringInfoGroup.h ../include/ArSonarDevice.h \ + ../include/ArRangeDevice.h ../include/ArRangeBuffer.h \ + ../include/ArDrawingData.h ../include/ArPriorityResolver.h \ + ../include/ArAction.h ../include/ArArg.h ../include/ArActionGroup.h \ + ../include/ArActionGroups.h ../include/ArActionColorFollow.h \ + ../include/ArACTS.h ../include/ArPTZ.h ../include/ArPTZConnector.h \ + ../include/ArActionDeceleratingLimiter.h \ + ../include/ArActionLimiterForwards.h \ + ../include/ArActionLimiterBackwards.h \ + ../include/ArActionLimiterTableSensor.h ../include/ArActionBumpers.h \ + ../include/ArActionIRs.h ../include/ArActionStallRecover.h \ + ../include/ArActionAvoidFront.h ../include/ArActionAvoidSide.h \ + ../include/ArActionConstantVelocity.h ../include/ArActionInput.h \ + ../include/ArActionRobotJoydrive.h ../include/ArActionJoydrive.h \ + ../include/ArActionKeydrive.h ../include/ArActionTriangleDriveTo.h \ + ../include/ArLineFinder.h ../include/ArActionTurn.h \ + ../include/ArActionRatioInput.h ../include/ArActionStop.h \ + ../include/ArActionGoto.h ../include/ArModule.h \ + ../include/ArModuleLoader.h ../include/ArRecurrentTask.h \ + ../include/ArGripper.h ../include/ArSonyPTZ.h ../include/ArRVisionPTZ.h \ + ../include/ArAMPTU.h ../include/ArP2Arm.h ../include/ArSick.h \ + ../include/ArLaser.h ../include/ArRangeDeviceThreaded.h \ + ../include/ArFunctorASyncTask.h ../include/ArLMS2xx.h \ + ../include/ArLMS2xxPacket.h ../include/ArLMS2xxPacketReceiver.h \ + ../include/ArLaserLogger.h ../include/ArIrrfDevice.h \ + ../include/ArDPPTU.h ../include/ArVCC4.h ../include/ArMode.h \ + ../include/ArModes.h ../include/ArTCMCompassRobot.h ../include/ArTCM2.h \ + ../include/ArNetServer.h ../include/ArSignalHandler.h \ + ../include/ArAnalogGyro.h ../include/ArMapInterface.h \ + ../include/ArMapObject.h ../include/ArMapUtils.h ../include/ArMap.h \ + ../include/ArMapComponents.h ../include/ArBumpers.h ../include/ArIRs.h \ + ../include/ArForbiddenRangeDevice.h ../include/ArVersalogicIO.h \ + ../include/ArMTXIO.h ../include/ArActionGotoStraight.h \ + ../include/ArDataLogger.h ../include/ArRobotJoyHandler.h \ + ../include/ArRatioInputKeydrive.h ../include/ArRatioInputJoydrive.h \ + ../include/ArRatioInputRobotJoydrive.h \ + ../include/ArActionMovementParameters.h ../include/ArSoundPlayer.h \ + ../include/ArSoundsQueue.h ../include/ArSpeech.h \ + ../include/ArCameraCollection.h ../include/ArCameraCommands.h \ + ../include/ArSonarAutoDisabler.h ../include/ArActionDriveDistance.h \ + ../include/ArLaserReflectorDevice.h ../include/ArRobotConfig.h \ + ../include/ArTCMCompassDirect.h ../include/ArNMEAParser.h \ + ../include/ArLaserFilter.h ../include/ArUrg.h ../include/ArGPS.h \ + ../include/ArTrimbleGPS.h ../include/ArNovatelGPS.h \ + ../include/ArGPSCoords.h ../include/ArSonarConnector.h \ + ../include/ArBatteryConnector.h ../include/ArLCDConnector.h \ + ../include/ArSonarMTX.h ../include/ArBatteryMTX.h ../include/ArLCDMTX.h \ + ../include/ArSimulatedLaser.h ../include/ArExitErrorSource.h \ + ../include/ArActionLimiterRot.h ../include/ArRobotBatteryPacketReader.h \ + ../include/ArLMS1XX.h ../include/ArUrg_2_0.h \ + ../include/ArActionMovementParametersDebugging.h ../include/ArZippable.h \ + ../include/ArS3Series.h ../include/ArSZSeries.h ../include/ArExport.h \ + include/ArClientSimpleConnector.h include/ArClientBase.h \ + include/ArClientCommands.h include/ArServerCommands.h \ + include/ArNetPacket.h include/ArNetPacketSenderTcp.h \ + include/ArNetPacketReceiverTcp.h include/ArNetPacketReceiverUdp.h \ + include/ArClientData.h +../obj/ArClientSwitchManager.o: src/ArClientSwitchManager.cpp ../include/Aria.h \ + ../include/ariaOSDef.h ../include/ariaTypedefs.h \ + ../include/ArSerialConnection.h ../include/ArDeviceConnection.h \ + ../include/ariaUtil.h ../include/ArLog.h ../include/ArMutex.h \ + ../include/ArFunctor.h ../include/ArArgumentParser.h \ + ../include/ArArgumentBuilder.h ../include/ArBasePacket.h \ + ../include/ArTcpConnection.h ../include/ArSocket.h \ + ../include/ArSimpleConnector.h ../include/ArRobotConnector.h \ + ../include/ArLaserConnector.h ../include/ArLogFileConnection.h \ + ../include/ArRobotPacket.h ../include/ArRobotPacketSender.h \ + ../include/ArRobotPacketReceiver.h \ + ../include/ArRobotConfigPacketReader.h ../include/ArRobotTypes.h \ + ../include/ArRobotParams.h ../include/ArConfig.h \ + ../include/ArConfigArg.h ../include/ArFileParser.h \ + ../include/ArHasFileName.h ../include/ArConfigGroup.h \ + ../include/ArRobot.h ../include/ArSyncTask.h ../include/ArTaskState.h \ + ../include/ArSensorReading.h ../include/ArTransform.h \ + ../include/ArCondition.h ../include/ArSyncLoop.h \ + ../include/ArASyncTask.h ../include/ArThread.h \ + ../include/ArRobotPacketReaderThread.h ../include/ArActionDesired.h \ + ../include/ArResolver.h ../include/ArInterpolation.h \ + ../include/ArKeyHandler.h ../include/ArCommands.h \ + ../include/ArJoyHandler.h ../include/ariaInternal.h \ + ../include/ArStringInfoGroup.h ../include/ArSonarDevice.h \ + ../include/ArRangeDevice.h ../include/ArRangeBuffer.h \ + ../include/ArDrawingData.h ../include/ArPriorityResolver.h \ + ../include/ArAction.h ../include/ArArg.h ../include/ArActionGroup.h \ + ../include/ArActionGroups.h ../include/ArActionColorFollow.h \ + ../include/ArACTS.h ../include/ArPTZ.h ../include/ArPTZConnector.h \ + ../include/ArActionDeceleratingLimiter.h \ + ../include/ArActionLimiterForwards.h \ + ../include/ArActionLimiterBackwards.h \ + ../include/ArActionLimiterTableSensor.h ../include/ArActionBumpers.h \ + ../include/ArActionIRs.h ../include/ArActionStallRecover.h \ + ../include/ArActionAvoidFront.h ../include/ArActionAvoidSide.h \ + ../include/ArActionConstantVelocity.h ../include/ArActionInput.h \ + ../include/ArActionRobotJoydrive.h ../include/ArActionJoydrive.h \ + ../include/ArActionKeydrive.h ../include/ArActionTriangleDriveTo.h \ + ../include/ArLineFinder.h ../include/ArActionTurn.h \ + ../include/ArActionRatioInput.h ../include/ArActionStop.h \ + ../include/ArActionGoto.h ../include/ArModule.h \ + ../include/ArModuleLoader.h ../include/ArRecurrentTask.h \ + ../include/ArGripper.h ../include/ArSonyPTZ.h ../include/ArRVisionPTZ.h \ + ../include/ArAMPTU.h ../include/ArP2Arm.h ../include/ArSick.h \ + ../include/ArLaser.h ../include/ArRangeDeviceThreaded.h \ + ../include/ArFunctorASyncTask.h ../include/ArLMS2xx.h \ + ../include/ArLMS2xxPacket.h ../include/ArLMS2xxPacketReceiver.h \ + ../include/ArLaserLogger.h ../include/ArIrrfDevice.h \ + ../include/ArDPPTU.h ../include/ArVCC4.h ../include/ArMode.h \ + ../include/ArModes.h ../include/ArTCMCompassRobot.h ../include/ArTCM2.h \ + ../include/ArNetServer.h ../include/ArSignalHandler.h \ + ../include/ArAnalogGyro.h ../include/ArMapInterface.h \ + ../include/ArMapObject.h ../include/ArMapUtils.h ../include/ArMap.h \ + ../include/ArMapComponents.h ../include/ArBumpers.h ../include/ArIRs.h \ + ../include/ArForbiddenRangeDevice.h ../include/ArVersalogicIO.h \ + ../include/ArMTXIO.h ../include/ArActionGotoStraight.h \ + ../include/ArDataLogger.h ../include/ArRobotJoyHandler.h \ + ../include/ArRatioInputKeydrive.h ../include/ArRatioInputJoydrive.h \ + ../include/ArRatioInputRobotJoydrive.h \ + ../include/ArActionMovementParameters.h ../include/ArSoundPlayer.h \ + ../include/ArSoundsQueue.h ../include/ArSpeech.h \ + ../include/ArCameraCollection.h ../include/ArCameraCommands.h \ + ../include/ArSonarAutoDisabler.h ../include/ArActionDriveDistance.h \ + ../include/ArLaserReflectorDevice.h ../include/ArRobotConfig.h \ + ../include/ArTCMCompassDirect.h ../include/ArNMEAParser.h \ + ../include/ArLaserFilter.h ../include/ArUrg.h ../include/ArGPS.h \ + ../include/ArTrimbleGPS.h ../include/ArNovatelGPS.h \ + ../include/ArGPSCoords.h ../include/ArSonarConnector.h \ + ../include/ArBatteryConnector.h ../include/ArLCDConnector.h \ + ../include/ArSonarMTX.h ../include/ArBatteryMTX.h ../include/ArLCDMTX.h \ + ../include/ArSimulatedLaser.h ../include/ArExitErrorSource.h \ + ../include/ArActionLimiterRot.h ../include/ArRobotBatteryPacketReader.h \ + ../include/ArLMS1XX.h ../include/ArUrg_2_0.h \ + ../include/ArActionMovementParametersDebugging.h ../include/ArZippable.h \ + ../include/ArS3Series.h ../include/ArSZSeries.h ../include/ArExport.h \ + include/ArClientSwitchManager.h include/ArServerBase.h \ + include/ArServerCommands.h include/ArServerClient.h \ + include/ArNetPacket.h include/ArNetPacketReceiverTcp.h \ + include/ArNetPacketSenderTcp.h include/ArServerClientData.h \ + include/ArServerClientIdentifier.h include/ArServerData.h \ + include/ArNetPacketReceiverUdp.h include/ArServerUserInfo.h \ + include/ArClientBase.h include/ArClientCommands.h include/ArClientData.h +../obj/ArHybridForwarderVideo.o: src/ArHybridForwarderVideo.cpp \ + ../include/Aria.h ../include/ariaOSDef.h ../include/ariaTypedefs.h \ + ../include/ArSerialConnection.h ../include/ArDeviceConnection.h \ + ../include/ariaUtil.h ../include/ArLog.h ../include/ArMutex.h \ + ../include/ArFunctor.h ../include/ArArgumentParser.h \ + ../include/ArArgumentBuilder.h ../include/ArBasePacket.h \ + ../include/ArTcpConnection.h ../include/ArSocket.h \ + ../include/ArSimpleConnector.h ../include/ArRobotConnector.h \ + ../include/ArLaserConnector.h ../include/ArLogFileConnection.h \ + ../include/ArRobotPacket.h ../include/ArRobotPacketSender.h \ + ../include/ArRobotPacketReceiver.h \ + ../include/ArRobotConfigPacketReader.h ../include/ArRobotTypes.h \ + ../include/ArRobotParams.h ../include/ArConfig.h \ + ../include/ArConfigArg.h ../include/ArFileParser.h \ + ../include/ArHasFileName.h ../include/ArConfigGroup.h \ + ../include/ArRobot.h ../include/ArSyncTask.h ../include/ArTaskState.h \ + ../include/ArSensorReading.h ../include/ArTransform.h \ + ../include/ArCondition.h ../include/ArSyncLoop.h \ + ../include/ArASyncTask.h ../include/ArThread.h \ + ../include/ArRobotPacketReaderThread.h ../include/ArActionDesired.h \ + ../include/ArResolver.h ../include/ArInterpolation.h \ + ../include/ArKeyHandler.h ../include/ArCommands.h \ + ../include/ArJoyHandler.h ../include/ariaInternal.h \ + ../include/ArStringInfoGroup.h ../include/ArSonarDevice.h \ + ../include/ArRangeDevice.h ../include/ArRangeBuffer.h \ + ../include/ArDrawingData.h ../include/ArPriorityResolver.h \ + ../include/ArAction.h ../include/ArArg.h ../include/ArActionGroup.h \ + ../include/ArActionGroups.h ../include/ArActionColorFollow.h \ + ../include/ArACTS.h ../include/ArPTZ.h ../include/ArPTZConnector.h \ + ../include/ArActionDeceleratingLimiter.h \ + ../include/ArActionLimiterForwards.h \ + ../include/ArActionLimiterBackwards.h \ + ../include/ArActionLimiterTableSensor.h ../include/ArActionBumpers.h \ + ../include/ArActionIRs.h ../include/ArActionStallRecover.h \ + ../include/ArActionAvoidFront.h ../include/ArActionAvoidSide.h \ + ../include/ArActionConstantVelocity.h ../include/ArActionInput.h \ + ../include/ArActionRobotJoydrive.h ../include/ArActionJoydrive.h \ + ../include/ArActionKeydrive.h ../include/ArActionTriangleDriveTo.h \ + ../include/ArLineFinder.h ../include/ArActionTurn.h \ + ../include/ArActionRatioInput.h ../include/ArActionStop.h \ + ../include/ArActionGoto.h ../include/ArModule.h \ + ../include/ArModuleLoader.h ../include/ArRecurrentTask.h \ + ../include/ArGripper.h ../include/ArSonyPTZ.h ../include/ArRVisionPTZ.h \ + ../include/ArAMPTU.h ../include/ArP2Arm.h ../include/ArSick.h \ + ../include/ArLaser.h ../include/ArRangeDeviceThreaded.h \ + ../include/ArFunctorASyncTask.h ../include/ArLMS2xx.h \ + ../include/ArLMS2xxPacket.h ../include/ArLMS2xxPacketReceiver.h \ + ../include/ArLaserLogger.h ../include/ArIrrfDevice.h \ + ../include/ArDPPTU.h ../include/ArVCC4.h ../include/ArMode.h \ + ../include/ArModes.h ../include/ArTCMCompassRobot.h ../include/ArTCM2.h \ + ../include/ArNetServer.h ../include/ArSignalHandler.h \ + ../include/ArAnalogGyro.h ../include/ArMapInterface.h \ + ../include/ArMapObject.h ../include/ArMapUtils.h ../include/ArMap.h \ + ../include/ArMapComponents.h ../include/ArBumpers.h ../include/ArIRs.h \ + ../include/ArForbiddenRangeDevice.h ../include/ArVersalogicIO.h \ + ../include/ArMTXIO.h ../include/ArActionGotoStraight.h \ + ../include/ArDataLogger.h ../include/ArRobotJoyHandler.h \ + ../include/ArRatioInputKeydrive.h ../include/ArRatioInputJoydrive.h \ + ../include/ArRatioInputRobotJoydrive.h \ + ../include/ArActionMovementParameters.h ../include/ArSoundPlayer.h \ + ../include/ArSoundsQueue.h ../include/ArSpeech.h \ + ../include/ArCameraCollection.h ../include/ArCameraCommands.h \ + ../include/ArSonarAutoDisabler.h ../include/ArActionDriveDistance.h \ + ../include/ArLaserReflectorDevice.h ../include/ArRobotConfig.h \ + ../include/ArTCMCompassDirect.h ../include/ArNMEAParser.h \ + ../include/ArLaserFilter.h ../include/ArUrg.h ../include/ArGPS.h \ + ../include/ArTrimbleGPS.h ../include/ArNovatelGPS.h \ + ../include/ArGPSCoords.h ../include/ArSonarConnector.h \ + ../include/ArBatteryConnector.h ../include/ArLCDConnector.h \ + ../include/ArSonarMTX.h ../include/ArBatteryMTX.h ../include/ArLCDMTX.h \ + ../include/ArSimulatedLaser.h ../include/ArExitErrorSource.h \ + ../include/ArActionLimiterRot.h ../include/ArRobotBatteryPacketReader.h \ + ../include/ArLMS1XX.h ../include/ArUrg_2_0.h \ + ../include/ArActionMovementParametersDebugging.h ../include/ArZippable.h \ + ../include/ArS3Series.h ../include/ArSZSeries.h ../include/ArExport.h \ + include/ArHybridForwarderVideo.h include/ArServerBase.h \ + include/ArServerCommands.h include/ArServerClient.h \ + include/ArNetPacket.h include/ArNetPacketReceiverTcp.h \ + include/ArNetPacketSenderTcp.h include/ArServerClientData.h \ + include/ArServerClientIdentifier.h include/ArServerData.h \ + include/ArNetPacketReceiverUdp.h include/ArServerUserInfo.h \ + include/ArClientBase.h include/ArClientCommands.h include/ArClientData.h +../obj/ArMapChanger.o: src/ArMapChanger.cpp ../include/Aria.h \ + ../include/ariaOSDef.h ../include/ariaTypedefs.h \ + ../include/ArSerialConnection.h ../include/ArDeviceConnection.h \ + ../include/ariaUtil.h ../include/ArLog.h ../include/ArMutex.h \ + ../include/ArFunctor.h ../include/ArArgumentParser.h \ + ../include/ArArgumentBuilder.h ../include/ArBasePacket.h \ + ../include/ArTcpConnection.h ../include/ArSocket.h \ + ../include/ArSimpleConnector.h ../include/ArRobotConnector.h \ + ../include/ArLaserConnector.h ../include/ArLogFileConnection.h \ + ../include/ArRobotPacket.h ../include/ArRobotPacketSender.h \ + ../include/ArRobotPacketReceiver.h \ + ../include/ArRobotConfigPacketReader.h ../include/ArRobotTypes.h \ + ../include/ArRobotParams.h ../include/ArConfig.h \ + ../include/ArConfigArg.h ../include/ArFileParser.h \ + ../include/ArHasFileName.h ../include/ArConfigGroup.h \ + ../include/ArRobot.h ../include/ArSyncTask.h ../include/ArTaskState.h \ + ../include/ArSensorReading.h ../include/ArTransform.h \ + ../include/ArCondition.h ../include/ArSyncLoop.h \ + ../include/ArASyncTask.h ../include/ArThread.h \ + ../include/ArRobotPacketReaderThread.h ../include/ArActionDesired.h \ + ../include/ArResolver.h ../include/ArInterpolation.h \ + ../include/ArKeyHandler.h ../include/ArCommands.h \ + ../include/ArJoyHandler.h ../include/ariaInternal.h \ + ../include/ArStringInfoGroup.h ../include/ArSonarDevice.h \ + ../include/ArRangeDevice.h ../include/ArRangeBuffer.h \ + ../include/ArDrawingData.h ../include/ArPriorityResolver.h \ + ../include/ArAction.h ../include/ArArg.h ../include/ArActionGroup.h \ + ../include/ArActionGroups.h ../include/ArActionColorFollow.h \ + ../include/ArACTS.h ../include/ArPTZ.h ../include/ArPTZConnector.h \ + ../include/ArActionDeceleratingLimiter.h \ + ../include/ArActionLimiterForwards.h \ + ../include/ArActionLimiterBackwards.h \ + ../include/ArActionLimiterTableSensor.h ../include/ArActionBumpers.h \ + ../include/ArActionIRs.h ../include/ArActionStallRecover.h \ + ../include/ArActionAvoidFront.h ../include/ArActionAvoidSide.h \ + ../include/ArActionConstantVelocity.h ../include/ArActionInput.h \ + ../include/ArActionRobotJoydrive.h ../include/ArActionJoydrive.h \ + ../include/ArActionKeydrive.h ../include/ArActionTriangleDriveTo.h \ + ../include/ArLineFinder.h ../include/ArActionTurn.h \ + ../include/ArActionRatioInput.h ../include/ArActionStop.h \ + ../include/ArActionGoto.h ../include/ArModule.h \ + ../include/ArModuleLoader.h ../include/ArRecurrentTask.h \ + ../include/ArGripper.h ../include/ArSonyPTZ.h ../include/ArRVisionPTZ.h \ + ../include/ArAMPTU.h ../include/ArP2Arm.h ../include/ArSick.h \ + ../include/ArLaser.h ../include/ArRangeDeviceThreaded.h \ + ../include/ArFunctorASyncTask.h ../include/ArLMS2xx.h \ + ../include/ArLMS2xxPacket.h ../include/ArLMS2xxPacketReceiver.h \ + ../include/ArLaserLogger.h ../include/ArIrrfDevice.h \ + ../include/ArDPPTU.h ../include/ArVCC4.h ../include/ArMode.h \ + ../include/ArModes.h ../include/ArTCMCompassRobot.h ../include/ArTCM2.h \ + ../include/ArNetServer.h ../include/ArSignalHandler.h \ + ../include/ArAnalogGyro.h ../include/ArMapInterface.h \ + ../include/ArMapObject.h ../include/ArMapUtils.h ../include/ArMap.h \ + ../include/ArMapComponents.h ../include/ArBumpers.h ../include/ArIRs.h \ + ../include/ArForbiddenRangeDevice.h ../include/ArVersalogicIO.h \ + ../include/ArMTXIO.h ../include/ArActionGotoStraight.h \ + ../include/ArDataLogger.h ../include/ArRobotJoyHandler.h \ + ../include/ArRatioInputKeydrive.h ../include/ArRatioInputJoydrive.h \ + ../include/ArRatioInputRobotJoydrive.h \ + ../include/ArActionMovementParameters.h ../include/ArSoundPlayer.h \ + ../include/ArSoundsQueue.h ../include/ArSpeech.h \ + ../include/ArCameraCollection.h ../include/ArCameraCommands.h \ + ../include/ArSonarAutoDisabler.h ../include/ArActionDriveDistance.h \ + ../include/ArLaserReflectorDevice.h ../include/ArRobotConfig.h \ + ../include/ArTCMCompassDirect.h ../include/ArNMEAParser.h \ + ../include/ArLaserFilter.h ../include/ArUrg.h ../include/ArGPS.h \ + ../include/ArTrimbleGPS.h ../include/ArNovatelGPS.h \ + ../include/ArGPSCoords.h ../include/ArSonarConnector.h \ + ../include/ArBatteryConnector.h ../include/ArLCDConnector.h \ + ../include/ArSonarMTX.h ../include/ArBatteryMTX.h ../include/ArLCDMTX.h \ + ../include/ArSimulatedLaser.h ../include/ArExitErrorSource.h \ + ../include/ArActionLimiterRot.h ../include/ArRobotBatteryPacketReader.h \ + ../include/ArLMS1XX.h ../include/ArUrg_2_0.h \ + ../include/ArActionMovementParametersDebugging.h ../include/ArZippable.h \ + ../include/ArS3Series.h ../include/ArSZSeries.h ../include/ArExport.h \ + include/ArMapChanger.h ../include/ariaTypedefs.h ../include/ariaUtil.h \ + ../include/ArMapInterface.h ../include/ArMapUtils.h ../include/ArMutex.h \ + include/ArNetPacket.h include/ArCentralForwarder.h \ + include/ArServerBase.h include/ArServerCommands.h \ + include/ArServerClient.h include/ArNetPacketReceiverTcp.h \ + include/ArNetPacketSenderTcp.h include/ArServerClientData.h \ + include/ArServerClientIdentifier.h include/ArServerData.h \ + include/ArNetPacketReceiverUdp.h include/ArServerUserInfo.h \ + include/ArClientBase.h include/ArClientCommands.h include/ArClientData.h \ + include/ArClientSwitchManager.h include/ArMapChanger.h \ + ../include/ArFileParser.h ../include/ArMD5Calculator.h ../include/md5.h +../obj/ArNetPacket.o: src/ArNetPacket.cpp ../include/Aria.h \ + ../include/ariaOSDef.h ../include/ariaTypedefs.h \ + ../include/ArSerialConnection.h ../include/ArDeviceConnection.h \ + ../include/ariaUtil.h ../include/ArLog.h ../include/ArMutex.h \ + ../include/ArFunctor.h ../include/ArArgumentParser.h \ + ../include/ArArgumentBuilder.h ../include/ArBasePacket.h \ + ../include/ArTcpConnection.h ../include/ArSocket.h \ + ../include/ArSimpleConnector.h ../include/ArRobotConnector.h \ + ../include/ArLaserConnector.h ../include/ArLogFileConnection.h \ + ../include/ArRobotPacket.h ../include/ArRobotPacketSender.h \ + ../include/ArRobotPacketReceiver.h \ + ../include/ArRobotConfigPacketReader.h ../include/ArRobotTypes.h \ + ../include/ArRobotParams.h ../include/ArConfig.h \ + ../include/ArConfigArg.h ../include/ArFileParser.h \ + ../include/ArHasFileName.h ../include/ArConfigGroup.h \ + ../include/ArRobot.h ../include/ArSyncTask.h ../include/ArTaskState.h \ + ../include/ArSensorReading.h ../include/ArTransform.h \ + ../include/ArCondition.h ../include/ArSyncLoop.h \ + ../include/ArASyncTask.h ../include/ArThread.h \ + ../include/ArRobotPacketReaderThread.h ../include/ArActionDesired.h \ + ../include/ArResolver.h ../include/ArInterpolation.h \ + ../include/ArKeyHandler.h ../include/ArCommands.h \ + ../include/ArJoyHandler.h ../include/ariaInternal.h \ + ../include/ArStringInfoGroup.h ../include/ArSonarDevice.h \ + ../include/ArRangeDevice.h ../include/ArRangeBuffer.h \ + ../include/ArDrawingData.h ../include/ArPriorityResolver.h \ + ../include/ArAction.h ../include/ArArg.h ../include/ArActionGroup.h \ + ../include/ArActionGroups.h ../include/ArActionColorFollow.h \ + ../include/ArACTS.h ../include/ArPTZ.h ../include/ArPTZConnector.h \ + ../include/ArActionDeceleratingLimiter.h \ + ../include/ArActionLimiterForwards.h \ + ../include/ArActionLimiterBackwards.h \ + ../include/ArActionLimiterTableSensor.h ../include/ArActionBumpers.h \ + ../include/ArActionIRs.h ../include/ArActionStallRecover.h \ + ../include/ArActionAvoidFront.h ../include/ArActionAvoidSide.h \ + ../include/ArActionConstantVelocity.h ../include/ArActionInput.h \ + ../include/ArActionRobotJoydrive.h ../include/ArActionJoydrive.h \ + ../include/ArActionKeydrive.h ../include/ArActionTriangleDriveTo.h \ + ../include/ArLineFinder.h ../include/ArActionTurn.h \ + ../include/ArActionRatioInput.h ../include/ArActionStop.h \ + ../include/ArActionGoto.h ../include/ArModule.h \ + ../include/ArModuleLoader.h ../include/ArRecurrentTask.h \ + ../include/ArGripper.h ../include/ArSonyPTZ.h ../include/ArRVisionPTZ.h \ + ../include/ArAMPTU.h ../include/ArP2Arm.h ../include/ArSick.h \ + ../include/ArLaser.h ../include/ArRangeDeviceThreaded.h \ + ../include/ArFunctorASyncTask.h ../include/ArLMS2xx.h \ + ../include/ArLMS2xxPacket.h ../include/ArLMS2xxPacketReceiver.h \ + ../include/ArLaserLogger.h ../include/ArIrrfDevice.h \ + ../include/ArDPPTU.h ../include/ArVCC4.h ../include/ArMode.h \ + ../include/ArModes.h ../include/ArTCMCompassRobot.h ../include/ArTCM2.h \ + ../include/ArNetServer.h ../include/ArSignalHandler.h \ + ../include/ArAnalogGyro.h ../include/ArMapInterface.h \ + ../include/ArMapObject.h ../include/ArMapUtils.h ../include/ArMap.h \ + ../include/ArMapComponents.h ../include/ArBumpers.h ../include/ArIRs.h \ + ../include/ArForbiddenRangeDevice.h ../include/ArVersalogicIO.h \ + ../include/ArMTXIO.h ../include/ArActionGotoStraight.h \ + ../include/ArDataLogger.h ../include/ArRobotJoyHandler.h \ + ../include/ArRatioInputKeydrive.h ../include/ArRatioInputJoydrive.h \ + ../include/ArRatioInputRobotJoydrive.h \ + ../include/ArActionMovementParameters.h ../include/ArSoundPlayer.h \ + ../include/ArSoundsQueue.h ../include/ArSpeech.h \ + ../include/ArCameraCollection.h ../include/ArCameraCommands.h \ + ../include/ArSonarAutoDisabler.h ../include/ArActionDriveDistance.h \ + ../include/ArLaserReflectorDevice.h ../include/ArRobotConfig.h \ + ../include/ArTCMCompassDirect.h ../include/ArNMEAParser.h \ + ../include/ArLaserFilter.h ../include/ArUrg.h ../include/ArGPS.h \ + ../include/ArTrimbleGPS.h ../include/ArNovatelGPS.h \ + ../include/ArGPSCoords.h ../include/ArSonarConnector.h \ + ../include/ArBatteryConnector.h ../include/ArLCDConnector.h \ + ../include/ArSonarMTX.h ../include/ArBatteryMTX.h ../include/ArLCDMTX.h \ + ../include/ArSimulatedLaser.h ../include/ArExitErrorSource.h \ + ../include/ArActionLimiterRot.h ../include/ArRobotBatteryPacketReader.h \ + ../include/ArLMS1XX.h ../include/ArUrg_2_0.h \ + ../include/ArActionMovementParametersDebugging.h ../include/ArZippable.h \ + ../include/ArS3Series.h ../include/ArSZSeries.h ../include/ArExport.h \ + include/ArNetPacket.h +../obj/ArNetPacketReceiverTcp.o: src/ArNetPacketReceiverTcp.cpp \ + ../include/Aria.h ../include/ariaOSDef.h ../include/ariaTypedefs.h \ + ../include/ArSerialConnection.h ../include/ArDeviceConnection.h \ + ../include/ariaUtil.h ../include/ArLog.h ../include/ArMutex.h \ + ../include/ArFunctor.h ../include/ArArgumentParser.h \ + ../include/ArArgumentBuilder.h ../include/ArBasePacket.h \ + ../include/ArTcpConnection.h ../include/ArSocket.h \ + ../include/ArSimpleConnector.h ../include/ArRobotConnector.h \ + ../include/ArLaserConnector.h ../include/ArLogFileConnection.h \ + ../include/ArRobotPacket.h ../include/ArRobotPacketSender.h \ + ../include/ArRobotPacketReceiver.h \ + ../include/ArRobotConfigPacketReader.h ../include/ArRobotTypes.h \ + ../include/ArRobotParams.h ../include/ArConfig.h \ + ../include/ArConfigArg.h ../include/ArFileParser.h \ + ../include/ArHasFileName.h ../include/ArConfigGroup.h \ + ../include/ArRobot.h ../include/ArSyncTask.h ../include/ArTaskState.h \ + ../include/ArSensorReading.h ../include/ArTransform.h \ + ../include/ArCondition.h ../include/ArSyncLoop.h \ + ../include/ArASyncTask.h ../include/ArThread.h \ + ../include/ArRobotPacketReaderThread.h ../include/ArActionDesired.h \ + ../include/ArResolver.h ../include/ArInterpolation.h \ + ../include/ArKeyHandler.h ../include/ArCommands.h \ + ../include/ArJoyHandler.h ../include/ariaInternal.h \ + ../include/ArStringInfoGroup.h ../include/ArSonarDevice.h \ + ../include/ArRangeDevice.h ../include/ArRangeBuffer.h \ + ../include/ArDrawingData.h ../include/ArPriorityResolver.h \ + ../include/ArAction.h ../include/ArArg.h ../include/ArActionGroup.h \ + ../include/ArActionGroups.h ../include/ArActionColorFollow.h \ + ../include/ArACTS.h ../include/ArPTZ.h ../include/ArPTZConnector.h \ + ../include/ArActionDeceleratingLimiter.h \ + ../include/ArActionLimiterForwards.h \ + ../include/ArActionLimiterBackwards.h \ + ../include/ArActionLimiterTableSensor.h ../include/ArActionBumpers.h \ + ../include/ArActionIRs.h ../include/ArActionStallRecover.h \ + ../include/ArActionAvoidFront.h ../include/ArActionAvoidSide.h \ + ../include/ArActionConstantVelocity.h ../include/ArActionInput.h \ + ../include/ArActionRobotJoydrive.h ../include/ArActionJoydrive.h \ + ../include/ArActionKeydrive.h ../include/ArActionTriangleDriveTo.h \ + ../include/ArLineFinder.h ../include/ArActionTurn.h \ + ../include/ArActionRatioInput.h ../include/ArActionStop.h \ + ../include/ArActionGoto.h ../include/ArModule.h \ + ../include/ArModuleLoader.h ../include/ArRecurrentTask.h \ + ../include/ArGripper.h ../include/ArSonyPTZ.h ../include/ArRVisionPTZ.h \ + ../include/ArAMPTU.h ../include/ArP2Arm.h ../include/ArSick.h \ + ../include/ArLaser.h ../include/ArRangeDeviceThreaded.h \ + ../include/ArFunctorASyncTask.h ../include/ArLMS2xx.h \ + ../include/ArLMS2xxPacket.h ../include/ArLMS2xxPacketReceiver.h \ + ../include/ArLaserLogger.h ../include/ArIrrfDevice.h \ + ../include/ArDPPTU.h ../include/ArVCC4.h ../include/ArMode.h \ + ../include/ArModes.h ../include/ArTCMCompassRobot.h ../include/ArTCM2.h \ + ../include/ArNetServer.h ../include/ArSignalHandler.h \ + ../include/ArAnalogGyro.h ../include/ArMapInterface.h \ + ../include/ArMapObject.h ../include/ArMapUtils.h ../include/ArMap.h \ + ../include/ArMapComponents.h ../include/ArBumpers.h ../include/ArIRs.h \ + ../include/ArForbiddenRangeDevice.h ../include/ArVersalogicIO.h \ + ../include/ArMTXIO.h ../include/ArActionGotoStraight.h \ + ../include/ArDataLogger.h ../include/ArRobotJoyHandler.h \ + ../include/ArRatioInputKeydrive.h ../include/ArRatioInputJoydrive.h \ + ../include/ArRatioInputRobotJoydrive.h \ + ../include/ArActionMovementParameters.h ../include/ArSoundPlayer.h \ + ../include/ArSoundsQueue.h ../include/ArSpeech.h \ + ../include/ArCameraCollection.h ../include/ArCameraCommands.h \ + ../include/ArSonarAutoDisabler.h ../include/ArActionDriveDistance.h \ + ../include/ArLaserReflectorDevice.h ../include/ArRobotConfig.h \ + ../include/ArTCMCompassDirect.h ../include/ArNMEAParser.h \ + ../include/ArLaserFilter.h ../include/ArUrg.h ../include/ArGPS.h \ + ../include/ArTrimbleGPS.h ../include/ArNovatelGPS.h \ + ../include/ArGPSCoords.h ../include/ArSonarConnector.h \ + ../include/ArBatteryConnector.h ../include/ArLCDConnector.h \ + ../include/ArSonarMTX.h ../include/ArBatteryMTX.h ../include/ArLCDMTX.h \ + ../include/ArSimulatedLaser.h ../include/ArExitErrorSource.h \ + ../include/ArActionLimiterRot.h ../include/ArRobotBatteryPacketReader.h \ + ../include/ArLMS1XX.h ../include/ArUrg_2_0.h \ + ../include/ArActionMovementParametersDebugging.h ../include/ArZippable.h \ + ../include/ArS3Series.h ../include/ArSZSeries.h ../include/ArExport.h \ + include/ArNetPacketReceiverTcp.h include/ArNetPacket.h +../obj/ArNetPacketReceiverUdp.o: src/ArNetPacketReceiverUdp.cpp \ + ../include/Aria.h ../include/ariaOSDef.h ../include/ariaTypedefs.h \ + ../include/ArSerialConnection.h ../include/ArDeviceConnection.h \ + ../include/ariaUtil.h ../include/ArLog.h ../include/ArMutex.h \ + ../include/ArFunctor.h ../include/ArArgumentParser.h \ + ../include/ArArgumentBuilder.h ../include/ArBasePacket.h \ + ../include/ArTcpConnection.h ../include/ArSocket.h \ + ../include/ArSimpleConnector.h ../include/ArRobotConnector.h \ + ../include/ArLaserConnector.h ../include/ArLogFileConnection.h \ + ../include/ArRobotPacket.h ../include/ArRobotPacketSender.h \ + ../include/ArRobotPacketReceiver.h \ + ../include/ArRobotConfigPacketReader.h ../include/ArRobotTypes.h \ + ../include/ArRobotParams.h ../include/ArConfig.h \ + ../include/ArConfigArg.h ../include/ArFileParser.h \ + ../include/ArHasFileName.h ../include/ArConfigGroup.h \ + ../include/ArRobot.h ../include/ArSyncTask.h ../include/ArTaskState.h \ + ../include/ArSensorReading.h ../include/ArTransform.h \ + ../include/ArCondition.h ../include/ArSyncLoop.h \ + ../include/ArASyncTask.h ../include/ArThread.h \ + ../include/ArRobotPacketReaderThread.h ../include/ArActionDesired.h \ + ../include/ArResolver.h ../include/ArInterpolation.h \ + ../include/ArKeyHandler.h ../include/ArCommands.h \ + ../include/ArJoyHandler.h ../include/ariaInternal.h \ + ../include/ArStringInfoGroup.h ../include/ArSonarDevice.h \ + ../include/ArRangeDevice.h ../include/ArRangeBuffer.h \ + ../include/ArDrawingData.h ../include/ArPriorityResolver.h \ + ../include/ArAction.h ../include/ArArg.h ../include/ArActionGroup.h \ + ../include/ArActionGroups.h ../include/ArActionColorFollow.h \ + ../include/ArACTS.h ../include/ArPTZ.h ../include/ArPTZConnector.h \ + ../include/ArActionDeceleratingLimiter.h \ + ../include/ArActionLimiterForwards.h \ + ../include/ArActionLimiterBackwards.h \ + ../include/ArActionLimiterTableSensor.h ../include/ArActionBumpers.h \ + ../include/ArActionIRs.h ../include/ArActionStallRecover.h \ + ../include/ArActionAvoidFront.h ../include/ArActionAvoidSide.h \ + ../include/ArActionConstantVelocity.h ../include/ArActionInput.h \ + ../include/ArActionRobotJoydrive.h ../include/ArActionJoydrive.h \ + ../include/ArActionKeydrive.h ../include/ArActionTriangleDriveTo.h \ + ../include/ArLineFinder.h ../include/ArActionTurn.h \ + ../include/ArActionRatioInput.h ../include/ArActionStop.h \ + ../include/ArActionGoto.h ../include/ArModule.h \ + ../include/ArModuleLoader.h ../include/ArRecurrentTask.h \ + ../include/ArGripper.h ../include/ArSonyPTZ.h ../include/ArRVisionPTZ.h \ + ../include/ArAMPTU.h ../include/ArP2Arm.h ../include/ArSick.h \ + ../include/ArLaser.h ../include/ArRangeDeviceThreaded.h \ + ../include/ArFunctorASyncTask.h ../include/ArLMS2xx.h \ + ../include/ArLMS2xxPacket.h ../include/ArLMS2xxPacketReceiver.h \ + ../include/ArLaserLogger.h ../include/ArIrrfDevice.h \ + ../include/ArDPPTU.h ../include/ArVCC4.h ../include/ArMode.h \ + ../include/ArModes.h ../include/ArTCMCompassRobot.h ../include/ArTCM2.h \ + ../include/ArNetServer.h ../include/ArSignalHandler.h \ + ../include/ArAnalogGyro.h ../include/ArMapInterface.h \ + ../include/ArMapObject.h ../include/ArMapUtils.h ../include/ArMap.h \ + ../include/ArMapComponents.h ../include/ArBumpers.h ../include/ArIRs.h \ + ../include/ArForbiddenRangeDevice.h ../include/ArVersalogicIO.h \ + ../include/ArMTXIO.h ../include/ArActionGotoStraight.h \ + ../include/ArDataLogger.h ../include/ArRobotJoyHandler.h \ + ../include/ArRatioInputKeydrive.h ../include/ArRatioInputJoydrive.h \ + ../include/ArRatioInputRobotJoydrive.h \ + ../include/ArActionMovementParameters.h ../include/ArSoundPlayer.h \ + ../include/ArSoundsQueue.h ../include/ArSpeech.h \ + ../include/ArCameraCollection.h ../include/ArCameraCommands.h \ + ../include/ArSonarAutoDisabler.h ../include/ArActionDriveDistance.h \ + ../include/ArLaserReflectorDevice.h ../include/ArRobotConfig.h \ + ../include/ArTCMCompassDirect.h ../include/ArNMEAParser.h \ + ../include/ArLaserFilter.h ../include/ArUrg.h ../include/ArGPS.h \ + ../include/ArTrimbleGPS.h ../include/ArNovatelGPS.h \ + ../include/ArGPSCoords.h ../include/ArSonarConnector.h \ + ../include/ArBatteryConnector.h ../include/ArLCDConnector.h \ + ../include/ArSonarMTX.h ../include/ArBatteryMTX.h ../include/ArLCDMTX.h \ + ../include/ArSimulatedLaser.h ../include/ArExitErrorSource.h \ + ../include/ArActionLimiterRot.h ../include/ArRobotBatteryPacketReader.h \ + ../include/ArLMS1XX.h ../include/ArUrg_2_0.h \ + ../include/ArActionMovementParametersDebugging.h ../include/ArZippable.h \ + ../include/ArS3Series.h ../include/ArSZSeries.h ../include/ArExport.h \ + include/ArNetPacketReceiverUdp.h include/ArNetPacket.h +../obj/ArNetPacketSenderTcp.o: src/ArNetPacketSenderTcp.cpp ../include/Aria.h \ + ../include/ariaOSDef.h ../include/ariaTypedefs.h \ + ../include/ArSerialConnection.h ../include/ArDeviceConnection.h \ + ../include/ariaUtil.h ../include/ArLog.h ../include/ArMutex.h \ + ../include/ArFunctor.h ../include/ArArgumentParser.h \ + ../include/ArArgumentBuilder.h ../include/ArBasePacket.h \ + ../include/ArTcpConnection.h ../include/ArSocket.h \ + ../include/ArSimpleConnector.h ../include/ArRobotConnector.h \ + ../include/ArLaserConnector.h ../include/ArLogFileConnection.h \ + ../include/ArRobotPacket.h ../include/ArRobotPacketSender.h \ + ../include/ArRobotPacketReceiver.h \ + ../include/ArRobotConfigPacketReader.h ../include/ArRobotTypes.h \ + ../include/ArRobotParams.h ../include/ArConfig.h \ + ../include/ArConfigArg.h ../include/ArFileParser.h \ + ../include/ArHasFileName.h ../include/ArConfigGroup.h \ + ../include/ArRobot.h ../include/ArSyncTask.h ../include/ArTaskState.h \ + ../include/ArSensorReading.h ../include/ArTransform.h \ + ../include/ArCondition.h ../include/ArSyncLoop.h \ + ../include/ArASyncTask.h ../include/ArThread.h \ + ../include/ArRobotPacketReaderThread.h ../include/ArActionDesired.h \ + ../include/ArResolver.h ../include/ArInterpolation.h \ + ../include/ArKeyHandler.h ../include/ArCommands.h \ + ../include/ArJoyHandler.h ../include/ariaInternal.h \ + ../include/ArStringInfoGroup.h ../include/ArSonarDevice.h \ + ../include/ArRangeDevice.h ../include/ArRangeBuffer.h \ + ../include/ArDrawingData.h ../include/ArPriorityResolver.h \ + ../include/ArAction.h ../include/ArArg.h ../include/ArActionGroup.h \ + ../include/ArActionGroups.h ../include/ArActionColorFollow.h \ + ../include/ArACTS.h ../include/ArPTZ.h ../include/ArPTZConnector.h \ + ../include/ArActionDeceleratingLimiter.h \ + ../include/ArActionLimiterForwards.h \ + ../include/ArActionLimiterBackwards.h \ + ../include/ArActionLimiterTableSensor.h ../include/ArActionBumpers.h \ + ../include/ArActionIRs.h ../include/ArActionStallRecover.h \ + ../include/ArActionAvoidFront.h ../include/ArActionAvoidSide.h \ + ../include/ArActionConstantVelocity.h ../include/ArActionInput.h \ + ../include/ArActionRobotJoydrive.h ../include/ArActionJoydrive.h \ + ../include/ArActionKeydrive.h ../include/ArActionTriangleDriveTo.h \ + ../include/ArLineFinder.h ../include/ArActionTurn.h \ + ../include/ArActionRatioInput.h ../include/ArActionStop.h \ + ../include/ArActionGoto.h ../include/ArModule.h \ + ../include/ArModuleLoader.h ../include/ArRecurrentTask.h \ + ../include/ArGripper.h ../include/ArSonyPTZ.h ../include/ArRVisionPTZ.h \ + ../include/ArAMPTU.h ../include/ArP2Arm.h ../include/ArSick.h \ + ../include/ArLaser.h ../include/ArRangeDeviceThreaded.h \ + ../include/ArFunctorASyncTask.h ../include/ArLMS2xx.h \ + ../include/ArLMS2xxPacket.h ../include/ArLMS2xxPacketReceiver.h \ + ../include/ArLaserLogger.h ../include/ArIrrfDevice.h \ + ../include/ArDPPTU.h ../include/ArVCC4.h ../include/ArMode.h \ + ../include/ArModes.h ../include/ArTCMCompassRobot.h ../include/ArTCM2.h \ + ../include/ArNetServer.h ../include/ArSignalHandler.h \ + ../include/ArAnalogGyro.h ../include/ArMapInterface.h \ + ../include/ArMapObject.h ../include/ArMapUtils.h ../include/ArMap.h \ + ../include/ArMapComponents.h ../include/ArBumpers.h ../include/ArIRs.h \ + ../include/ArForbiddenRangeDevice.h ../include/ArVersalogicIO.h \ + ../include/ArMTXIO.h ../include/ArActionGotoStraight.h \ + ../include/ArDataLogger.h ../include/ArRobotJoyHandler.h \ + ../include/ArRatioInputKeydrive.h ../include/ArRatioInputJoydrive.h \ + ../include/ArRatioInputRobotJoydrive.h \ + ../include/ArActionMovementParameters.h ../include/ArSoundPlayer.h \ + ../include/ArSoundsQueue.h ../include/ArSpeech.h \ + ../include/ArCameraCollection.h ../include/ArCameraCommands.h \ + ../include/ArSonarAutoDisabler.h ../include/ArActionDriveDistance.h \ + ../include/ArLaserReflectorDevice.h ../include/ArRobotConfig.h \ + ../include/ArTCMCompassDirect.h ../include/ArNMEAParser.h \ + ../include/ArLaserFilter.h ../include/ArUrg.h ../include/ArGPS.h \ + ../include/ArTrimbleGPS.h ../include/ArNovatelGPS.h \ + ../include/ArGPSCoords.h ../include/ArSonarConnector.h \ + ../include/ArBatteryConnector.h ../include/ArLCDConnector.h \ + ../include/ArSonarMTX.h ../include/ArBatteryMTX.h ../include/ArLCDMTX.h \ + ../include/ArSimulatedLaser.h ../include/ArExitErrorSource.h \ + ../include/ArActionLimiterRot.h ../include/ArRobotBatteryPacketReader.h \ + ../include/ArLMS1XX.h ../include/ArUrg_2_0.h \ + ../include/ArActionMovementParametersDebugging.h ../include/ArZippable.h \ + ../include/ArS3Series.h ../include/ArSZSeries.h ../include/ArExport.h \ + include/ArNetPacketSenderTcp.h include/ArNetPacket.h +../obj/ArServerBase.o: src/ArServerBase.cpp ../include/Aria.h \ + ../include/ariaOSDef.h ../include/ariaTypedefs.h \ + ../include/ArSerialConnection.h ../include/ArDeviceConnection.h \ + ../include/ariaUtil.h ../include/ArLog.h ../include/ArMutex.h \ + ../include/ArFunctor.h ../include/ArArgumentParser.h \ + ../include/ArArgumentBuilder.h ../include/ArBasePacket.h \ + ../include/ArTcpConnection.h ../include/ArSocket.h \ + ../include/ArSimpleConnector.h ../include/ArRobotConnector.h \ + ../include/ArLaserConnector.h ../include/ArLogFileConnection.h \ + ../include/ArRobotPacket.h ../include/ArRobotPacketSender.h \ + ../include/ArRobotPacketReceiver.h \ + ../include/ArRobotConfigPacketReader.h ../include/ArRobotTypes.h \ + ../include/ArRobotParams.h ../include/ArConfig.h \ + ../include/ArConfigArg.h ../include/ArFileParser.h \ + ../include/ArHasFileName.h ../include/ArConfigGroup.h \ + ../include/ArRobot.h ../include/ArSyncTask.h ../include/ArTaskState.h \ + ../include/ArSensorReading.h ../include/ArTransform.h \ + ../include/ArCondition.h ../include/ArSyncLoop.h \ + ../include/ArASyncTask.h ../include/ArThread.h \ + ../include/ArRobotPacketReaderThread.h ../include/ArActionDesired.h \ + ../include/ArResolver.h ../include/ArInterpolation.h \ + ../include/ArKeyHandler.h ../include/ArCommands.h \ + ../include/ArJoyHandler.h ../include/ariaInternal.h \ + ../include/ArStringInfoGroup.h ../include/ArSonarDevice.h \ + ../include/ArRangeDevice.h ../include/ArRangeBuffer.h \ + ../include/ArDrawingData.h ../include/ArPriorityResolver.h \ + ../include/ArAction.h ../include/ArArg.h ../include/ArActionGroup.h \ + ../include/ArActionGroups.h ../include/ArActionColorFollow.h \ + ../include/ArACTS.h ../include/ArPTZ.h ../include/ArPTZConnector.h \ + ../include/ArActionDeceleratingLimiter.h \ + ../include/ArActionLimiterForwards.h \ + ../include/ArActionLimiterBackwards.h \ + ../include/ArActionLimiterTableSensor.h ../include/ArActionBumpers.h \ + ../include/ArActionIRs.h ../include/ArActionStallRecover.h \ + ../include/ArActionAvoidFront.h ../include/ArActionAvoidSide.h \ + ../include/ArActionConstantVelocity.h ../include/ArActionInput.h \ + ../include/ArActionRobotJoydrive.h ../include/ArActionJoydrive.h \ + ../include/ArActionKeydrive.h ../include/ArActionTriangleDriveTo.h \ + ../include/ArLineFinder.h ../include/ArActionTurn.h \ + ../include/ArActionRatioInput.h ../include/ArActionStop.h \ + ../include/ArActionGoto.h ../include/ArModule.h \ + ../include/ArModuleLoader.h ../include/ArRecurrentTask.h \ + ../include/ArGripper.h ../include/ArSonyPTZ.h ../include/ArRVisionPTZ.h \ + ../include/ArAMPTU.h ../include/ArP2Arm.h ../include/ArSick.h \ + ../include/ArLaser.h ../include/ArRangeDeviceThreaded.h \ + ../include/ArFunctorASyncTask.h ../include/ArLMS2xx.h \ + ../include/ArLMS2xxPacket.h ../include/ArLMS2xxPacketReceiver.h \ + ../include/ArLaserLogger.h ../include/ArIrrfDevice.h \ + ../include/ArDPPTU.h ../include/ArVCC4.h ../include/ArMode.h \ + ../include/ArModes.h ../include/ArTCMCompassRobot.h ../include/ArTCM2.h \ + ../include/ArNetServer.h ../include/ArSignalHandler.h \ + ../include/ArAnalogGyro.h ../include/ArMapInterface.h \ + ../include/ArMapObject.h ../include/ArMapUtils.h ../include/ArMap.h \ + ../include/ArMapComponents.h ../include/ArBumpers.h ../include/ArIRs.h \ + ../include/ArForbiddenRangeDevice.h ../include/ArVersalogicIO.h \ + ../include/ArMTXIO.h ../include/ArActionGotoStraight.h \ + ../include/ArDataLogger.h ../include/ArRobotJoyHandler.h \ + ../include/ArRatioInputKeydrive.h ../include/ArRatioInputJoydrive.h \ + ../include/ArRatioInputRobotJoydrive.h \ + ../include/ArActionMovementParameters.h ../include/ArSoundPlayer.h \ + ../include/ArSoundsQueue.h ../include/ArSpeech.h \ + ../include/ArCameraCollection.h ../include/ArCameraCommands.h \ + ../include/ArSonarAutoDisabler.h ../include/ArActionDriveDistance.h \ + ../include/ArLaserReflectorDevice.h ../include/ArRobotConfig.h \ + ../include/ArTCMCompassDirect.h ../include/ArNMEAParser.h \ + ../include/ArLaserFilter.h ../include/ArUrg.h ../include/ArGPS.h \ + ../include/ArTrimbleGPS.h ../include/ArNovatelGPS.h \ + ../include/ArGPSCoords.h ../include/ArSonarConnector.h \ + ../include/ArBatteryConnector.h ../include/ArLCDConnector.h \ + ../include/ArSonarMTX.h ../include/ArBatteryMTX.h ../include/ArLCDMTX.h \ + ../include/ArSimulatedLaser.h ../include/ArExitErrorSource.h \ + ../include/ArActionLimiterRot.h ../include/ArRobotBatteryPacketReader.h \ + ../include/ArLMS1XX.h ../include/ArUrg_2_0.h \ + ../include/ArActionMovementParametersDebugging.h ../include/ArZippable.h \ + ../include/ArS3Series.h ../include/ArSZSeries.h ../include/ArExport.h \ + include/ArServerBase.h include/ArServerCommands.h \ + include/ArServerClient.h include/ArNetPacket.h \ + include/ArNetPacketReceiverTcp.h include/ArNetPacketSenderTcp.h \ + include/ArServerClientData.h include/ArServerClientIdentifier.h \ + include/ArServerData.h include/ArNetPacketReceiverUdp.h \ + include/ArServerUserInfo.h include/ArServerCommands.h \ + include/ArClientCommands.h include/ArServerMode.h include/ArServerBase.h +../obj/ArServerClient.o: src/ArServerClient.cpp ../include/Aria.h \ + ../include/ariaOSDef.h ../include/ariaTypedefs.h \ + ../include/ArSerialConnection.h ../include/ArDeviceConnection.h \ + ../include/ariaUtil.h ../include/ArLog.h ../include/ArMutex.h \ + ../include/ArFunctor.h ../include/ArArgumentParser.h \ + ../include/ArArgumentBuilder.h ../include/ArBasePacket.h \ + ../include/ArTcpConnection.h ../include/ArSocket.h \ + ../include/ArSimpleConnector.h ../include/ArRobotConnector.h \ + ../include/ArLaserConnector.h ../include/ArLogFileConnection.h \ + ../include/ArRobotPacket.h ../include/ArRobotPacketSender.h \ + ../include/ArRobotPacketReceiver.h \ + ../include/ArRobotConfigPacketReader.h ../include/ArRobotTypes.h \ + ../include/ArRobotParams.h ../include/ArConfig.h \ + ../include/ArConfigArg.h ../include/ArFileParser.h \ + ../include/ArHasFileName.h ../include/ArConfigGroup.h \ + ../include/ArRobot.h ../include/ArSyncTask.h ../include/ArTaskState.h \ + ../include/ArSensorReading.h ../include/ArTransform.h \ + ../include/ArCondition.h ../include/ArSyncLoop.h \ + ../include/ArASyncTask.h ../include/ArThread.h \ + ../include/ArRobotPacketReaderThread.h ../include/ArActionDesired.h \ + ../include/ArResolver.h ../include/ArInterpolation.h \ + ../include/ArKeyHandler.h ../include/ArCommands.h \ + ../include/ArJoyHandler.h ../include/ariaInternal.h \ + ../include/ArStringInfoGroup.h ../include/ArSonarDevice.h \ + ../include/ArRangeDevice.h ../include/ArRangeBuffer.h \ + ../include/ArDrawingData.h ../include/ArPriorityResolver.h \ + ../include/ArAction.h ../include/ArArg.h ../include/ArActionGroup.h \ + ../include/ArActionGroups.h ../include/ArActionColorFollow.h \ + ../include/ArACTS.h ../include/ArPTZ.h ../include/ArPTZConnector.h \ + ../include/ArActionDeceleratingLimiter.h \ + ../include/ArActionLimiterForwards.h \ + ../include/ArActionLimiterBackwards.h \ + ../include/ArActionLimiterTableSensor.h ../include/ArActionBumpers.h \ + ../include/ArActionIRs.h ../include/ArActionStallRecover.h \ + ../include/ArActionAvoidFront.h ../include/ArActionAvoidSide.h \ + ../include/ArActionConstantVelocity.h ../include/ArActionInput.h \ + ../include/ArActionRobotJoydrive.h ../include/ArActionJoydrive.h \ + ../include/ArActionKeydrive.h ../include/ArActionTriangleDriveTo.h \ + ../include/ArLineFinder.h ../include/ArActionTurn.h \ + ../include/ArActionRatioInput.h ../include/ArActionStop.h \ + ../include/ArActionGoto.h ../include/ArModule.h \ + ../include/ArModuleLoader.h ../include/ArRecurrentTask.h \ + ../include/ArGripper.h ../include/ArSonyPTZ.h ../include/ArRVisionPTZ.h \ + ../include/ArAMPTU.h ../include/ArP2Arm.h ../include/ArSick.h \ + ../include/ArLaser.h ../include/ArRangeDeviceThreaded.h \ + ../include/ArFunctorASyncTask.h ../include/ArLMS2xx.h \ + ../include/ArLMS2xxPacket.h ../include/ArLMS2xxPacketReceiver.h \ + ../include/ArLaserLogger.h ../include/ArIrrfDevice.h \ + ../include/ArDPPTU.h ../include/ArVCC4.h ../include/ArMode.h \ + ../include/ArModes.h ../include/ArTCMCompassRobot.h ../include/ArTCM2.h \ + ../include/ArNetServer.h ../include/ArSignalHandler.h \ + ../include/ArAnalogGyro.h ../include/ArMapInterface.h \ + ../include/ArMapObject.h ../include/ArMapUtils.h ../include/ArMap.h \ + ../include/ArMapComponents.h ../include/ArBumpers.h ../include/ArIRs.h \ + ../include/ArForbiddenRangeDevice.h ../include/ArVersalogicIO.h \ + ../include/ArMTXIO.h ../include/ArActionGotoStraight.h \ + ../include/ArDataLogger.h ../include/ArRobotJoyHandler.h \ + ../include/ArRatioInputKeydrive.h ../include/ArRatioInputJoydrive.h \ + ../include/ArRatioInputRobotJoydrive.h \ + ../include/ArActionMovementParameters.h ../include/ArSoundPlayer.h \ + ../include/ArSoundsQueue.h ../include/ArSpeech.h \ + ../include/ArCameraCollection.h ../include/ArCameraCommands.h \ + ../include/ArSonarAutoDisabler.h ../include/ArActionDriveDistance.h \ + ../include/ArLaserReflectorDevice.h ../include/ArRobotConfig.h \ + ../include/ArTCMCompassDirect.h ../include/ArNMEAParser.h \ + ../include/ArLaserFilter.h ../include/ArUrg.h ../include/ArGPS.h \ + ../include/ArTrimbleGPS.h ../include/ArNovatelGPS.h \ + ../include/ArGPSCoords.h ../include/ArSonarConnector.h \ + ../include/ArBatteryConnector.h ../include/ArLCDConnector.h \ + ../include/ArSonarMTX.h ../include/ArBatteryMTX.h ../include/ArLCDMTX.h \ + ../include/ArSimulatedLaser.h ../include/ArExitErrorSource.h \ + ../include/ArActionLimiterRot.h ../include/ArRobotBatteryPacketReader.h \ + ../include/ArLMS1XX.h ../include/ArUrg_2_0.h \ + ../include/ArActionMovementParametersDebugging.h ../include/ArZippable.h \ + ../include/ArS3Series.h ../include/ArSZSeries.h ../include/ArExport.h \ + include/ArServerClient.h include/ArNetPacket.h \ + include/ArServerCommands.h include/ArNetPacketReceiverTcp.h \ + include/ArNetPacketSenderTcp.h include/ArServerClientData.h \ + include/ArServerClientIdentifier.h include/ArServerCommands.h \ + include/ArClientCommands.h include/ArServerData.h \ + include/ArServerUserInfo.h +../obj/ArServerData.o: src/ArServerData.cpp ../include/Aria.h \ + ../include/ariaOSDef.h ../include/ariaTypedefs.h \ + ../include/ArSerialConnection.h ../include/ArDeviceConnection.h \ + ../include/ariaUtil.h ../include/ArLog.h ../include/ArMutex.h \ + ../include/ArFunctor.h ../include/ArArgumentParser.h \ + ../include/ArArgumentBuilder.h ../include/ArBasePacket.h \ + ../include/ArTcpConnection.h ../include/ArSocket.h \ + ../include/ArSimpleConnector.h ../include/ArRobotConnector.h \ + ../include/ArLaserConnector.h ../include/ArLogFileConnection.h \ + ../include/ArRobotPacket.h ../include/ArRobotPacketSender.h \ + ../include/ArRobotPacketReceiver.h \ + ../include/ArRobotConfigPacketReader.h ../include/ArRobotTypes.h \ + ../include/ArRobotParams.h ../include/ArConfig.h \ + ../include/ArConfigArg.h ../include/ArFileParser.h \ + ../include/ArHasFileName.h ../include/ArConfigGroup.h \ + ../include/ArRobot.h ../include/ArSyncTask.h ../include/ArTaskState.h \ + ../include/ArSensorReading.h ../include/ArTransform.h \ + ../include/ArCondition.h ../include/ArSyncLoop.h \ + ../include/ArASyncTask.h ../include/ArThread.h \ + ../include/ArRobotPacketReaderThread.h ../include/ArActionDesired.h \ + ../include/ArResolver.h ../include/ArInterpolation.h \ + ../include/ArKeyHandler.h ../include/ArCommands.h \ + ../include/ArJoyHandler.h ../include/ariaInternal.h \ + ../include/ArStringInfoGroup.h ../include/ArSonarDevice.h \ + ../include/ArRangeDevice.h ../include/ArRangeBuffer.h \ + ../include/ArDrawingData.h ../include/ArPriorityResolver.h \ + ../include/ArAction.h ../include/ArArg.h ../include/ArActionGroup.h \ + ../include/ArActionGroups.h ../include/ArActionColorFollow.h \ + ../include/ArACTS.h ../include/ArPTZ.h ../include/ArPTZConnector.h \ + ../include/ArActionDeceleratingLimiter.h \ + ../include/ArActionLimiterForwards.h \ + ../include/ArActionLimiterBackwards.h \ + ../include/ArActionLimiterTableSensor.h ../include/ArActionBumpers.h \ + ../include/ArActionIRs.h ../include/ArActionStallRecover.h \ + ../include/ArActionAvoidFront.h ../include/ArActionAvoidSide.h \ + ../include/ArActionConstantVelocity.h ../include/ArActionInput.h \ + ../include/ArActionRobotJoydrive.h ../include/ArActionJoydrive.h \ + ../include/ArActionKeydrive.h ../include/ArActionTriangleDriveTo.h \ + ../include/ArLineFinder.h ../include/ArActionTurn.h \ + ../include/ArActionRatioInput.h ../include/ArActionStop.h \ + ../include/ArActionGoto.h ../include/ArModule.h \ + ../include/ArModuleLoader.h ../include/ArRecurrentTask.h \ + ../include/ArGripper.h ../include/ArSonyPTZ.h ../include/ArRVisionPTZ.h \ + ../include/ArAMPTU.h ../include/ArP2Arm.h ../include/ArSick.h \ + ../include/ArLaser.h ../include/ArRangeDeviceThreaded.h \ + ../include/ArFunctorASyncTask.h ../include/ArLMS2xx.h \ + ../include/ArLMS2xxPacket.h ../include/ArLMS2xxPacketReceiver.h \ + ../include/ArLaserLogger.h ../include/ArIrrfDevice.h \ + ../include/ArDPPTU.h ../include/ArVCC4.h ../include/ArMode.h \ + ../include/ArModes.h ../include/ArTCMCompassRobot.h ../include/ArTCM2.h \ + ../include/ArNetServer.h ../include/ArSignalHandler.h \ + ../include/ArAnalogGyro.h ../include/ArMapInterface.h \ + ../include/ArMapObject.h ../include/ArMapUtils.h ../include/ArMap.h \ + ../include/ArMapComponents.h ../include/ArBumpers.h ../include/ArIRs.h \ + ../include/ArForbiddenRangeDevice.h ../include/ArVersalogicIO.h \ + ../include/ArMTXIO.h ../include/ArActionGotoStraight.h \ + ../include/ArDataLogger.h ../include/ArRobotJoyHandler.h \ + ../include/ArRatioInputKeydrive.h ../include/ArRatioInputJoydrive.h \ + ../include/ArRatioInputRobotJoydrive.h \ + ../include/ArActionMovementParameters.h ../include/ArSoundPlayer.h \ + ../include/ArSoundsQueue.h ../include/ArSpeech.h \ + ../include/ArCameraCollection.h ../include/ArCameraCommands.h \ + ../include/ArSonarAutoDisabler.h ../include/ArActionDriveDistance.h \ + ../include/ArLaserReflectorDevice.h ../include/ArRobotConfig.h \ + ../include/ArTCMCompassDirect.h ../include/ArNMEAParser.h \ + ../include/ArLaserFilter.h ../include/ArUrg.h ../include/ArGPS.h \ + ../include/ArTrimbleGPS.h ../include/ArNovatelGPS.h \ + ../include/ArGPSCoords.h ../include/ArSonarConnector.h \ + ../include/ArBatteryConnector.h ../include/ArLCDConnector.h \ + ../include/ArSonarMTX.h ../include/ArBatteryMTX.h ../include/ArLCDMTX.h \ + ../include/ArSimulatedLaser.h ../include/ArExitErrorSource.h \ + ../include/ArActionLimiterRot.h ../include/ArRobotBatteryPacketReader.h \ + ../include/ArLMS1XX.h ../include/ArUrg_2_0.h \ + ../include/ArActionMovementParametersDebugging.h ../include/ArZippable.h \ + ../include/ArS3Series.h ../include/ArSZSeries.h ../include/ArExport.h \ + include/ArServerData.h include/ArServerClient.h include/ArNetPacket.h \ + include/ArServerCommands.h include/ArNetPacketReceiverTcp.h \ + include/ArNetPacketSenderTcp.h include/ArServerClientData.h \ + include/ArServerClientIdentifier.h include/ArNetPacket.h +../obj/ArServerFileUtils.o: src/ArServerFileUtils.cpp ../include/Aria.h \ + ../include/ariaOSDef.h ../include/ariaTypedefs.h \ + ../include/ArSerialConnection.h ../include/ArDeviceConnection.h \ + ../include/ariaUtil.h ../include/ArLog.h ../include/ArMutex.h \ + ../include/ArFunctor.h ../include/ArArgumentParser.h \ + ../include/ArArgumentBuilder.h ../include/ArBasePacket.h \ + ../include/ArTcpConnection.h ../include/ArSocket.h \ + ../include/ArSimpleConnector.h ../include/ArRobotConnector.h \ + ../include/ArLaserConnector.h ../include/ArLogFileConnection.h \ + ../include/ArRobotPacket.h ../include/ArRobotPacketSender.h \ + ../include/ArRobotPacketReceiver.h \ + ../include/ArRobotConfigPacketReader.h ../include/ArRobotTypes.h \ + ../include/ArRobotParams.h ../include/ArConfig.h \ + ../include/ArConfigArg.h ../include/ArFileParser.h \ + ../include/ArHasFileName.h ../include/ArConfigGroup.h \ + ../include/ArRobot.h ../include/ArSyncTask.h ../include/ArTaskState.h \ + ../include/ArSensorReading.h ../include/ArTransform.h \ + ../include/ArCondition.h ../include/ArSyncLoop.h \ + ../include/ArASyncTask.h ../include/ArThread.h \ + ../include/ArRobotPacketReaderThread.h ../include/ArActionDesired.h \ + ../include/ArResolver.h ../include/ArInterpolation.h \ + ../include/ArKeyHandler.h ../include/ArCommands.h \ + ../include/ArJoyHandler.h ../include/ariaInternal.h \ + ../include/ArStringInfoGroup.h ../include/ArSonarDevice.h \ + ../include/ArRangeDevice.h ../include/ArRangeBuffer.h \ + ../include/ArDrawingData.h ../include/ArPriorityResolver.h \ + ../include/ArAction.h ../include/ArArg.h ../include/ArActionGroup.h \ + ../include/ArActionGroups.h ../include/ArActionColorFollow.h \ + ../include/ArACTS.h ../include/ArPTZ.h ../include/ArPTZConnector.h \ + ../include/ArActionDeceleratingLimiter.h \ + ../include/ArActionLimiterForwards.h \ + ../include/ArActionLimiterBackwards.h \ + ../include/ArActionLimiterTableSensor.h ../include/ArActionBumpers.h \ + ../include/ArActionIRs.h ../include/ArActionStallRecover.h \ + ../include/ArActionAvoidFront.h ../include/ArActionAvoidSide.h \ + ../include/ArActionConstantVelocity.h ../include/ArActionInput.h \ + ../include/ArActionRobotJoydrive.h ../include/ArActionJoydrive.h \ + ../include/ArActionKeydrive.h ../include/ArActionTriangleDriveTo.h \ + ../include/ArLineFinder.h ../include/ArActionTurn.h \ + ../include/ArActionRatioInput.h ../include/ArActionStop.h \ + ../include/ArActionGoto.h ../include/ArModule.h \ + ../include/ArModuleLoader.h ../include/ArRecurrentTask.h \ + ../include/ArGripper.h ../include/ArSonyPTZ.h ../include/ArRVisionPTZ.h \ + ../include/ArAMPTU.h ../include/ArP2Arm.h ../include/ArSick.h \ + ../include/ArLaser.h ../include/ArRangeDeviceThreaded.h \ + ../include/ArFunctorASyncTask.h ../include/ArLMS2xx.h \ + ../include/ArLMS2xxPacket.h ../include/ArLMS2xxPacketReceiver.h \ + ../include/ArLaserLogger.h ../include/ArIrrfDevice.h \ + ../include/ArDPPTU.h ../include/ArVCC4.h ../include/ArMode.h \ + ../include/ArModes.h ../include/ArTCMCompassRobot.h ../include/ArTCM2.h \ + ../include/ArNetServer.h ../include/ArSignalHandler.h \ + ../include/ArAnalogGyro.h ../include/ArMapInterface.h \ + ../include/ArMapObject.h ../include/ArMapUtils.h ../include/ArMap.h \ + ../include/ArMapComponents.h ../include/ArBumpers.h ../include/ArIRs.h \ + ../include/ArForbiddenRangeDevice.h ../include/ArVersalogicIO.h \ + ../include/ArMTXIO.h ../include/ArActionGotoStraight.h \ + ../include/ArDataLogger.h ../include/ArRobotJoyHandler.h \ + ../include/ArRatioInputKeydrive.h ../include/ArRatioInputJoydrive.h \ + ../include/ArRatioInputRobotJoydrive.h \ + ../include/ArActionMovementParameters.h ../include/ArSoundPlayer.h \ + ../include/ArSoundsQueue.h ../include/ArSpeech.h \ + ../include/ArCameraCollection.h ../include/ArCameraCommands.h \ + ../include/ArSonarAutoDisabler.h ../include/ArActionDriveDistance.h \ + ../include/ArLaserReflectorDevice.h ../include/ArRobotConfig.h \ + ../include/ArTCMCompassDirect.h ../include/ArNMEAParser.h \ + ../include/ArLaserFilter.h ../include/ArUrg.h ../include/ArGPS.h \ + ../include/ArTrimbleGPS.h ../include/ArNovatelGPS.h \ + ../include/ArGPSCoords.h ../include/ArSonarConnector.h \ + ../include/ArBatteryConnector.h ../include/ArLCDConnector.h \ + ../include/ArSonarMTX.h ../include/ArBatteryMTX.h ../include/ArLCDMTX.h \ + ../include/ArSimulatedLaser.h ../include/ArExitErrorSource.h \ + ../include/ArActionLimiterRot.h ../include/ArRobotBatteryPacketReader.h \ + ../include/ArLMS1XX.h ../include/ArUrg_2_0.h \ + ../include/ArActionMovementParametersDebugging.h ../include/ArZippable.h \ + ../include/ArS3Series.h ../include/ArSZSeries.h ../include/ArExport.h \ + include/ArServerFileUtils.h include/ArServerBase.h \ + include/ArServerCommands.h include/ArServerClient.h \ + include/ArNetPacket.h include/ArNetPacketReceiverTcp.h \ + include/ArNetPacketSenderTcp.h include/ArServerClientData.h \ + include/ArServerClientIdentifier.h include/ArServerData.h \ + include/ArNetPacketReceiverUdp.h include/ArServerUserInfo.h +../obj/ArServerHandlerCamera.o: src/ArServerHandlerCamera.cpp ../include/Aria.h \ + ../include/ariaOSDef.h ../include/ariaTypedefs.h \ + ../include/ArSerialConnection.h ../include/ArDeviceConnection.h \ + ../include/ariaUtil.h ../include/ArLog.h ../include/ArMutex.h \ + ../include/ArFunctor.h ../include/ArArgumentParser.h \ + ../include/ArArgumentBuilder.h ../include/ArBasePacket.h \ + ../include/ArTcpConnection.h ../include/ArSocket.h \ + ../include/ArSimpleConnector.h ../include/ArRobotConnector.h \ + ../include/ArLaserConnector.h ../include/ArLogFileConnection.h \ + ../include/ArRobotPacket.h ../include/ArRobotPacketSender.h \ + ../include/ArRobotPacketReceiver.h \ + ../include/ArRobotConfigPacketReader.h ../include/ArRobotTypes.h \ + ../include/ArRobotParams.h ../include/ArConfig.h \ + ../include/ArConfigArg.h ../include/ArFileParser.h \ + ../include/ArHasFileName.h ../include/ArConfigGroup.h \ + ../include/ArRobot.h ../include/ArSyncTask.h ../include/ArTaskState.h \ + ../include/ArSensorReading.h ../include/ArTransform.h \ + ../include/ArCondition.h ../include/ArSyncLoop.h \ + ../include/ArASyncTask.h ../include/ArThread.h \ + ../include/ArRobotPacketReaderThread.h ../include/ArActionDesired.h \ + ../include/ArResolver.h ../include/ArInterpolation.h \ + ../include/ArKeyHandler.h ../include/ArCommands.h \ + ../include/ArJoyHandler.h ../include/ariaInternal.h \ + ../include/ArStringInfoGroup.h ../include/ArSonarDevice.h \ + ../include/ArRangeDevice.h ../include/ArRangeBuffer.h \ + ../include/ArDrawingData.h ../include/ArPriorityResolver.h \ + ../include/ArAction.h ../include/ArArg.h ../include/ArActionGroup.h \ + ../include/ArActionGroups.h ../include/ArActionColorFollow.h \ + ../include/ArACTS.h ../include/ArPTZ.h ../include/ArPTZConnector.h \ + ../include/ArActionDeceleratingLimiter.h \ + ../include/ArActionLimiterForwards.h \ + ../include/ArActionLimiterBackwards.h \ + ../include/ArActionLimiterTableSensor.h ../include/ArActionBumpers.h \ + ../include/ArActionIRs.h ../include/ArActionStallRecover.h \ + ../include/ArActionAvoidFront.h ../include/ArActionAvoidSide.h \ + ../include/ArActionConstantVelocity.h ../include/ArActionInput.h \ + ../include/ArActionRobotJoydrive.h ../include/ArActionJoydrive.h \ + ../include/ArActionKeydrive.h ../include/ArActionTriangleDriveTo.h \ + ../include/ArLineFinder.h ../include/ArActionTurn.h \ + ../include/ArActionRatioInput.h ../include/ArActionStop.h \ + ../include/ArActionGoto.h ../include/ArModule.h \ + ../include/ArModuleLoader.h ../include/ArRecurrentTask.h \ + ../include/ArGripper.h ../include/ArSonyPTZ.h ../include/ArRVisionPTZ.h \ + ../include/ArAMPTU.h ../include/ArP2Arm.h ../include/ArSick.h \ + ../include/ArLaser.h ../include/ArRangeDeviceThreaded.h \ + ../include/ArFunctorASyncTask.h ../include/ArLMS2xx.h \ + ../include/ArLMS2xxPacket.h ../include/ArLMS2xxPacketReceiver.h \ + ../include/ArLaserLogger.h ../include/ArIrrfDevice.h \ + ../include/ArDPPTU.h ../include/ArVCC4.h ../include/ArMode.h \ + ../include/ArModes.h ../include/ArTCMCompassRobot.h ../include/ArTCM2.h \ + ../include/ArNetServer.h ../include/ArSignalHandler.h \ + ../include/ArAnalogGyro.h ../include/ArMapInterface.h \ + ../include/ArMapObject.h ../include/ArMapUtils.h ../include/ArMap.h \ + ../include/ArMapComponents.h ../include/ArBumpers.h ../include/ArIRs.h \ + ../include/ArForbiddenRangeDevice.h ../include/ArVersalogicIO.h \ + ../include/ArMTXIO.h ../include/ArActionGotoStraight.h \ + ../include/ArDataLogger.h ../include/ArRobotJoyHandler.h \ + ../include/ArRatioInputKeydrive.h ../include/ArRatioInputJoydrive.h \ + ../include/ArRatioInputRobotJoydrive.h \ + ../include/ArActionMovementParameters.h ../include/ArSoundPlayer.h \ + ../include/ArSoundsQueue.h ../include/ArSpeech.h \ + ../include/ArCameraCollection.h ../include/ArCameraCommands.h \ + ../include/ArSonarAutoDisabler.h ../include/ArActionDriveDistance.h \ + ../include/ArLaserReflectorDevice.h ../include/ArRobotConfig.h \ + ../include/ArTCMCompassDirect.h ../include/ArNMEAParser.h \ + ../include/ArLaserFilter.h ../include/ArUrg.h ../include/ArGPS.h \ + ../include/ArTrimbleGPS.h ../include/ArNovatelGPS.h \ + ../include/ArGPSCoords.h ../include/ArSonarConnector.h \ + ../include/ArBatteryConnector.h ../include/ArLCDConnector.h \ + ../include/ArSonarMTX.h ../include/ArBatteryMTX.h ../include/ArLCDMTX.h \ + ../include/ArSimulatedLaser.h ../include/ArExitErrorSource.h \ + ../include/ArActionLimiterRot.h ../include/ArRobotBatteryPacketReader.h \ + ../include/ArLMS1XX.h ../include/ArUrg_2_0.h \ + ../include/ArActionMovementParametersDebugging.h ../include/ArZippable.h \ + ../include/ArS3Series.h ../include/ArSZSeries.h ../include/ArExport.h \ + include/ArServerHandlerCamera.h include/ArNetworking.h \ + include/ArServerBase.h include/ArServerCommands.h \ + include/ArServerClient.h include/ArNetPacket.h \ + include/ArNetPacketReceiverTcp.h include/ArNetPacketSenderTcp.h \ + include/ArServerClientData.h include/ArServerClientIdentifier.h \ + include/ArServerData.h include/ArNetPacketReceiverUdp.h \ + include/ArServerUserInfo.h include/ArClientBase.h \ + include/ArClientCommands.h include/ArClientData.h include/ArMapChanger.h \ + ../include/ariaTypedefs.h ../include/ariaUtil.h \ + ../include/ArMapInterface.h ../include/ArMapUtils.h ../include/ArMutex.h \ + include/ArCentralForwarder.h include/ArClientSwitchManager.h \ + include/ArServerHandlerCamera.h \ + include/ArServerHandlerCameraCollection.h ../include/ArFunctor.h \ + ../include/ArCameraCollection.h include/ArServerHandlerCommMonitor.h \ + include/ArServerHandlerCommands.h include/ArServerHandlerPopup.h \ + include/ArServerInfoDrawings.h include/ArServerInfoRobot.h \ + include/ArServerInfoSensor.h include/ArServerHandlerMap.h \ + ../include/ArConfig.h include/ArServerMode.h include/ArServerModeDrive.h \ + include/ArServerModeRatioDrive.h include/ArServerModeStop.h \ + include/ArServerModeWander.h include/ArServerHandlerConfig.h \ + include/ArClientHandlerConfig.h include/ArHybridForwarderVideo.h \ + include/ArServerSimpleCommands.h include/ArServerFileUtils.h \ + include/ArClientFileUtils.h include/ArClientSimpleConnector.h \ + include/ArServerHandlerMapping.h include/ArTempDirectoryHelper.h \ + include/ArServerSimpleOpener.h include/ArServerInfoStrings.h \ + include/ArClientArgUtils.h include/ArCentralManager.h \ + include/ArServerModeIdle.h +../obj/ArServerHandlerCameraCollection.o: \ + src/ArServerHandlerCameraCollection.cpp ../include/Aria.h \ + ../include/ariaOSDef.h ../include/ariaTypedefs.h \ + ../include/ArSerialConnection.h ../include/ArDeviceConnection.h \ + ../include/ariaUtil.h ../include/ArLog.h ../include/ArMutex.h \ + ../include/ArFunctor.h ../include/ArArgumentParser.h \ + ../include/ArArgumentBuilder.h ../include/ArBasePacket.h \ + ../include/ArTcpConnection.h ../include/ArSocket.h \ + ../include/ArSimpleConnector.h ../include/ArRobotConnector.h \ + ../include/ArLaserConnector.h ../include/ArLogFileConnection.h \ + ../include/ArRobotPacket.h ../include/ArRobotPacketSender.h \ + ../include/ArRobotPacketReceiver.h \ + ../include/ArRobotConfigPacketReader.h ../include/ArRobotTypes.h \ + ../include/ArRobotParams.h ../include/ArConfig.h \ + ../include/ArConfigArg.h ../include/ArFileParser.h \ + ../include/ArHasFileName.h ../include/ArConfigGroup.h \ + ../include/ArRobot.h ../include/ArSyncTask.h ../include/ArTaskState.h \ + ../include/ArSensorReading.h ../include/ArTransform.h \ + ../include/ArCondition.h ../include/ArSyncLoop.h \ + ../include/ArASyncTask.h ../include/ArThread.h \ + ../include/ArRobotPacketReaderThread.h ../include/ArActionDesired.h \ + ../include/ArResolver.h ../include/ArInterpolation.h \ + ../include/ArKeyHandler.h ../include/ArCommands.h \ + ../include/ArJoyHandler.h ../include/ariaInternal.h \ + ../include/ArStringInfoGroup.h ../include/ArSonarDevice.h \ + ../include/ArRangeDevice.h ../include/ArRangeBuffer.h \ + ../include/ArDrawingData.h ../include/ArPriorityResolver.h \ + ../include/ArAction.h ../include/ArArg.h ../include/ArActionGroup.h \ + ../include/ArActionGroups.h ../include/ArActionColorFollow.h \ + ../include/ArACTS.h ../include/ArPTZ.h ../include/ArPTZConnector.h \ + ../include/ArActionDeceleratingLimiter.h \ + ../include/ArActionLimiterForwards.h \ + ../include/ArActionLimiterBackwards.h \ + ../include/ArActionLimiterTableSensor.h ../include/ArActionBumpers.h \ + ../include/ArActionIRs.h ../include/ArActionStallRecover.h \ + ../include/ArActionAvoidFront.h ../include/ArActionAvoidSide.h \ + ../include/ArActionConstantVelocity.h ../include/ArActionInput.h \ + ../include/ArActionRobotJoydrive.h ../include/ArActionJoydrive.h \ + ../include/ArActionKeydrive.h ../include/ArActionTriangleDriveTo.h \ + ../include/ArLineFinder.h ../include/ArActionTurn.h \ + ../include/ArActionRatioInput.h ../include/ArActionStop.h \ + ../include/ArActionGoto.h ../include/ArModule.h \ + ../include/ArModuleLoader.h ../include/ArRecurrentTask.h \ + ../include/ArGripper.h ../include/ArSonyPTZ.h ../include/ArRVisionPTZ.h \ + ../include/ArAMPTU.h ../include/ArP2Arm.h ../include/ArSick.h \ + ../include/ArLaser.h ../include/ArRangeDeviceThreaded.h \ + ../include/ArFunctorASyncTask.h ../include/ArLMS2xx.h \ + ../include/ArLMS2xxPacket.h ../include/ArLMS2xxPacketReceiver.h \ + ../include/ArLaserLogger.h ../include/ArIrrfDevice.h \ + ../include/ArDPPTU.h ../include/ArVCC4.h ../include/ArMode.h \ + ../include/ArModes.h ../include/ArTCMCompassRobot.h ../include/ArTCM2.h \ + ../include/ArNetServer.h ../include/ArSignalHandler.h \ + ../include/ArAnalogGyro.h ../include/ArMapInterface.h \ + ../include/ArMapObject.h ../include/ArMapUtils.h ../include/ArMap.h \ + ../include/ArMapComponents.h ../include/ArBumpers.h ../include/ArIRs.h \ + ../include/ArForbiddenRangeDevice.h ../include/ArVersalogicIO.h \ + ../include/ArMTXIO.h ../include/ArActionGotoStraight.h \ + ../include/ArDataLogger.h ../include/ArRobotJoyHandler.h \ + ../include/ArRatioInputKeydrive.h ../include/ArRatioInputJoydrive.h \ + ../include/ArRatioInputRobotJoydrive.h \ + ../include/ArActionMovementParameters.h ../include/ArSoundPlayer.h \ + ../include/ArSoundsQueue.h ../include/ArSpeech.h \ + ../include/ArCameraCollection.h ../include/ArCameraCommands.h \ + ../include/ArSonarAutoDisabler.h ../include/ArActionDriveDistance.h \ + ../include/ArLaserReflectorDevice.h ../include/ArRobotConfig.h \ + ../include/ArTCMCompassDirect.h ../include/ArNMEAParser.h \ + ../include/ArLaserFilter.h ../include/ArUrg.h ../include/ArGPS.h \ + ../include/ArTrimbleGPS.h ../include/ArNovatelGPS.h \ + ../include/ArGPSCoords.h ../include/ArSonarConnector.h \ + ../include/ArBatteryConnector.h ../include/ArLCDConnector.h \ + ../include/ArSonarMTX.h ../include/ArBatteryMTX.h ../include/ArLCDMTX.h \ + ../include/ArSimulatedLaser.h ../include/ArExitErrorSource.h \ + ../include/ArActionLimiterRot.h ../include/ArRobotBatteryPacketReader.h \ + ../include/ArLMS1XX.h ../include/ArUrg_2_0.h \ + ../include/ArActionMovementParametersDebugging.h ../include/ArZippable.h \ + ../include/ArS3Series.h ../include/ArSZSeries.h ../include/ArExport.h \ + include/ArServerHandlerCameraCollection.h ../include/ArFunctor.h \ + ../include/ArCameraCollection.h include/ArServerBase.h \ + include/ArServerCommands.h include/ArServerClient.h \ + include/ArNetPacket.h include/ArNetPacketReceiverTcp.h \ + include/ArNetPacketSenderTcp.h include/ArServerClientData.h \ + include/ArServerClientIdentifier.h include/ArServerData.h \ + include/ArNetPacketReceiverUdp.h include/ArServerUserInfo.h \ + ../include/ArConfigArg.h include/ArClientArgUtils.h +../obj/ArServerHandlerCommMonitor.o: src/ArServerHandlerCommMonitor.cpp \ + ../include/Aria.h ../include/ariaOSDef.h ../include/ariaTypedefs.h \ + ../include/ArSerialConnection.h ../include/ArDeviceConnection.h \ + ../include/ariaUtil.h ../include/ArLog.h ../include/ArMutex.h \ + ../include/ArFunctor.h ../include/ArArgumentParser.h \ + ../include/ArArgumentBuilder.h ../include/ArBasePacket.h \ + ../include/ArTcpConnection.h ../include/ArSocket.h \ + ../include/ArSimpleConnector.h ../include/ArRobotConnector.h \ + ../include/ArLaserConnector.h ../include/ArLogFileConnection.h \ + ../include/ArRobotPacket.h ../include/ArRobotPacketSender.h \ + ../include/ArRobotPacketReceiver.h \ + ../include/ArRobotConfigPacketReader.h ../include/ArRobotTypes.h \ + ../include/ArRobotParams.h ../include/ArConfig.h \ + ../include/ArConfigArg.h ../include/ArFileParser.h \ + ../include/ArHasFileName.h ../include/ArConfigGroup.h \ + ../include/ArRobot.h ../include/ArSyncTask.h ../include/ArTaskState.h \ + ../include/ArSensorReading.h ../include/ArTransform.h \ + ../include/ArCondition.h ../include/ArSyncLoop.h \ + ../include/ArASyncTask.h ../include/ArThread.h \ + ../include/ArRobotPacketReaderThread.h ../include/ArActionDesired.h \ + ../include/ArResolver.h ../include/ArInterpolation.h \ + ../include/ArKeyHandler.h ../include/ArCommands.h \ + ../include/ArJoyHandler.h ../include/ariaInternal.h \ + ../include/ArStringInfoGroup.h ../include/ArSonarDevice.h \ + ../include/ArRangeDevice.h ../include/ArRangeBuffer.h \ + ../include/ArDrawingData.h ../include/ArPriorityResolver.h \ + ../include/ArAction.h ../include/ArArg.h ../include/ArActionGroup.h \ + ../include/ArActionGroups.h ../include/ArActionColorFollow.h \ + ../include/ArACTS.h ../include/ArPTZ.h ../include/ArPTZConnector.h \ + ../include/ArActionDeceleratingLimiter.h \ + ../include/ArActionLimiterForwards.h \ + ../include/ArActionLimiterBackwards.h \ + ../include/ArActionLimiterTableSensor.h ../include/ArActionBumpers.h \ + ../include/ArActionIRs.h ../include/ArActionStallRecover.h \ + ../include/ArActionAvoidFront.h ../include/ArActionAvoidSide.h \ + ../include/ArActionConstantVelocity.h ../include/ArActionInput.h \ + ../include/ArActionRobotJoydrive.h ../include/ArActionJoydrive.h \ + ../include/ArActionKeydrive.h ../include/ArActionTriangleDriveTo.h \ + ../include/ArLineFinder.h ../include/ArActionTurn.h \ + ../include/ArActionRatioInput.h ../include/ArActionStop.h \ + ../include/ArActionGoto.h ../include/ArModule.h \ + ../include/ArModuleLoader.h ../include/ArRecurrentTask.h \ + ../include/ArGripper.h ../include/ArSonyPTZ.h ../include/ArRVisionPTZ.h \ + ../include/ArAMPTU.h ../include/ArP2Arm.h ../include/ArSick.h \ + ../include/ArLaser.h ../include/ArRangeDeviceThreaded.h \ + ../include/ArFunctorASyncTask.h ../include/ArLMS2xx.h \ + ../include/ArLMS2xxPacket.h ../include/ArLMS2xxPacketReceiver.h \ + ../include/ArLaserLogger.h ../include/ArIrrfDevice.h \ + ../include/ArDPPTU.h ../include/ArVCC4.h ../include/ArMode.h \ + ../include/ArModes.h ../include/ArTCMCompassRobot.h ../include/ArTCM2.h \ + ../include/ArNetServer.h ../include/ArSignalHandler.h \ + ../include/ArAnalogGyro.h ../include/ArMapInterface.h \ + ../include/ArMapObject.h ../include/ArMapUtils.h ../include/ArMap.h \ + ../include/ArMapComponents.h ../include/ArBumpers.h ../include/ArIRs.h \ + ../include/ArForbiddenRangeDevice.h ../include/ArVersalogicIO.h \ + ../include/ArMTXIO.h ../include/ArActionGotoStraight.h \ + ../include/ArDataLogger.h ../include/ArRobotJoyHandler.h \ + ../include/ArRatioInputKeydrive.h ../include/ArRatioInputJoydrive.h \ + ../include/ArRatioInputRobotJoydrive.h \ + ../include/ArActionMovementParameters.h ../include/ArSoundPlayer.h \ + ../include/ArSoundsQueue.h ../include/ArSpeech.h \ + ../include/ArCameraCollection.h ../include/ArCameraCommands.h \ + ../include/ArSonarAutoDisabler.h ../include/ArActionDriveDistance.h \ + ../include/ArLaserReflectorDevice.h ../include/ArRobotConfig.h \ + ../include/ArTCMCompassDirect.h ../include/ArNMEAParser.h \ + ../include/ArLaserFilter.h ../include/ArUrg.h ../include/ArGPS.h \ + ../include/ArTrimbleGPS.h ../include/ArNovatelGPS.h \ + ../include/ArGPSCoords.h ../include/ArSonarConnector.h \ + ../include/ArBatteryConnector.h ../include/ArLCDConnector.h \ + ../include/ArSonarMTX.h ../include/ArBatteryMTX.h ../include/ArLCDMTX.h \ + ../include/ArSimulatedLaser.h ../include/ArExitErrorSource.h \ + ../include/ArActionLimiterRot.h ../include/ArRobotBatteryPacketReader.h \ + ../include/ArLMS1XX.h ../include/ArUrg_2_0.h \ + ../include/ArActionMovementParametersDebugging.h ../include/ArZippable.h \ + ../include/ArS3Series.h ../include/ArSZSeries.h ../include/ArExport.h \ + include/ArServerHandlerCommMonitor.h include/ArNetworking.h \ + include/ArServerBase.h include/ArServerCommands.h \ + include/ArServerClient.h include/ArNetPacket.h \ + include/ArNetPacketReceiverTcp.h include/ArNetPacketSenderTcp.h \ + include/ArServerClientData.h include/ArServerClientIdentifier.h \ + include/ArServerData.h include/ArNetPacketReceiverUdp.h \ + include/ArServerUserInfo.h include/ArClientBase.h \ + include/ArClientCommands.h include/ArClientData.h include/ArMapChanger.h \ + ../include/ariaTypedefs.h ../include/ariaUtil.h \ + ../include/ArMapInterface.h ../include/ArMapUtils.h ../include/ArMutex.h \ + include/ArCentralForwarder.h include/ArClientSwitchManager.h \ + include/ArServerHandlerCamera.h \ + include/ArServerHandlerCameraCollection.h ../include/ArFunctor.h \ + ../include/ArCameraCollection.h include/ArServerHandlerCommMonitor.h \ + include/ArServerHandlerCommands.h include/ArServerHandlerPopup.h \ + include/ArServerInfoDrawings.h include/ArServerInfoRobot.h \ + include/ArServerInfoSensor.h include/ArServerHandlerMap.h \ + ../include/ArConfig.h include/ArServerMode.h include/ArServerModeDrive.h \ + include/ArServerModeRatioDrive.h include/ArServerModeStop.h \ + include/ArServerModeWander.h include/ArServerHandlerConfig.h \ + include/ArClientHandlerConfig.h include/ArHybridForwarderVideo.h \ + include/ArServerSimpleCommands.h include/ArServerFileUtils.h \ + include/ArClientFileUtils.h include/ArClientSimpleConnector.h \ + include/ArServerHandlerMapping.h include/ArTempDirectoryHelper.h \ + include/ArServerSimpleOpener.h include/ArServerInfoStrings.h \ + include/ArClientArgUtils.h include/ArCentralManager.h \ + include/ArServerModeIdle.h +../obj/ArServerHandlerCommands.o: src/ArServerHandlerCommands.cpp \ + ../include/Aria.h ../include/ariaOSDef.h ../include/ariaTypedefs.h \ + ../include/ArSerialConnection.h ../include/ArDeviceConnection.h \ + ../include/ariaUtil.h ../include/ArLog.h ../include/ArMutex.h \ + ../include/ArFunctor.h ../include/ArArgumentParser.h \ + ../include/ArArgumentBuilder.h ../include/ArBasePacket.h \ + ../include/ArTcpConnection.h ../include/ArSocket.h \ + ../include/ArSimpleConnector.h ../include/ArRobotConnector.h \ + ../include/ArLaserConnector.h ../include/ArLogFileConnection.h \ + ../include/ArRobotPacket.h ../include/ArRobotPacketSender.h \ + ../include/ArRobotPacketReceiver.h \ + ../include/ArRobotConfigPacketReader.h ../include/ArRobotTypes.h \ + ../include/ArRobotParams.h ../include/ArConfig.h \ + ../include/ArConfigArg.h ../include/ArFileParser.h \ + ../include/ArHasFileName.h ../include/ArConfigGroup.h \ + ../include/ArRobot.h ../include/ArSyncTask.h ../include/ArTaskState.h \ + ../include/ArSensorReading.h ../include/ArTransform.h \ + ../include/ArCondition.h ../include/ArSyncLoop.h \ + ../include/ArASyncTask.h ../include/ArThread.h \ + ../include/ArRobotPacketReaderThread.h ../include/ArActionDesired.h \ + ../include/ArResolver.h ../include/ArInterpolation.h \ + ../include/ArKeyHandler.h ../include/ArCommands.h \ + ../include/ArJoyHandler.h ../include/ariaInternal.h \ + ../include/ArStringInfoGroup.h ../include/ArSonarDevice.h \ + ../include/ArRangeDevice.h ../include/ArRangeBuffer.h \ + ../include/ArDrawingData.h ../include/ArPriorityResolver.h \ + ../include/ArAction.h ../include/ArArg.h ../include/ArActionGroup.h \ + ../include/ArActionGroups.h ../include/ArActionColorFollow.h \ + ../include/ArACTS.h ../include/ArPTZ.h ../include/ArPTZConnector.h \ + ../include/ArActionDeceleratingLimiter.h \ + ../include/ArActionLimiterForwards.h \ + ../include/ArActionLimiterBackwards.h \ + ../include/ArActionLimiterTableSensor.h ../include/ArActionBumpers.h \ + ../include/ArActionIRs.h ../include/ArActionStallRecover.h \ + ../include/ArActionAvoidFront.h ../include/ArActionAvoidSide.h \ + ../include/ArActionConstantVelocity.h ../include/ArActionInput.h \ + ../include/ArActionRobotJoydrive.h ../include/ArActionJoydrive.h \ + ../include/ArActionKeydrive.h ../include/ArActionTriangleDriveTo.h \ + ../include/ArLineFinder.h ../include/ArActionTurn.h \ + ../include/ArActionRatioInput.h ../include/ArActionStop.h \ + ../include/ArActionGoto.h ../include/ArModule.h \ + ../include/ArModuleLoader.h ../include/ArRecurrentTask.h \ + ../include/ArGripper.h ../include/ArSonyPTZ.h ../include/ArRVisionPTZ.h \ + ../include/ArAMPTU.h ../include/ArP2Arm.h ../include/ArSick.h \ + ../include/ArLaser.h ../include/ArRangeDeviceThreaded.h \ + ../include/ArFunctorASyncTask.h ../include/ArLMS2xx.h \ + ../include/ArLMS2xxPacket.h ../include/ArLMS2xxPacketReceiver.h \ + ../include/ArLaserLogger.h ../include/ArIrrfDevice.h \ + ../include/ArDPPTU.h ../include/ArVCC4.h ../include/ArMode.h \ + ../include/ArModes.h ../include/ArTCMCompassRobot.h ../include/ArTCM2.h \ + ../include/ArNetServer.h ../include/ArSignalHandler.h \ + ../include/ArAnalogGyro.h ../include/ArMapInterface.h \ + ../include/ArMapObject.h ../include/ArMapUtils.h ../include/ArMap.h \ + ../include/ArMapComponents.h ../include/ArBumpers.h ../include/ArIRs.h \ + ../include/ArForbiddenRangeDevice.h ../include/ArVersalogicIO.h \ + ../include/ArMTXIO.h ../include/ArActionGotoStraight.h \ + ../include/ArDataLogger.h ../include/ArRobotJoyHandler.h \ + ../include/ArRatioInputKeydrive.h ../include/ArRatioInputJoydrive.h \ + ../include/ArRatioInputRobotJoydrive.h \ + ../include/ArActionMovementParameters.h ../include/ArSoundPlayer.h \ + ../include/ArSoundsQueue.h ../include/ArSpeech.h \ + ../include/ArCameraCollection.h ../include/ArCameraCommands.h \ + ../include/ArSonarAutoDisabler.h ../include/ArActionDriveDistance.h \ + ../include/ArLaserReflectorDevice.h ../include/ArRobotConfig.h \ + ../include/ArTCMCompassDirect.h ../include/ArNMEAParser.h \ + ../include/ArLaserFilter.h ../include/ArUrg.h ../include/ArGPS.h \ + ../include/ArTrimbleGPS.h ../include/ArNovatelGPS.h \ + ../include/ArGPSCoords.h ../include/ArSonarConnector.h \ + ../include/ArBatteryConnector.h ../include/ArLCDConnector.h \ + ../include/ArSonarMTX.h ../include/ArBatteryMTX.h ../include/ArLCDMTX.h \ + ../include/ArSimulatedLaser.h ../include/ArExitErrorSource.h \ + ../include/ArActionLimiterRot.h ../include/ArRobotBatteryPacketReader.h \ + ../include/ArLMS1XX.h ../include/ArUrg_2_0.h \ + ../include/ArActionMovementParametersDebugging.h ../include/ArZippable.h \ + ../include/ArS3Series.h ../include/ArSZSeries.h ../include/ArExport.h \ + include/ArServerHandlerCommands.h include/ArServerBase.h \ + include/ArServerCommands.h include/ArServerClient.h \ + include/ArNetPacket.h include/ArNetPacketReceiverTcp.h \ + include/ArNetPacketSenderTcp.h include/ArServerClientData.h \ + include/ArServerClientIdentifier.h include/ArServerData.h \ + include/ArNetPacketReceiverUdp.h include/ArServerUserInfo.h +../obj/ArServerHandlerConfig.o: src/ArServerHandlerConfig.cpp ../include/Aria.h \ + ../include/ariaOSDef.h ../include/ariaTypedefs.h \ + ../include/ArSerialConnection.h ../include/ArDeviceConnection.h \ + ../include/ariaUtil.h ../include/ArLog.h ../include/ArMutex.h \ + ../include/ArFunctor.h ../include/ArArgumentParser.h \ + ../include/ArArgumentBuilder.h ../include/ArBasePacket.h \ + ../include/ArTcpConnection.h ../include/ArSocket.h \ + ../include/ArSimpleConnector.h ../include/ArRobotConnector.h \ + ../include/ArLaserConnector.h ../include/ArLogFileConnection.h \ + ../include/ArRobotPacket.h ../include/ArRobotPacketSender.h \ + ../include/ArRobotPacketReceiver.h \ + ../include/ArRobotConfigPacketReader.h ../include/ArRobotTypes.h \ + ../include/ArRobotParams.h ../include/ArConfig.h \ + ../include/ArConfigArg.h ../include/ArFileParser.h \ + ../include/ArHasFileName.h ../include/ArConfigGroup.h \ + ../include/ArRobot.h ../include/ArSyncTask.h ../include/ArTaskState.h \ + ../include/ArSensorReading.h ../include/ArTransform.h \ + ../include/ArCondition.h ../include/ArSyncLoop.h \ + ../include/ArASyncTask.h ../include/ArThread.h \ + ../include/ArRobotPacketReaderThread.h ../include/ArActionDesired.h \ + ../include/ArResolver.h ../include/ArInterpolation.h \ + ../include/ArKeyHandler.h ../include/ArCommands.h \ + ../include/ArJoyHandler.h ../include/ariaInternal.h \ + ../include/ArStringInfoGroup.h ../include/ArSonarDevice.h \ + ../include/ArRangeDevice.h ../include/ArRangeBuffer.h \ + ../include/ArDrawingData.h ../include/ArPriorityResolver.h \ + ../include/ArAction.h ../include/ArArg.h ../include/ArActionGroup.h \ + ../include/ArActionGroups.h ../include/ArActionColorFollow.h \ + ../include/ArACTS.h ../include/ArPTZ.h ../include/ArPTZConnector.h \ + ../include/ArActionDeceleratingLimiter.h \ + ../include/ArActionLimiterForwards.h \ + ../include/ArActionLimiterBackwards.h \ + ../include/ArActionLimiterTableSensor.h ../include/ArActionBumpers.h \ + ../include/ArActionIRs.h ../include/ArActionStallRecover.h \ + ../include/ArActionAvoidFront.h ../include/ArActionAvoidSide.h \ + ../include/ArActionConstantVelocity.h ../include/ArActionInput.h \ + ../include/ArActionRobotJoydrive.h ../include/ArActionJoydrive.h \ + ../include/ArActionKeydrive.h ../include/ArActionTriangleDriveTo.h \ + ../include/ArLineFinder.h ../include/ArActionTurn.h \ + ../include/ArActionRatioInput.h ../include/ArActionStop.h \ + ../include/ArActionGoto.h ../include/ArModule.h \ + ../include/ArModuleLoader.h ../include/ArRecurrentTask.h \ + ../include/ArGripper.h ../include/ArSonyPTZ.h ../include/ArRVisionPTZ.h \ + ../include/ArAMPTU.h ../include/ArP2Arm.h ../include/ArSick.h \ + ../include/ArLaser.h ../include/ArRangeDeviceThreaded.h \ + ../include/ArFunctorASyncTask.h ../include/ArLMS2xx.h \ + ../include/ArLMS2xxPacket.h ../include/ArLMS2xxPacketReceiver.h \ + ../include/ArLaserLogger.h ../include/ArIrrfDevice.h \ + ../include/ArDPPTU.h ../include/ArVCC4.h ../include/ArMode.h \ + ../include/ArModes.h ../include/ArTCMCompassRobot.h ../include/ArTCM2.h \ + ../include/ArNetServer.h ../include/ArSignalHandler.h \ + ../include/ArAnalogGyro.h ../include/ArMapInterface.h \ + ../include/ArMapObject.h ../include/ArMapUtils.h ../include/ArMap.h \ + ../include/ArMapComponents.h ../include/ArBumpers.h ../include/ArIRs.h \ + ../include/ArForbiddenRangeDevice.h ../include/ArVersalogicIO.h \ + ../include/ArMTXIO.h ../include/ArActionGotoStraight.h \ + ../include/ArDataLogger.h ../include/ArRobotJoyHandler.h \ + ../include/ArRatioInputKeydrive.h ../include/ArRatioInputJoydrive.h \ + ../include/ArRatioInputRobotJoydrive.h \ + ../include/ArActionMovementParameters.h ../include/ArSoundPlayer.h \ + ../include/ArSoundsQueue.h ../include/ArSpeech.h \ + ../include/ArCameraCollection.h ../include/ArCameraCommands.h \ + ../include/ArSonarAutoDisabler.h ../include/ArActionDriveDistance.h \ + ../include/ArLaserReflectorDevice.h ../include/ArRobotConfig.h \ + ../include/ArTCMCompassDirect.h ../include/ArNMEAParser.h \ + ../include/ArLaserFilter.h ../include/ArUrg.h ../include/ArGPS.h \ + ../include/ArTrimbleGPS.h ../include/ArNovatelGPS.h \ + ../include/ArGPSCoords.h ../include/ArSonarConnector.h \ + ../include/ArBatteryConnector.h ../include/ArLCDConnector.h \ + ../include/ArSonarMTX.h ../include/ArBatteryMTX.h ../include/ArLCDMTX.h \ + ../include/ArSimulatedLaser.h ../include/ArExitErrorSource.h \ + ../include/ArActionLimiterRot.h ../include/ArRobotBatteryPacketReader.h \ + ../include/ArLMS1XX.h ../include/ArUrg_2_0.h \ + ../include/ArActionMovementParametersDebugging.h ../include/ArZippable.h \ + ../include/ArS3Series.h ../include/ArSZSeries.h ../include/ArExport.h \ + include/ArServerHandlerConfig.h include/ArServerBase.h \ + include/ArServerCommands.h include/ArServerClient.h \ + include/ArNetPacket.h include/ArNetPacketReceiverTcp.h \ + include/ArNetPacketSenderTcp.h include/ArServerClientData.h \ + include/ArServerClientIdentifier.h include/ArServerData.h \ + include/ArNetPacketReceiverUdp.h include/ArServerUserInfo.h \ + include/ArClientArgUtils.h +../obj/ArServerHandlerMap.o: src/ArServerHandlerMap.cpp ../include/Aria.h \ + ../include/ariaOSDef.h ../include/ariaTypedefs.h \ + ../include/ArSerialConnection.h ../include/ArDeviceConnection.h \ + ../include/ariaUtil.h ../include/ArLog.h ../include/ArMutex.h \ + ../include/ArFunctor.h ../include/ArArgumentParser.h \ + ../include/ArArgumentBuilder.h ../include/ArBasePacket.h \ + ../include/ArTcpConnection.h ../include/ArSocket.h \ + ../include/ArSimpleConnector.h ../include/ArRobotConnector.h \ + ../include/ArLaserConnector.h ../include/ArLogFileConnection.h \ + ../include/ArRobotPacket.h ../include/ArRobotPacketSender.h \ + ../include/ArRobotPacketReceiver.h \ + ../include/ArRobotConfigPacketReader.h ../include/ArRobotTypes.h \ + ../include/ArRobotParams.h ../include/ArConfig.h \ + ../include/ArConfigArg.h ../include/ArFileParser.h \ + ../include/ArHasFileName.h ../include/ArConfigGroup.h \ + ../include/ArRobot.h ../include/ArSyncTask.h ../include/ArTaskState.h \ + ../include/ArSensorReading.h ../include/ArTransform.h \ + ../include/ArCondition.h ../include/ArSyncLoop.h \ + ../include/ArASyncTask.h ../include/ArThread.h \ + ../include/ArRobotPacketReaderThread.h ../include/ArActionDesired.h \ + ../include/ArResolver.h ../include/ArInterpolation.h \ + ../include/ArKeyHandler.h ../include/ArCommands.h \ + ../include/ArJoyHandler.h ../include/ariaInternal.h \ + ../include/ArStringInfoGroup.h ../include/ArSonarDevice.h \ + ../include/ArRangeDevice.h ../include/ArRangeBuffer.h \ + ../include/ArDrawingData.h ../include/ArPriorityResolver.h \ + ../include/ArAction.h ../include/ArArg.h ../include/ArActionGroup.h \ + ../include/ArActionGroups.h ../include/ArActionColorFollow.h \ + ../include/ArACTS.h ../include/ArPTZ.h ../include/ArPTZConnector.h \ + ../include/ArActionDeceleratingLimiter.h \ + ../include/ArActionLimiterForwards.h \ + ../include/ArActionLimiterBackwards.h \ + ../include/ArActionLimiterTableSensor.h ../include/ArActionBumpers.h \ + ../include/ArActionIRs.h ../include/ArActionStallRecover.h \ + ../include/ArActionAvoidFront.h ../include/ArActionAvoidSide.h \ + ../include/ArActionConstantVelocity.h ../include/ArActionInput.h \ + ../include/ArActionRobotJoydrive.h ../include/ArActionJoydrive.h \ + ../include/ArActionKeydrive.h ../include/ArActionTriangleDriveTo.h \ + ../include/ArLineFinder.h ../include/ArActionTurn.h \ + ../include/ArActionRatioInput.h ../include/ArActionStop.h \ + ../include/ArActionGoto.h ../include/ArModule.h \ + ../include/ArModuleLoader.h ../include/ArRecurrentTask.h \ + ../include/ArGripper.h ../include/ArSonyPTZ.h ../include/ArRVisionPTZ.h \ + ../include/ArAMPTU.h ../include/ArP2Arm.h ../include/ArSick.h \ + ../include/ArLaser.h ../include/ArRangeDeviceThreaded.h \ + ../include/ArFunctorASyncTask.h ../include/ArLMS2xx.h \ + ../include/ArLMS2xxPacket.h ../include/ArLMS2xxPacketReceiver.h \ + ../include/ArLaserLogger.h ../include/ArIrrfDevice.h \ + ../include/ArDPPTU.h ../include/ArVCC4.h ../include/ArMode.h \ + ../include/ArModes.h ../include/ArTCMCompassRobot.h ../include/ArTCM2.h \ + ../include/ArNetServer.h ../include/ArSignalHandler.h \ + ../include/ArAnalogGyro.h ../include/ArMapInterface.h \ + ../include/ArMapObject.h ../include/ArMapUtils.h ../include/ArMap.h \ + ../include/ArMapComponents.h ../include/ArBumpers.h ../include/ArIRs.h \ + ../include/ArForbiddenRangeDevice.h ../include/ArVersalogicIO.h \ + ../include/ArMTXIO.h ../include/ArActionGotoStraight.h \ + ../include/ArDataLogger.h ../include/ArRobotJoyHandler.h \ + ../include/ArRatioInputKeydrive.h ../include/ArRatioInputJoydrive.h \ + ../include/ArRatioInputRobotJoydrive.h \ + ../include/ArActionMovementParameters.h ../include/ArSoundPlayer.h \ + ../include/ArSoundsQueue.h ../include/ArSpeech.h \ + ../include/ArCameraCollection.h ../include/ArCameraCommands.h \ + ../include/ArSonarAutoDisabler.h ../include/ArActionDriveDistance.h \ + ../include/ArLaserReflectorDevice.h ../include/ArRobotConfig.h \ + ../include/ArTCMCompassDirect.h ../include/ArNMEAParser.h \ + ../include/ArLaserFilter.h ../include/ArUrg.h ../include/ArGPS.h \ + ../include/ArTrimbleGPS.h ../include/ArNovatelGPS.h \ + ../include/ArGPSCoords.h ../include/ArSonarConnector.h \ + ../include/ArBatteryConnector.h ../include/ArLCDConnector.h \ + ../include/ArSonarMTX.h ../include/ArBatteryMTX.h ../include/ArLCDMTX.h \ + ../include/ArSimulatedLaser.h ../include/ArExitErrorSource.h \ + ../include/ArActionLimiterRot.h ../include/ArRobotBatteryPacketReader.h \ + ../include/ArLMS1XX.h ../include/ArUrg_2_0.h \ + ../include/ArActionMovementParametersDebugging.h ../include/ArZippable.h \ + ../include/ArS3Series.h ../include/ArSZSeries.h ../include/ArExport.h \ + include/ArServerHandlerMap.h include/ArServerBase.h \ + include/ArServerCommands.h include/ArServerClient.h \ + include/ArNetPacket.h include/ArNetPacketReceiverTcp.h \ + include/ArNetPacketSenderTcp.h include/ArServerClientData.h \ + include/ArServerClientIdentifier.h include/ArServerData.h \ + include/ArNetPacketReceiverUdp.h include/ArServerUserInfo.h \ + ../include/ArConfig.h ../include/ArMap.h +../obj/ArServerHandlerMapping.o: src/ArServerHandlerMapping.cpp \ + ../include/Aria.h ../include/ariaOSDef.h ../include/ariaTypedefs.h \ + ../include/ArSerialConnection.h ../include/ArDeviceConnection.h \ + ../include/ariaUtil.h ../include/ArLog.h ../include/ArMutex.h \ + ../include/ArFunctor.h ../include/ArArgumentParser.h \ + ../include/ArArgumentBuilder.h ../include/ArBasePacket.h \ + ../include/ArTcpConnection.h ../include/ArSocket.h \ + ../include/ArSimpleConnector.h ../include/ArRobotConnector.h \ + ../include/ArLaserConnector.h ../include/ArLogFileConnection.h \ + ../include/ArRobotPacket.h ../include/ArRobotPacketSender.h \ + ../include/ArRobotPacketReceiver.h \ + ../include/ArRobotConfigPacketReader.h ../include/ArRobotTypes.h \ + ../include/ArRobotParams.h ../include/ArConfig.h \ + ../include/ArConfigArg.h ../include/ArFileParser.h \ + ../include/ArHasFileName.h ../include/ArConfigGroup.h \ + ../include/ArRobot.h ../include/ArSyncTask.h ../include/ArTaskState.h \ + ../include/ArSensorReading.h ../include/ArTransform.h \ + ../include/ArCondition.h ../include/ArSyncLoop.h \ + ../include/ArASyncTask.h ../include/ArThread.h \ + ../include/ArRobotPacketReaderThread.h ../include/ArActionDesired.h \ + ../include/ArResolver.h ../include/ArInterpolation.h \ + ../include/ArKeyHandler.h ../include/ArCommands.h \ + ../include/ArJoyHandler.h ../include/ariaInternal.h \ + ../include/ArStringInfoGroup.h ../include/ArSonarDevice.h \ + ../include/ArRangeDevice.h ../include/ArRangeBuffer.h \ + ../include/ArDrawingData.h ../include/ArPriorityResolver.h \ + ../include/ArAction.h ../include/ArArg.h ../include/ArActionGroup.h \ + ../include/ArActionGroups.h ../include/ArActionColorFollow.h \ + ../include/ArACTS.h ../include/ArPTZ.h ../include/ArPTZConnector.h \ + ../include/ArActionDeceleratingLimiter.h \ + ../include/ArActionLimiterForwards.h \ + ../include/ArActionLimiterBackwards.h \ + ../include/ArActionLimiterTableSensor.h ../include/ArActionBumpers.h \ + ../include/ArActionIRs.h ../include/ArActionStallRecover.h \ + ../include/ArActionAvoidFront.h ../include/ArActionAvoidSide.h \ + ../include/ArActionConstantVelocity.h ../include/ArActionInput.h \ + ../include/ArActionRobotJoydrive.h ../include/ArActionJoydrive.h \ + ../include/ArActionKeydrive.h ../include/ArActionTriangleDriveTo.h \ + ../include/ArLineFinder.h ../include/ArActionTurn.h \ + ../include/ArActionRatioInput.h ../include/ArActionStop.h \ + ../include/ArActionGoto.h ../include/ArModule.h \ + ../include/ArModuleLoader.h ../include/ArRecurrentTask.h \ + ../include/ArGripper.h ../include/ArSonyPTZ.h ../include/ArRVisionPTZ.h \ + ../include/ArAMPTU.h ../include/ArP2Arm.h ../include/ArSick.h \ + ../include/ArLaser.h ../include/ArRangeDeviceThreaded.h \ + ../include/ArFunctorASyncTask.h ../include/ArLMS2xx.h \ + ../include/ArLMS2xxPacket.h ../include/ArLMS2xxPacketReceiver.h \ + ../include/ArLaserLogger.h ../include/ArIrrfDevice.h \ + ../include/ArDPPTU.h ../include/ArVCC4.h ../include/ArMode.h \ + ../include/ArModes.h ../include/ArTCMCompassRobot.h ../include/ArTCM2.h \ + ../include/ArNetServer.h ../include/ArSignalHandler.h \ + ../include/ArAnalogGyro.h ../include/ArMapInterface.h \ + ../include/ArMapObject.h ../include/ArMapUtils.h ../include/ArMap.h \ + ../include/ArMapComponents.h ../include/ArBumpers.h ../include/ArIRs.h \ + ../include/ArForbiddenRangeDevice.h ../include/ArVersalogicIO.h \ + ../include/ArMTXIO.h ../include/ArActionGotoStraight.h \ + ../include/ArDataLogger.h ../include/ArRobotJoyHandler.h \ + ../include/ArRatioInputKeydrive.h ../include/ArRatioInputJoydrive.h \ + ../include/ArRatioInputRobotJoydrive.h \ + ../include/ArActionMovementParameters.h ../include/ArSoundPlayer.h \ + ../include/ArSoundsQueue.h ../include/ArSpeech.h \ + ../include/ArCameraCollection.h ../include/ArCameraCommands.h \ + ../include/ArSonarAutoDisabler.h ../include/ArActionDriveDistance.h \ + ../include/ArLaserReflectorDevice.h ../include/ArRobotConfig.h \ + ../include/ArTCMCompassDirect.h ../include/ArNMEAParser.h \ + ../include/ArLaserFilter.h ../include/ArUrg.h ../include/ArGPS.h \ + ../include/ArTrimbleGPS.h ../include/ArNovatelGPS.h \ + ../include/ArGPSCoords.h ../include/ArSonarConnector.h \ + ../include/ArBatteryConnector.h ../include/ArLCDConnector.h \ + ../include/ArSonarMTX.h ../include/ArBatteryMTX.h ../include/ArLCDMTX.h \ + ../include/ArSimulatedLaser.h ../include/ArExitErrorSource.h \ + ../include/ArActionLimiterRot.h ../include/ArRobotBatteryPacketReader.h \ + ../include/ArLMS1XX.h ../include/ArUrg_2_0.h \ + ../include/ArActionMovementParametersDebugging.h ../include/ArZippable.h \ + ../include/ArS3Series.h ../include/ArSZSeries.h ../include/ArExport.h \ + include/ArServerHandlerMapping.h include/ArServerBase.h \ + include/ArServerCommands.h include/ArServerClient.h \ + include/ArNetPacket.h include/ArNetPacketReceiverTcp.h \ + include/ArNetPacketSenderTcp.h include/ArServerClientData.h \ + include/ArServerClientIdentifier.h include/ArServerData.h \ + include/ArNetPacketReceiverUdp.h include/ArServerUserInfo.h \ + include/ArServerHandlerCommands.h include/ArTempDirectoryHelper.h \ + ../include/ariaTypedefs.h ../include/ArFunctor.h +../obj/ArServerHandlerPopup.o: src/ArServerHandlerPopup.cpp ../include/Aria.h \ + ../include/ariaOSDef.h ../include/ariaTypedefs.h \ + ../include/ArSerialConnection.h ../include/ArDeviceConnection.h \ + ../include/ariaUtil.h ../include/ArLog.h ../include/ArMutex.h \ + ../include/ArFunctor.h ../include/ArArgumentParser.h \ + ../include/ArArgumentBuilder.h ../include/ArBasePacket.h \ + ../include/ArTcpConnection.h ../include/ArSocket.h \ + ../include/ArSimpleConnector.h ../include/ArRobotConnector.h \ + ../include/ArLaserConnector.h ../include/ArLogFileConnection.h \ + ../include/ArRobotPacket.h ../include/ArRobotPacketSender.h \ + ../include/ArRobotPacketReceiver.h \ + ../include/ArRobotConfigPacketReader.h ../include/ArRobotTypes.h \ + ../include/ArRobotParams.h ../include/ArConfig.h \ + ../include/ArConfigArg.h ../include/ArFileParser.h \ + ../include/ArHasFileName.h ../include/ArConfigGroup.h \ + ../include/ArRobot.h ../include/ArSyncTask.h ../include/ArTaskState.h \ + ../include/ArSensorReading.h ../include/ArTransform.h \ + ../include/ArCondition.h ../include/ArSyncLoop.h \ + ../include/ArASyncTask.h ../include/ArThread.h \ + ../include/ArRobotPacketReaderThread.h ../include/ArActionDesired.h \ + ../include/ArResolver.h ../include/ArInterpolation.h \ + ../include/ArKeyHandler.h ../include/ArCommands.h \ + ../include/ArJoyHandler.h ../include/ariaInternal.h \ + ../include/ArStringInfoGroup.h ../include/ArSonarDevice.h \ + ../include/ArRangeDevice.h ../include/ArRangeBuffer.h \ + ../include/ArDrawingData.h ../include/ArPriorityResolver.h \ + ../include/ArAction.h ../include/ArArg.h ../include/ArActionGroup.h \ + ../include/ArActionGroups.h ../include/ArActionColorFollow.h \ + ../include/ArACTS.h ../include/ArPTZ.h ../include/ArPTZConnector.h \ + ../include/ArActionDeceleratingLimiter.h \ + ../include/ArActionLimiterForwards.h \ + ../include/ArActionLimiterBackwards.h \ + ../include/ArActionLimiterTableSensor.h ../include/ArActionBumpers.h \ + ../include/ArActionIRs.h ../include/ArActionStallRecover.h \ + ../include/ArActionAvoidFront.h ../include/ArActionAvoidSide.h \ + ../include/ArActionConstantVelocity.h ../include/ArActionInput.h \ + ../include/ArActionRobotJoydrive.h ../include/ArActionJoydrive.h \ + ../include/ArActionKeydrive.h ../include/ArActionTriangleDriveTo.h \ + ../include/ArLineFinder.h ../include/ArActionTurn.h \ + ../include/ArActionRatioInput.h ../include/ArActionStop.h \ + ../include/ArActionGoto.h ../include/ArModule.h \ + ../include/ArModuleLoader.h ../include/ArRecurrentTask.h \ + ../include/ArGripper.h ../include/ArSonyPTZ.h ../include/ArRVisionPTZ.h \ + ../include/ArAMPTU.h ../include/ArP2Arm.h ../include/ArSick.h \ + ../include/ArLaser.h ../include/ArRangeDeviceThreaded.h \ + ../include/ArFunctorASyncTask.h ../include/ArLMS2xx.h \ + ../include/ArLMS2xxPacket.h ../include/ArLMS2xxPacketReceiver.h \ + ../include/ArLaserLogger.h ../include/ArIrrfDevice.h \ + ../include/ArDPPTU.h ../include/ArVCC4.h ../include/ArMode.h \ + ../include/ArModes.h ../include/ArTCMCompassRobot.h ../include/ArTCM2.h \ + ../include/ArNetServer.h ../include/ArSignalHandler.h \ + ../include/ArAnalogGyro.h ../include/ArMapInterface.h \ + ../include/ArMapObject.h ../include/ArMapUtils.h ../include/ArMap.h \ + ../include/ArMapComponents.h ../include/ArBumpers.h ../include/ArIRs.h \ + ../include/ArForbiddenRangeDevice.h ../include/ArVersalogicIO.h \ + ../include/ArMTXIO.h ../include/ArActionGotoStraight.h \ + ../include/ArDataLogger.h ../include/ArRobotJoyHandler.h \ + ../include/ArRatioInputKeydrive.h ../include/ArRatioInputJoydrive.h \ + ../include/ArRatioInputRobotJoydrive.h \ + ../include/ArActionMovementParameters.h ../include/ArSoundPlayer.h \ + ../include/ArSoundsQueue.h ../include/ArSpeech.h \ + ../include/ArCameraCollection.h ../include/ArCameraCommands.h \ + ../include/ArSonarAutoDisabler.h ../include/ArActionDriveDistance.h \ + ../include/ArLaserReflectorDevice.h ../include/ArRobotConfig.h \ + ../include/ArTCMCompassDirect.h ../include/ArNMEAParser.h \ + ../include/ArLaserFilter.h ../include/ArUrg.h ../include/ArGPS.h \ + ../include/ArTrimbleGPS.h ../include/ArNovatelGPS.h \ + ../include/ArGPSCoords.h ../include/ArSonarConnector.h \ + ../include/ArBatteryConnector.h ../include/ArLCDConnector.h \ + ../include/ArSonarMTX.h ../include/ArBatteryMTX.h ../include/ArLCDMTX.h \ + ../include/ArSimulatedLaser.h ../include/ArExitErrorSource.h \ + ../include/ArActionLimiterRot.h ../include/ArRobotBatteryPacketReader.h \ + ../include/ArLMS1XX.h ../include/ArUrg_2_0.h \ + ../include/ArActionMovementParametersDebugging.h ../include/ArZippable.h \ + ../include/ArS3Series.h ../include/ArSZSeries.h ../include/ArExport.h \ + include/ArServerHandlerPopup.h include/ArServerBase.h \ + include/ArServerCommands.h include/ArServerClient.h \ + include/ArNetPacket.h include/ArNetPacketReceiverTcp.h \ + include/ArNetPacketSenderTcp.h include/ArServerClientData.h \ + include/ArServerClientIdentifier.h include/ArServerData.h \ + include/ArNetPacketReceiverUdp.h include/ArServerUserInfo.h +../obj/ArServerInfoDrawings.o: src/ArServerInfoDrawings.cpp ../include/Aria.h \ + ../include/ariaOSDef.h ../include/ariaTypedefs.h \ + ../include/ArSerialConnection.h ../include/ArDeviceConnection.h \ + ../include/ariaUtil.h ../include/ArLog.h ../include/ArMutex.h \ + ../include/ArFunctor.h ../include/ArArgumentParser.h \ + ../include/ArArgumentBuilder.h ../include/ArBasePacket.h \ + ../include/ArTcpConnection.h ../include/ArSocket.h \ + ../include/ArSimpleConnector.h ../include/ArRobotConnector.h \ + ../include/ArLaserConnector.h ../include/ArLogFileConnection.h \ + ../include/ArRobotPacket.h ../include/ArRobotPacketSender.h \ + ../include/ArRobotPacketReceiver.h \ + ../include/ArRobotConfigPacketReader.h ../include/ArRobotTypes.h \ + ../include/ArRobotParams.h ../include/ArConfig.h \ + ../include/ArConfigArg.h ../include/ArFileParser.h \ + ../include/ArHasFileName.h ../include/ArConfigGroup.h \ + ../include/ArRobot.h ../include/ArSyncTask.h ../include/ArTaskState.h \ + ../include/ArSensorReading.h ../include/ArTransform.h \ + ../include/ArCondition.h ../include/ArSyncLoop.h \ + ../include/ArASyncTask.h ../include/ArThread.h \ + ../include/ArRobotPacketReaderThread.h ../include/ArActionDesired.h \ + ../include/ArResolver.h ../include/ArInterpolation.h \ + ../include/ArKeyHandler.h ../include/ArCommands.h \ + ../include/ArJoyHandler.h ../include/ariaInternal.h \ + ../include/ArStringInfoGroup.h ../include/ArSonarDevice.h \ + ../include/ArRangeDevice.h ../include/ArRangeBuffer.h \ + ../include/ArDrawingData.h ../include/ArPriorityResolver.h \ + ../include/ArAction.h ../include/ArArg.h ../include/ArActionGroup.h \ + ../include/ArActionGroups.h ../include/ArActionColorFollow.h \ + ../include/ArACTS.h ../include/ArPTZ.h ../include/ArPTZConnector.h \ + ../include/ArActionDeceleratingLimiter.h \ + ../include/ArActionLimiterForwards.h \ + ../include/ArActionLimiterBackwards.h \ + ../include/ArActionLimiterTableSensor.h ../include/ArActionBumpers.h \ + ../include/ArActionIRs.h ../include/ArActionStallRecover.h \ + ../include/ArActionAvoidFront.h ../include/ArActionAvoidSide.h \ + ../include/ArActionConstantVelocity.h ../include/ArActionInput.h \ + ../include/ArActionRobotJoydrive.h ../include/ArActionJoydrive.h \ + ../include/ArActionKeydrive.h ../include/ArActionTriangleDriveTo.h \ + ../include/ArLineFinder.h ../include/ArActionTurn.h \ + ../include/ArActionRatioInput.h ../include/ArActionStop.h \ + ../include/ArActionGoto.h ../include/ArModule.h \ + ../include/ArModuleLoader.h ../include/ArRecurrentTask.h \ + ../include/ArGripper.h ../include/ArSonyPTZ.h ../include/ArRVisionPTZ.h \ + ../include/ArAMPTU.h ../include/ArP2Arm.h ../include/ArSick.h \ + ../include/ArLaser.h ../include/ArRangeDeviceThreaded.h \ + ../include/ArFunctorASyncTask.h ../include/ArLMS2xx.h \ + ../include/ArLMS2xxPacket.h ../include/ArLMS2xxPacketReceiver.h \ + ../include/ArLaserLogger.h ../include/ArIrrfDevice.h \ + ../include/ArDPPTU.h ../include/ArVCC4.h ../include/ArMode.h \ + ../include/ArModes.h ../include/ArTCMCompassRobot.h ../include/ArTCM2.h \ + ../include/ArNetServer.h ../include/ArSignalHandler.h \ + ../include/ArAnalogGyro.h ../include/ArMapInterface.h \ + ../include/ArMapObject.h ../include/ArMapUtils.h ../include/ArMap.h \ + ../include/ArMapComponents.h ../include/ArBumpers.h ../include/ArIRs.h \ + ../include/ArForbiddenRangeDevice.h ../include/ArVersalogicIO.h \ + ../include/ArMTXIO.h ../include/ArActionGotoStraight.h \ + ../include/ArDataLogger.h ../include/ArRobotJoyHandler.h \ + ../include/ArRatioInputKeydrive.h ../include/ArRatioInputJoydrive.h \ + ../include/ArRatioInputRobotJoydrive.h \ + ../include/ArActionMovementParameters.h ../include/ArSoundPlayer.h \ + ../include/ArSoundsQueue.h ../include/ArSpeech.h \ + ../include/ArCameraCollection.h ../include/ArCameraCommands.h \ + ../include/ArSonarAutoDisabler.h ../include/ArActionDriveDistance.h \ + ../include/ArLaserReflectorDevice.h ../include/ArRobotConfig.h \ + ../include/ArTCMCompassDirect.h ../include/ArNMEAParser.h \ + ../include/ArLaserFilter.h ../include/ArUrg.h ../include/ArGPS.h \ + ../include/ArTrimbleGPS.h ../include/ArNovatelGPS.h \ + ../include/ArGPSCoords.h ../include/ArSonarConnector.h \ + ../include/ArBatteryConnector.h ../include/ArLCDConnector.h \ + ../include/ArSonarMTX.h ../include/ArBatteryMTX.h ../include/ArLCDMTX.h \ + ../include/ArSimulatedLaser.h ../include/ArExitErrorSource.h \ + ../include/ArActionLimiterRot.h ../include/ArRobotBatteryPacketReader.h \ + ../include/ArLMS1XX.h ../include/ArUrg_2_0.h \ + ../include/ArActionMovementParametersDebugging.h ../include/ArZippable.h \ + ../include/ArS3Series.h ../include/ArSZSeries.h ../include/ArExport.h \ + include/ArServerInfoDrawings.h include/ArServerBase.h \ + include/ArServerCommands.h include/ArServerClient.h \ + include/ArNetPacket.h include/ArNetPacketReceiverTcp.h \ + include/ArNetPacketSenderTcp.h include/ArServerClientData.h \ + include/ArServerClientIdentifier.h include/ArServerData.h \ + include/ArNetPacketReceiverUdp.h include/ArServerUserInfo.h +../obj/ArServerInfoRobot.o: src/ArServerInfoRobot.cpp ../include/Aria.h \ + ../include/ariaOSDef.h ../include/ariaTypedefs.h \ + ../include/ArSerialConnection.h ../include/ArDeviceConnection.h \ + ../include/ariaUtil.h ../include/ArLog.h ../include/ArMutex.h \ + ../include/ArFunctor.h ../include/ArArgumentParser.h \ + ../include/ArArgumentBuilder.h ../include/ArBasePacket.h \ + ../include/ArTcpConnection.h ../include/ArSocket.h \ + ../include/ArSimpleConnector.h ../include/ArRobotConnector.h \ + ../include/ArLaserConnector.h ../include/ArLogFileConnection.h \ + ../include/ArRobotPacket.h ../include/ArRobotPacketSender.h \ + ../include/ArRobotPacketReceiver.h \ + ../include/ArRobotConfigPacketReader.h ../include/ArRobotTypes.h \ + ../include/ArRobotParams.h ../include/ArConfig.h \ + ../include/ArConfigArg.h ../include/ArFileParser.h \ + ../include/ArHasFileName.h ../include/ArConfigGroup.h \ + ../include/ArRobot.h ../include/ArSyncTask.h ../include/ArTaskState.h \ + ../include/ArSensorReading.h ../include/ArTransform.h \ + ../include/ArCondition.h ../include/ArSyncLoop.h \ + ../include/ArASyncTask.h ../include/ArThread.h \ + ../include/ArRobotPacketReaderThread.h ../include/ArActionDesired.h \ + ../include/ArResolver.h ../include/ArInterpolation.h \ + ../include/ArKeyHandler.h ../include/ArCommands.h \ + ../include/ArJoyHandler.h ../include/ariaInternal.h \ + ../include/ArStringInfoGroup.h ../include/ArSonarDevice.h \ + ../include/ArRangeDevice.h ../include/ArRangeBuffer.h \ + ../include/ArDrawingData.h ../include/ArPriorityResolver.h \ + ../include/ArAction.h ../include/ArArg.h ../include/ArActionGroup.h \ + ../include/ArActionGroups.h ../include/ArActionColorFollow.h \ + ../include/ArACTS.h ../include/ArPTZ.h ../include/ArPTZConnector.h \ + ../include/ArActionDeceleratingLimiter.h \ + ../include/ArActionLimiterForwards.h \ + ../include/ArActionLimiterBackwards.h \ + ../include/ArActionLimiterTableSensor.h ../include/ArActionBumpers.h \ + ../include/ArActionIRs.h ../include/ArActionStallRecover.h \ + ../include/ArActionAvoidFront.h ../include/ArActionAvoidSide.h \ + ../include/ArActionConstantVelocity.h ../include/ArActionInput.h \ + ../include/ArActionRobotJoydrive.h ../include/ArActionJoydrive.h \ + ../include/ArActionKeydrive.h ../include/ArActionTriangleDriveTo.h \ + ../include/ArLineFinder.h ../include/ArActionTurn.h \ + ../include/ArActionRatioInput.h ../include/ArActionStop.h \ + ../include/ArActionGoto.h ../include/ArModule.h \ + ../include/ArModuleLoader.h ../include/ArRecurrentTask.h \ + ../include/ArGripper.h ../include/ArSonyPTZ.h ../include/ArRVisionPTZ.h \ + ../include/ArAMPTU.h ../include/ArP2Arm.h ../include/ArSick.h \ + ../include/ArLaser.h ../include/ArRangeDeviceThreaded.h \ + ../include/ArFunctorASyncTask.h ../include/ArLMS2xx.h \ + ../include/ArLMS2xxPacket.h ../include/ArLMS2xxPacketReceiver.h \ + ../include/ArLaserLogger.h ../include/ArIrrfDevice.h \ + ../include/ArDPPTU.h ../include/ArVCC4.h ../include/ArMode.h \ + ../include/ArModes.h ../include/ArTCMCompassRobot.h ../include/ArTCM2.h \ + ../include/ArNetServer.h ../include/ArSignalHandler.h \ + ../include/ArAnalogGyro.h ../include/ArMapInterface.h \ + ../include/ArMapObject.h ../include/ArMapUtils.h ../include/ArMap.h \ + ../include/ArMapComponents.h ../include/ArBumpers.h ../include/ArIRs.h \ + ../include/ArForbiddenRangeDevice.h ../include/ArVersalogicIO.h \ + ../include/ArMTXIO.h ../include/ArActionGotoStraight.h \ + ../include/ArDataLogger.h ../include/ArRobotJoyHandler.h \ + ../include/ArRatioInputKeydrive.h ../include/ArRatioInputJoydrive.h \ + ../include/ArRatioInputRobotJoydrive.h \ + ../include/ArActionMovementParameters.h ../include/ArSoundPlayer.h \ + ../include/ArSoundsQueue.h ../include/ArSpeech.h \ + ../include/ArCameraCollection.h ../include/ArCameraCommands.h \ + ../include/ArSonarAutoDisabler.h ../include/ArActionDriveDistance.h \ + ../include/ArLaserReflectorDevice.h ../include/ArRobotConfig.h \ + ../include/ArTCMCompassDirect.h ../include/ArNMEAParser.h \ + ../include/ArLaserFilter.h ../include/ArUrg.h ../include/ArGPS.h \ + ../include/ArTrimbleGPS.h ../include/ArNovatelGPS.h \ + ../include/ArGPSCoords.h ../include/ArSonarConnector.h \ + ../include/ArBatteryConnector.h ../include/ArLCDConnector.h \ + ../include/ArSonarMTX.h ../include/ArBatteryMTX.h ../include/ArLCDMTX.h \ + ../include/ArSimulatedLaser.h ../include/ArExitErrorSource.h \ + ../include/ArActionLimiterRot.h ../include/ArRobotBatteryPacketReader.h \ + ../include/ArLMS1XX.h ../include/ArUrg_2_0.h \ + ../include/ArActionMovementParametersDebugging.h ../include/ArZippable.h \ + ../include/ArS3Series.h ../include/ArSZSeries.h ../include/ArExport.h \ + include/ArServerInfoRobot.h include/ArServerBase.h \ + include/ArServerCommands.h include/ArServerClient.h \ + include/ArNetPacket.h include/ArNetPacketReceiverTcp.h \ + include/ArNetPacketSenderTcp.h include/ArServerClientData.h \ + include/ArServerClientIdentifier.h include/ArServerData.h \ + include/ArNetPacketReceiverUdp.h include/ArServerUserInfo.h \ + include/ArServerMode.h +../obj/ArServerInfoSensor.o: src/ArServerInfoSensor.cpp ../include/Aria.h \ + ../include/ariaOSDef.h ../include/ariaTypedefs.h \ + ../include/ArSerialConnection.h ../include/ArDeviceConnection.h \ + ../include/ariaUtil.h ../include/ArLog.h ../include/ArMutex.h \ + ../include/ArFunctor.h ../include/ArArgumentParser.h \ + ../include/ArArgumentBuilder.h ../include/ArBasePacket.h \ + ../include/ArTcpConnection.h ../include/ArSocket.h \ + ../include/ArSimpleConnector.h ../include/ArRobotConnector.h \ + ../include/ArLaserConnector.h ../include/ArLogFileConnection.h \ + ../include/ArRobotPacket.h ../include/ArRobotPacketSender.h \ + ../include/ArRobotPacketReceiver.h \ + ../include/ArRobotConfigPacketReader.h ../include/ArRobotTypes.h \ + ../include/ArRobotParams.h ../include/ArConfig.h \ + ../include/ArConfigArg.h ../include/ArFileParser.h \ + ../include/ArHasFileName.h ../include/ArConfigGroup.h \ + ../include/ArRobot.h ../include/ArSyncTask.h ../include/ArTaskState.h \ + ../include/ArSensorReading.h ../include/ArTransform.h \ + ../include/ArCondition.h ../include/ArSyncLoop.h \ + ../include/ArASyncTask.h ../include/ArThread.h \ + ../include/ArRobotPacketReaderThread.h ../include/ArActionDesired.h \ + ../include/ArResolver.h ../include/ArInterpolation.h \ + ../include/ArKeyHandler.h ../include/ArCommands.h \ + ../include/ArJoyHandler.h ../include/ariaInternal.h \ + ../include/ArStringInfoGroup.h ../include/ArSonarDevice.h \ + ../include/ArRangeDevice.h ../include/ArRangeBuffer.h \ + ../include/ArDrawingData.h ../include/ArPriorityResolver.h \ + ../include/ArAction.h ../include/ArArg.h ../include/ArActionGroup.h \ + ../include/ArActionGroups.h ../include/ArActionColorFollow.h \ + ../include/ArACTS.h ../include/ArPTZ.h ../include/ArPTZConnector.h \ + ../include/ArActionDeceleratingLimiter.h \ + ../include/ArActionLimiterForwards.h \ + ../include/ArActionLimiterBackwards.h \ + ../include/ArActionLimiterTableSensor.h ../include/ArActionBumpers.h \ + ../include/ArActionIRs.h ../include/ArActionStallRecover.h \ + ../include/ArActionAvoidFront.h ../include/ArActionAvoidSide.h \ + ../include/ArActionConstantVelocity.h ../include/ArActionInput.h \ + ../include/ArActionRobotJoydrive.h ../include/ArActionJoydrive.h \ + ../include/ArActionKeydrive.h ../include/ArActionTriangleDriveTo.h \ + ../include/ArLineFinder.h ../include/ArActionTurn.h \ + ../include/ArActionRatioInput.h ../include/ArActionStop.h \ + ../include/ArActionGoto.h ../include/ArModule.h \ + ../include/ArModuleLoader.h ../include/ArRecurrentTask.h \ + ../include/ArGripper.h ../include/ArSonyPTZ.h ../include/ArRVisionPTZ.h \ + ../include/ArAMPTU.h ../include/ArP2Arm.h ../include/ArSick.h \ + ../include/ArLaser.h ../include/ArRangeDeviceThreaded.h \ + ../include/ArFunctorASyncTask.h ../include/ArLMS2xx.h \ + ../include/ArLMS2xxPacket.h ../include/ArLMS2xxPacketReceiver.h \ + ../include/ArLaserLogger.h ../include/ArIrrfDevice.h \ + ../include/ArDPPTU.h ../include/ArVCC4.h ../include/ArMode.h \ + ../include/ArModes.h ../include/ArTCMCompassRobot.h ../include/ArTCM2.h \ + ../include/ArNetServer.h ../include/ArSignalHandler.h \ + ../include/ArAnalogGyro.h ../include/ArMapInterface.h \ + ../include/ArMapObject.h ../include/ArMapUtils.h ../include/ArMap.h \ + ../include/ArMapComponents.h ../include/ArBumpers.h ../include/ArIRs.h \ + ../include/ArForbiddenRangeDevice.h ../include/ArVersalogicIO.h \ + ../include/ArMTXIO.h ../include/ArActionGotoStraight.h \ + ../include/ArDataLogger.h ../include/ArRobotJoyHandler.h \ + ../include/ArRatioInputKeydrive.h ../include/ArRatioInputJoydrive.h \ + ../include/ArRatioInputRobotJoydrive.h \ + ../include/ArActionMovementParameters.h ../include/ArSoundPlayer.h \ + ../include/ArSoundsQueue.h ../include/ArSpeech.h \ + ../include/ArCameraCollection.h ../include/ArCameraCommands.h \ + ../include/ArSonarAutoDisabler.h ../include/ArActionDriveDistance.h \ + ../include/ArLaserReflectorDevice.h ../include/ArRobotConfig.h \ + ../include/ArTCMCompassDirect.h ../include/ArNMEAParser.h \ + ../include/ArLaserFilter.h ../include/ArUrg.h ../include/ArGPS.h \ + ../include/ArTrimbleGPS.h ../include/ArNovatelGPS.h \ + ../include/ArGPSCoords.h ../include/ArSonarConnector.h \ + ../include/ArBatteryConnector.h ../include/ArLCDConnector.h \ + ../include/ArSonarMTX.h ../include/ArBatteryMTX.h ../include/ArLCDMTX.h \ + ../include/ArSimulatedLaser.h ../include/ArExitErrorSource.h \ + ../include/ArActionLimiterRot.h ../include/ArRobotBatteryPacketReader.h \ + ../include/ArLMS1XX.h ../include/ArUrg_2_0.h \ + ../include/ArActionMovementParametersDebugging.h ../include/ArZippable.h \ + ../include/ArS3Series.h ../include/ArSZSeries.h ../include/ArExport.h \ + include/ArServerInfoSensor.h include/ArServerBase.h \ + include/ArServerCommands.h include/ArServerClient.h \ + include/ArNetPacket.h include/ArNetPacketReceiverTcp.h \ + include/ArNetPacketSenderTcp.h include/ArServerClientData.h \ + include/ArServerClientIdentifier.h include/ArServerData.h \ + include/ArNetPacketReceiverUdp.h include/ArServerUserInfo.h +../obj/ArServerInfoStrings.o: src/ArServerInfoStrings.cpp ../include/Aria.h \ + ../include/ariaOSDef.h ../include/ariaTypedefs.h \ + ../include/ArSerialConnection.h ../include/ArDeviceConnection.h \ + ../include/ariaUtil.h ../include/ArLog.h ../include/ArMutex.h \ + ../include/ArFunctor.h ../include/ArArgumentParser.h \ + ../include/ArArgumentBuilder.h ../include/ArBasePacket.h \ + ../include/ArTcpConnection.h ../include/ArSocket.h \ + ../include/ArSimpleConnector.h ../include/ArRobotConnector.h \ + ../include/ArLaserConnector.h ../include/ArLogFileConnection.h \ + ../include/ArRobotPacket.h ../include/ArRobotPacketSender.h \ + ../include/ArRobotPacketReceiver.h \ + ../include/ArRobotConfigPacketReader.h ../include/ArRobotTypes.h \ + ../include/ArRobotParams.h ../include/ArConfig.h \ + ../include/ArConfigArg.h ../include/ArFileParser.h \ + ../include/ArHasFileName.h ../include/ArConfigGroup.h \ + ../include/ArRobot.h ../include/ArSyncTask.h ../include/ArTaskState.h \ + ../include/ArSensorReading.h ../include/ArTransform.h \ + ../include/ArCondition.h ../include/ArSyncLoop.h \ + ../include/ArASyncTask.h ../include/ArThread.h \ + ../include/ArRobotPacketReaderThread.h ../include/ArActionDesired.h \ + ../include/ArResolver.h ../include/ArInterpolation.h \ + ../include/ArKeyHandler.h ../include/ArCommands.h \ + ../include/ArJoyHandler.h ../include/ariaInternal.h \ + ../include/ArStringInfoGroup.h ../include/ArSonarDevice.h \ + ../include/ArRangeDevice.h ../include/ArRangeBuffer.h \ + ../include/ArDrawingData.h ../include/ArPriorityResolver.h \ + ../include/ArAction.h ../include/ArArg.h ../include/ArActionGroup.h \ + ../include/ArActionGroups.h ../include/ArActionColorFollow.h \ + ../include/ArACTS.h ../include/ArPTZ.h ../include/ArPTZConnector.h \ + ../include/ArActionDeceleratingLimiter.h \ + ../include/ArActionLimiterForwards.h \ + ../include/ArActionLimiterBackwards.h \ + ../include/ArActionLimiterTableSensor.h ../include/ArActionBumpers.h \ + ../include/ArActionIRs.h ../include/ArActionStallRecover.h \ + ../include/ArActionAvoidFront.h ../include/ArActionAvoidSide.h \ + ../include/ArActionConstantVelocity.h ../include/ArActionInput.h \ + ../include/ArActionRobotJoydrive.h ../include/ArActionJoydrive.h \ + ../include/ArActionKeydrive.h ../include/ArActionTriangleDriveTo.h \ + ../include/ArLineFinder.h ../include/ArActionTurn.h \ + ../include/ArActionRatioInput.h ../include/ArActionStop.h \ + ../include/ArActionGoto.h ../include/ArModule.h \ + ../include/ArModuleLoader.h ../include/ArRecurrentTask.h \ + ../include/ArGripper.h ../include/ArSonyPTZ.h ../include/ArRVisionPTZ.h \ + ../include/ArAMPTU.h ../include/ArP2Arm.h ../include/ArSick.h \ + ../include/ArLaser.h ../include/ArRangeDeviceThreaded.h \ + ../include/ArFunctorASyncTask.h ../include/ArLMS2xx.h \ + ../include/ArLMS2xxPacket.h ../include/ArLMS2xxPacketReceiver.h \ + ../include/ArLaserLogger.h ../include/ArIrrfDevice.h \ + ../include/ArDPPTU.h ../include/ArVCC4.h ../include/ArMode.h \ + ../include/ArModes.h ../include/ArTCMCompassRobot.h ../include/ArTCM2.h \ + ../include/ArNetServer.h ../include/ArSignalHandler.h \ + ../include/ArAnalogGyro.h ../include/ArMapInterface.h \ + ../include/ArMapObject.h ../include/ArMapUtils.h ../include/ArMap.h \ + ../include/ArMapComponents.h ../include/ArBumpers.h ../include/ArIRs.h \ + ../include/ArForbiddenRangeDevice.h ../include/ArVersalogicIO.h \ + ../include/ArMTXIO.h ../include/ArActionGotoStraight.h \ + ../include/ArDataLogger.h ../include/ArRobotJoyHandler.h \ + ../include/ArRatioInputKeydrive.h ../include/ArRatioInputJoydrive.h \ + ../include/ArRatioInputRobotJoydrive.h \ + ../include/ArActionMovementParameters.h ../include/ArSoundPlayer.h \ + ../include/ArSoundsQueue.h ../include/ArSpeech.h \ + ../include/ArCameraCollection.h ../include/ArCameraCommands.h \ + ../include/ArSonarAutoDisabler.h ../include/ArActionDriveDistance.h \ + ../include/ArLaserReflectorDevice.h ../include/ArRobotConfig.h \ + ../include/ArTCMCompassDirect.h ../include/ArNMEAParser.h \ + ../include/ArLaserFilter.h ../include/ArUrg.h ../include/ArGPS.h \ + ../include/ArTrimbleGPS.h ../include/ArNovatelGPS.h \ + ../include/ArGPSCoords.h ../include/ArSonarConnector.h \ + ../include/ArBatteryConnector.h ../include/ArLCDConnector.h \ + ../include/ArSonarMTX.h ../include/ArBatteryMTX.h ../include/ArLCDMTX.h \ + ../include/ArSimulatedLaser.h ../include/ArExitErrorSource.h \ + ../include/ArActionLimiterRot.h ../include/ArRobotBatteryPacketReader.h \ + ../include/ArLMS1XX.h ../include/ArUrg_2_0.h \ + ../include/ArActionMovementParametersDebugging.h ../include/ArZippable.h \ + ../include/ArS3Series.h ../include/ArSZSeries.h ../include/ArExport.h \ + include/ArServerInfoStrings.h include/ArServerBase.h \ + include/ArServerCommands.h include/ArServerClient.h \ + include/ArNetPacket.h include/ArNetPacketReceiverTcp.h \ + include/ArNetPacketSenderTcp.h include/ArServerClientData.h \ + include/ArServerClientIdentifier.h include/ArServerData.h \ + include/ArNetPacketReceiverUdp.h include/ArServerUserInfo.h +../obj/ArServerMode.o: src/ArServerMode.cpp ../include/Aria.h \ + ../include/ariaOSDef.h ../include/ariaTypedefs.h \ + ../include/ArSerialConnection.h ../include/ArDeviceConnection.h \ + ../include/ariaUtil.h ../include/ArLog.h ../include/ArMutex.h \ + ../include/ArFunctor.h ../include/ArArgumentParser.h \ + ../include/ArArgumentBuilder.h ../include/ArBasePacket.h \ + ../include/ArTcpConnection.h ../include/ArSocket.h \ + ../include/ArSimpleConnector.h ../include/ArRobotConnector.h \ + ../include/ArLaserConnector.h ../include/ArLogFileConnection.h \ + ../include/ArRobotPacket.h ../include/ArRobotPacketSender.h \ + ../include/ArRobotPacketReceiver.h \ + ../include/ArRobotConfigPacketReader.h ../include/ArRobotTypes.h \ + ../include/ArRobotParams.h ../include/ArConfig.h \ + ../include/ArConfigArg.h ../include/ArFileParser.h \ + ../include/ArHasFileName.h ../include/ArConfigGroup.h \ + ../include/ArRobot.h ../include/ArSyncTask.h ../include/ArTaskState.h \ + ../include/ArSensorReading.h ../include/ArTransform.h \ + ../include/ArCondition.h ../include/ArSyncLoop.h \ + ../include/ArASyncTask.h ../include/ArThread.h \ + ../include/ArRobotPacketReaderThread.h ../include/ArActionDesired.h \ + ../include/ArResolver.h ../include/ArInterpolation.h \ + ../include/ArKeyHandler.h ../include/ArCommands.h \ + ../include/ArJoyHandler.h ../include/ariaInternal.h \ + ../include/ArStringInfoGroup.h ../include/ArSonarDevice.h \ + ../include/ArRangeDevice.h ../include/ArRangeBuffer.h \ + ../include/ArDrawingData.h ../include/ArPriorityResolver.h \ + ../include/ArAction.h ../include/ArArg.h ../include/ArActionGroup.h \ + ../include/ArActionGroups.h ../include/ArActionColorFollow.h \ + ../include/ArACTS.h ../include/ArPTZ.h ../include/ArPTZConnector.h \ + ../include/ArActionDeceleratingLimiter.h \ + ../include/ArActionLimiterForwards.h \ + ../include/ArActionLimiterBackwards.h \ + ../include/ArActionLimiterTableSensor.h ../include/ArActionBumpers.h \ + ../include/ArActionIRs.h ../include/ArActionStallRecover.h \ + ../include/ArActionAvoidFront.h ../include/ArActionAvoidSide.h \ + ../include/ArActionConstantVelocity.h ../include/ArActionInput.h \ + ../include/ArActionRobotJoydrive.h ../include/ArActionJoydrive.h \ + ../include/ArActionKeydrive.h ../include/ArActionTriangleDriveTo.h \ + ../include/ArLineFinder.h ../include/ArActionTurn.h \ + ../include/ArActionRatioInput.h ../include/ArActionStop.h \ + ../include/ArActionGoto.h ../include/ArModule.h \ + ../include/ArModuleLoader.h ../include/ArRecurrentTask.h \ + ../include/ArGripper.h ../include/ArSonyPTZ.h ../include/ArRVisionPTZ.h \ + ../include/ArAMPTU.h ../include/ArP2Arm.h ../include/ArSick.h \ + ../include/ArLaser.h ../include/ArRangeDeviceThreaded.h \ + ../include/ArFunctorASyncTask.h ../include/ArLMS2xx.h \ + ../include/ArLMS2xxPacket.h ../include/ArLMS2xxPacketReceiver.h \ + ../include/ArLaserLogger.h ../include/ArIrrfDevice.h \ + ../include/ArDPPTU.h ../include/ArVCC4.h ../include/ArMode.h \ + ../include/ArModes.h ../include/ArTCMCompassRobot.h ../include/ArTCM2.h \ + ../include/ArNetServer.h ../include/ArSignalHandler.h \ + ../include/ArAnalogGyro.h ../include/ArMapInterface.h \ + ../include/ArMapObject.h ../include/ArMapUtils.h ../include/ArMap.h \ + ../include/ArMapComponents.h ../include/ArBumpers.h ../include/ArIRs.h \ + ../include/ArForbiddenRangeDevice.h ../include/ArVersalogicIO.h \ + ../include/ArMTXIO.h ../include/ArActionGotoStraight.h \ + ../include/ArDataLogger.h ../include/ArRobotJoyHandler.h \ + ../include/ArRatioInputKeydrive.h ../include/ArRatioInputJoydrive.h \ + ../include/ArRatioInputRobotJoydrive.h \ + ../include/ArActionMovementParameters.h ../include/ArSoundPlayer.h \ + ../include/ArSoundsQueue.h ../include/ArSpeech.h \ + ../include/ArCameraCollection.h ../include/ArCameraCommands.h \ + ../include/ArSonarAutoDisabler.h ../include/ArActionDriveDistance.h \ + ../include/ArLaserReflectorDevice.h ../include/ArRobotConfig.h \ + ../include/ArTCMCompassDirect.h ../include/ArNMEAParser.h \ + ../include/ArLaserFilter.h ../include/ArUrg.h ../include/ArGPS.h \ + ../include/ArTrimbleGPS.h ../include/ArNovatelGPS.h \ + ../include/ArGPSCoords.h ../include/ArSonarConnector.h \ + ../include/ArBatteryConnector.h ../include/ArLCDConnector.h \ + ../include/ArSonarMTX.h ../include/ArBatteryMTX.h ../include/ArLCDMTX.h \ + ../include/ArSimulatedLaser.h ../include/ArExitErrorSource.h \ + ../include/ArActionLimiterRot.h ../include/ArRobotBatteryPacketReader.h \ + ../include/ArLMS1XX.h ../include/ArUrg_2_0.h \ + ../include/ArActionMovementParametersDebugging.h ../include/ArZippable.h \ + ../include/ArS3Series.h ../include/ArSZSeries.h ../include/ArExport.h \ + include/ArServerMode.h include/ArServerBase.h include/ArServerCommands.h \ + include/ArServerClient.h include/ArNetPacket.h \ + include/ArNetPacketReceiverTcp.h include/ArNetPacketSenderTcp.h \ + include/ArServerClientData.h include/ArServerClientIdentifier.h \ + include/ArServerData.h include/ArNetPacketReceiverUdp.h \ + include/ArServerUserInfo.h include/ArServerModeIdle.h \ + include/ArServerMode.h +../obj/ArServerModeDrive.o: src/ArServerModeDrive.cpp ../include/Aria.h \ + ../include/ariaOSDef.h ../include/ariaTypedefs.h \ + ../include/ArSerialConnection.h ../include/ArDeviceConnection.h \ + ../include/ariaUtil.h ../include/ArLog.h ../include/ArMutex.h \ + ../include/ArFunctor.h ../include/ArArgumentParser.h \ + ../include/ArArgumentBuilder.h ../include/ArBasePacket.h \ + ../include/ArTcpConnection.h ../include/ArSocket.h \ + ../include/ArSimpleConnector.h ../include/ArRobotConnector.h \ + ../include/ArLaserConnector.h ../include/ArLogFileConnection.h \ + ../include/ArRobotPacket.h ../include/ArRobotPacketSender.h \ + ../include/ArRobotPacketReceiver.h \ + ../include/ArRobotConfigPacketReader.h ../include/ArRobotTypes.h \ + ../include/ArRobotParams.h ../include/ArConfig.h \ + ../include/ArConfigArg.h ../include/ArFileParser.h \ + ../include/ArHasFileName.h ../include/ArConfigGroup.h \ + ../include/ArRobot.h ../include/ArSyncTask.h ../include/ArTaskState.h \ + ../include/ArSensorReading.h ../include/ArTransform.h \ + ../include/ArCondition.h ../include/ArSyncLoop.h \ + ../include/ArASyncTask.h ../include/ArThread.h \ + ../include/ArRobotPacketReaderThread.h ../include/ArActionDesired.h \ + ../include/ArResolver.h ../include/ArInterpolation.h \ + ../include/ArKeyHandler.h ../include/ArCommands.h \ + ../include/ArJoyHandler.h ../include/ariaInternal.h \ + ../include/ArStringInfoGroup.h ../include/ArSonarDevice.h \ + ../include/ArRangeDevice.h ../include/ArRangeBuffer.h \ + ../include/ArDrawingData.h ../include/ArPriorityResolver.h \ + ../include/ArAction.h ../include/ArArg.h ../include/ArActionGroup.h \ + ../include/ArActionGroups.h ../include/ArActionColorFollow.h \ + ../include/ArACTS.h ../include/ArPTZ.h ../include/ArPTZConnector.h \ + ../include/ArActionDeceleratingLimiter.h \ + ../include/ArActionLimiterForwards.h \ + ../include/ArActionLimiterBackwards.h \ + ../include/ArActionLimiterTableSensor.h ../include/ArActionBumpers.h \ + ../include/ArActionIRs.h ../include/ArActionStallRecover.h \ + ../include/ArActionAvoidFront.h ../include/ArActionAvoidSide.h \ + ../include/ArActionConstantVelocity.h ../include/ArActionInput.h \ + ../include/ArActionRobotJoydrive.h ../include/ArActionJoydrive.h \ + ../include/ArActionKeydrive.h ../include/ArActionTriangleDriveTo.h \ + ../include/ArLineFinder.h ../include/ArActionTurn.h \ + ../include/ArActionRatioInput.h ../include/ArActionStop.h \ + ../include/ArActionGoto.h ../include/ArModule.h \ + ../include/ArModuleLoader.h ../include/ArRecurrentTask.h \ + ../include/ArGripper.h ../include/ArSonyPTZ.h ../include/ArRVisionPTZ.h \ + ../include/ArAMPTU.h ../include/ArP2Arm.h ../include/ArSick.h \ + ../include/ArLaser.h ../include/ArRangeDeviceThreaded.h \ + ../include/ArFunctorASyncTask.h ../include/ArLMS2xx.h \ + ../include/ArLMS2xxPacket.h ../include/ArLMS2xxPacketReceiver.h \ + ../include/ArLaserLogger.h ../include/ArIrrfDevice.h \ + ../include/ArDPPTU.h ../include/ArVCC4.h ../include/ArMode.h \ + ../include/ArModes.h ../include/ArTCMCompassRobot.h ../include/ArTCM2.h \ + ../include/ArNetServer.h ../include/ArSignalHandler.h \ + ../include/ArAnalogGyro.h ../include/ArMapInterface.h \ + ../include/ArMapObject.h ../include/ArMapUtils.h ../include/ArMap.h \ + ../include/ArMapComponents.h ../include/ArBumpers.h ../include/ArIRs.h \ + ../include/ArForbiddenRangeDevice.h ../include/ArVersalogicIO.h \ + ../include/ArMTXIO.h ../include/ArActionGotoStraight.h \ + ../include/ArDataLogger.h ../include/ArRobotJoyHandler.h \ + ../include/ArRatioInputKeydrive.h ../include/ArRatioInputJoydrive.h \ + ../include/ArRatioInputRobotJoydrive.h \ + ../include/ArActionMovementParameters.h ../include/ArSoundPlayer.h \ + ../include/ArSoundsQueue.h ../include/ArSpeech.h \ + ../include/ArCameraCollection.h ../include/ArCameraCommands.h \ + ../include/ArSonarAutoDisabler.h ../include/ArActionDriveDistance.h \ + ../include/ArLaserReflectorDevice.h ../include/ArRobotConfig.h \ + ../include/ArTCMCompassDirect.h ../include/ArNMEAParser.h \ + ../include/ArLaserFilter.h ../include/ArUrg.h ../include/ArGPS.h \ + ../include/ArTrimbleGPS.h ../include/ArNovatelGPS.h \ + ../include/ArGPSCoords.h ../include/ArSonarConnector.h \ + ../include/ArBatteryConnector.h ../include/ArLCDConnector.h \ + ../include/ArSonarMTX.h ../include/ArBatteryMTX.h ../include/ArLCDMTX.h \ + ../include/ArSimulatedLaser.h ../include/ArExitErrorSource.h \ + ../include/ArActionLimiterRot.h ../include/ArRobotBatteryPacketReader.h \ + ../include/ArLMS1XX.h ../include/ArUrg_2_0.h \ + ../include/ArActionMovementParametersDebugging.h ../include/ArZippable.h \ + ../include/ArS3Series.h ../include/ArSZSeries.h ../include/ArExport.h \ + include/ArServerModeDrive.h ../include/ariaTypedefs.h \ + include/ArNetworking.h include/ArServerBase.h include/ArServerCommands.h \ + include/ArServerClient.h include/ArNetPacket.h \ + include/ArNetPacketReceiverTcp.h include/ArNetPacketSenderTcp.h \ + include/ArServerClientData.h include/ArServerClientIdentifier.h \ + include/ArServerData.h include/ArNetPacketReceiverUdp.h \ + include/ArServerUserInfo.h include/ArClientBase.h \ + include/ArClientCommands.h include/ArClientData.h include/ArMapChanger.h \ + ../include/ariaUtil.h ../include/ArMapInterface.h \ + ../include/ArMapUtils.h ../include/ArMutex.h \ + include/ArCentralForwarder.h include/ArClientSwitchManager.h \ + include/ArServerHandlerCamera.h \ + include/ArServerHandlerCameraCollection.h ../include/ArFunctor.h \ + ../include/ArCameraCollection.h include/ArServerHandlerCommMonitor.h \ + include/ArServerHandlerCommands.h include/ArServerHandlerPopup.h \ + include/ArServerInfoDrawings.h include/ArServerInfoRobot.h \ + include/ArServerInfoSensor.h include/ArServerHandlerMap.h \ + ../include/ArConfig.h include/ArServerMode.h include/ArServerModeDrive.h \ + include/ArServerModeRatioDrive.h include/ArServerModeStop.h \ + include/ArServerModeWander.h include/ArServerHandlerConfig.h \ + include/ArClientHandlerConfig.h include/ArHybridForwarderVideo.h \ + include/ArServerSimpleCommands.h include/ArServerFileUtils.h \ + include/ArClientFileUtils.h include/ArClientSimpleConnector.h \ + include/ArServerHandlerMapping.h include/ArTempDirectoryHelper.h \ + include/ArServerSimpleOpener.h include/ArServerInfoStrings.h \ + include/ArClientArgUtils.h include/ArCentralManager.h \ + include/ArServerModeIdle.h +../obj/ArServerModeIdle.o: src/ArServerModeIdle.cpp ../include/Aria.h \ + ../include/ariaOSDef.h ../include/ariaTypedefs.h \ + ../include/ArSerialConnection.h ../include/ArDeviceConnection.h \ + ../include/ariaUtil.h ../include/ArLog.h ../include/ArMutex.h \ + ../include/ArFunctor.h ../include/ArArgumentParser.h \ + ../include/ArArgumentBuilder.h ../include/ArBasePacket.h \ + ../include/ArTcpConnection.h ../include/ArSocket.h \ + ../include/ArSimpleConnector.h ../include/ArRobotConnector.h \ + ../include/ArLaserConnector.h ../include/ArLogFileConnection.h \ + ../include/ArRobotPacket.h ../include/ArRobotPacketSender.h \ + ../include/ArRobotPacketReceiver.h \ + ../include/ArRobotConfigPacketReader.h ../include/ArRobotTypes.h \ + ../include/ArRobotParams.h ../include/ArConfig.h \ + ../include/ArConfigArg.h ../include/ArFileParser.h \ + ../include/ArHasFileName.h ../include/ArConfigGroup.h \ + ../include/ArRobot.h ../include/ArSyncTask.h ../include/ArTaskState.h \ + ../include/ArSensorReading.h ../include/ArTransform.h \ + ../include/ArCondition.h ../include/ArSyncLoop.h \ + ../include/ArASyncTask.h ../include/ArThread.h \ + ../include/ArRobotPacketReaderThread.h ../include/ArActionDesired.h \ + ../include/ArResolver.h ../include/ArInterpolation.h \ + ../include/ArKeyHandler.h ../include/ArCommands.h \ + ../include/ArJoyHandler.h ../include/ariaInternal.h \ + ../include/ArStringInfoGroup.h ../include/ArSonarDevice.h \ + ../include/ArRangeDevice.h ../include/ArRangeBuffer.h \ + ../include/ArDrawingData.h ../include/ArPriorityResolver.h \ + ../include/ArAction.h ../include/ArArg.h ../include/ArActionGroup.h \ + ../include/ArActionGroups.h ../include/ArActionColorFollow.h \ + ../include/ArACTS.h ../include/ArPTZ.h ../include/ArPTZConnector.h \ + ../include/ArActionDeceleratingLimiter.h \ + ../include/ArActionLimiterForwards.h \ + ../include/ArActionLimiterBackwards.h \ + ../include/ArActionLimiterTableSensor.h ../include/ArActionBumpers.h \ + ../include/ArActionIRs.h ../include/ArActionStallRecover.h \ + ../include/ArActionAvoidFront.h ../include/ArActionAvoidSide.h \ + ../include/ArActionConstantVelocity.h ../include/ArActionInput.h \ + ../include/ArActionRobotJoydrive.h ../include/ArActionJoydrive.h \ + ../include/ArActionKeydrive.h ../include/ArActionTriangleDriveTo.h \ + ../include/ArLineFinder.h ../include/ArActionTurn.h \ + ../include/ArActionRatioInput.h ../include/ArActionStop.h \ + ../include/ArActionGoto.h ../include/ArModule.h \ + ../include/ArModuleLoader.h ../include/ArRecurrentTask.h \ + ../include/ArGripper.h ../include/ArSonyPTZ.h ../include/ArRVisionPTZ.h \ + ../include/ArAMPTU.h ../include/ArP2Arm.h ../include/ArSick.h \ + ../include/ArLaser.h ../include/ArRangeDeviceThreaded.h \ + ../include/ArFunctorASyncTask.h ../include/ArLMS2xx.h \ + ../include/ArLMS2xxPacket.h ../include/ArLMS2xxPacketReceiver.h \ + ../include/ArLaserLogger.h ../include/ArIrrfDevice.h \ + ../include/ArDPPTU.h ../include/ArVCC4.h ../include/ArMode.h \ + ../include/ArModes.h ../include/ArTCMCompassRobot.h ../include/ArTCM2.h \ + ../include/ArNetServer.h ../include/ArSignalHandler.h \ + ../include/ArAnalogGyro.h ../include/ArMapInterface.h \ + ../include/ArMapObject.h ../include/ArMapUtils.h ../include/ArMap.h \ + ../include/ArMapComponents.h ../include/ArBumpers.h ../include/ArIRs.h \ + ../include/ArForbiddenRangeDevice.h ../include/ArVersalogicIO.h \ + ../include/ArMTXIO.h ../include/ArActionGotoStraight.h \ + ../include/ArDataLogger.h ../include/ArRobotJoyHandler.h \ + ../include/ArRatioInputKeydrive.h ../include/ArRatioInputJoydrive.h \ + ../include/ArRatioInputRobotJoydrive.h \ + ../include/ArActionMovementParameters.h ../include/ArSoundPlayer.h \ + ../include/ArSoundsQueue.h ../include/ArSpeech.h \ + ../include/ArCameraCollection.h ../include/ArCameraCommands.h \ + ../include/ArSonarAutoDisabler.h ../include/ArActionDriveDistance.h \ + ../include/ArLaserReflectorDevice.h ../include/ArRobotConfig.h \ + ../include/ArTCMCompassDirect.h ../include/ArNMEAParser.h \ + ../include/ArLaserFilter.h ../include/ArUrg.h ../include/ArGPS.h \ + ../include/ArTrimbleGPS.h ../include/ArNovatelGPS.h \ + ../include/ArGPSCoords.h ../include/ArSonarConnector.h \ + ../include/ArBatteryConnector.h ../include/ArLCDConnector.h \ + ../include/ArSonarMTX.h ../include/ArBatteryMTX.h ../include/ArLCDMTX.h \ + ../include/ArSimulatedLaser.h ../include/ArExitErrorSource.h \ + ../include/ArActionLimiterRot.h ../include/ArRobotBatteryPacketReader.h \ + ../include/ArLMS1XX.h ../include/ArUrg_2_0.h \ + ../include/ArActionMovementParametersDebugging.h ../include/ArZippable.h \ + ../include/ArS3Series.h ../include/ArSZSeries.h ../include/ArExport.h \ + include/ArServerModeIdle.h include/ArServerMode.h include/ArServerBase.h \ + include/ArServerCommands.h include/ArServerClient.h \ + include/ArNetPacket.h include/ArNetPacketReceiverTcp.h \ + include/ArNetPacketSenderTcp.h include/ArServerClientData.h \ + include/ArServerClientIdentifier.h include/ArServerData.h \ + include/ArNetPacketReceiverUdp.h include/ArServerUserInfo.h +../obj/ArServerModeRatioDrive.o: src/ArServerModeRatioDrive.cpp \ + ../include/Aria.h ../include/ariaOSDef.h ../include/ariaTypedefs.h \ + ../include/ArSerialConnection.h ../include/ArDeviceConnection.h \ + ../include/ariaUtil.h ../include/ArLog.h ../include/ArMutex.h \ + ../include/ArFunctor.h ../include/ArArgumentParser.h \ + ../include/ArArgumentBuilder.h ../include/ArBasePacket.h \ + ../include/ArTcpConnection.h ../include/ArSocket.h \ + ../include/ArSimpleConnector.h ../include/ArRobotConnector.h \ + ../include/ArLaserConnector.h ../include/ArLogFileConnection.h \ + ../include/ArRobotPacket.h ../include/ArRobotPacketSender.h \ + ../include/ArRobotPacketReceiver.h \ + ../include/ArRobotConfigPacketReader.h ../include/ArRobotTypes.h \ + ../include/ArRobotParams.h ../include/ArConfig.h \ + ../include/ArConfigArg.h ../include/ArFileParser.h \ + ../include/ArHasFileName.h ../include/ArConfigGroup.h \ + ../include/ArRobot.h ../include/ArSyncTask.h ../include/ArTaskState.h \ + ../include/ArSensorReading.h ../include/ArTransform.h \ + ../include/ArCondition.h ../include/ArSyncLoop.h \ + ../include/ArASyncTask.h ../include/ArThread.h \ + ../include/ArRobotPacketReaderThread.h ../include/ArActionDesired.h \ + ../include/ArResolver.h ../include/ArInterpolation.h \ + ../include/ArKeyHandler.h ../include/ArCommands.h \ + ../include/ArJoyHandler.h ../include/ariaInternal.h \ + ../include/ArStringInfoGroup.h ../include/ArSonarDevice.h \ + ../include/ArRangeDevice.h ../include/ArRangeBuffer.h \ + ../include/ArDrawingData.h ../include/ArPriorityResolver.h \ + ../include/ArAction.h ../include/ArArg.h ../include/ArActionGroup.h \ + ../include/ArActionGroups.h ../include/ArActionColorFollow.h \ + ../include/ArACTS.h ../include/ArPTZ.h ../include/ArPTZConnector.h \ + ../include/ArActionDeceleratingLimiter.h \ + ../include/ArActionLimiterForwards.h \ + ../include/ArActionLimiterBackwards.h \ + ../include/ArActionLimiterTableSensor.h ../include/ArActionBumpers.h \ + ../include/ArActionIRs.h ../include/ArActionStallRecover.h \ + ../include/ArActionAvoidFront.h ../include/ArActionAvoidSide.h \ + ../include/ArActionConstantVelocity.h ../include/ArActionInput.h \ + ../include/ArActionRobotJoydrive.h ../include/ArActionJoydrive.h \ + ../include/ArActionKeydrive.h ../include/ArActionTriangleDriveTo.h \ + ../include/ArLineFinder.h ../include/ArActionTurn.h \ + ../include/ArActionRatioInput.h ../include/ArActionStop.h \ + ../include/ArActionGoto.h ../include/ArModule.h \ + ../include/ArModuleLoader.h ../include/ArRecurrentTask.h \ + ../include/ArGripper.h ../include/ArSonyPTZ.h ../include/ArRVisionPTZ.h \ + ../include/ArAMPTU.h ../include/ArP2Arm.h ../include/ArSick.h \ + ../include/ArLaser.h ../include/ArRangeDeviceThreaded.h \ + ../include/ArFunctorASyncTask.h ../include/ArLMS2xx.h \ + ../include/ArLMS2xxPacket.h ../include/ArLMS2xxPacketReceiver.h \ + ../include/ArLaserLogger.h ../include/ArIrrfDevice.h \ + ../include/ArDPPTU.h ../include/ArVCC4.h ../include/ArMode.h \ + ../include/ArModes.h ../include/ArTCMCompassRobot.h ../include/ArTCM2.h \ + ../include/ArNetServer.h ../include/ArSignalHandler.h \ + ../include/ArAnalogGyro.h ../include/ArMapInterface.h \ + ../include/ArMapObject.h ../include/ArMapUtils.h ../include/ArMap.h \ + ../include/ArMapComponents.h ../include/ArBumpers.h ../include/ArIRs.h \ + ../include/ArForbiddenRangeDevice.h ../include/ArVersalogicIO.h \ + ../include/ArMTXIO.h ../include/ArActionGotoStraight.h \ + ../include/ArDataLogger.h ../include/ArRobotJoyHandler.h \ + ../include/ArRatioInputKeydrive.h ../include/ArRatioInputJoydrive.h \ + ../include/ArRatioInputRobotJoydrive.h \ + ../include/ArActionMovementParameters.h ../include/ArSoundPlayer.h \ + ../include/ArSoundsQueue.h ../include/ArSpeech.h \ + ../include/ArCameraCollection.h ../include/ArCameraCommands.h \ + ../include/ArSonarAutoDisabler.h ../include/ArActionDriveDistance.h \ + ../include/ArLaserReflectorDevice.h ../include/ArRobotConfig.h \ + ../include/ArTCMCompassDirect.h ../include/ArNMEAParser.h \ + ../include/ArLaserFilter.h ../include/ArUrg.h ../include/ArGPS.h \ + ../include/ArTrimbleGPS.h ../include/ArNovatelGPS.h \ + ../include/ArGPSCoords.h ../include/ArSonarConnector.h \ + ../include/ArBatteryConnector.h ../include/ArLCDConnector.h \ + ../include/ArSonarMTX.h ../include/ArBatteryMTX.h ../include/ArLCDMTX.h \ + ../include/ArSimulatedLaser.h ../include/ArExitErrorSource.h \ + ../include/ArActionLimiterRot.h ../include/ArRobotBatteryPacketReader.h \ + ../include/ArLMS1XX.h ../include/ArUrg_2_0.h \ + ../include/ArActionMovementParametersDebugging.h ../include/ArZippable.h \ + ../include/ArS3Series.h ../include/ArSZSeries.h ../include/ArExport.h \ + include/ArServerModeRatioDrive.h ../include/ariaTypedefs.h \ + include/ArServerMode.h include/ArServerBase.h include/ArServerCommands.h \ + include/ArServerClient.h include/ArNetPacket.h \ + include/ArNetPacketReceiverTcp.h include/ArNetPacketSenderTcp.h \ + include/ArServerClientData.h include/ArServerClientIdentifier.h \ + include/ArServerData.h include/ArNetPacketReceiverUdp.h \ + include/ArServerUserInfo.h include/ArServerHandlerCommands.h +../obj/ArServerModeStop.o: src/ArServerModeStop.cpp ../include/Aria.h \ + ../include/ariaOSDef.h ../include/ariaTypedefs.h \ + ../include/ArSerialConnection.h ../include/ArDeviceConnection.h \ + ../include/ariaUtil.h ../include/ArLog.h ../include/ArMutex.h \ + ../include/ArFunctor.h ../include/ArArgumentParser.h \ + ../include/ArArgumentBuilder.h ../include/ArBasePacket.h \ + ../include/ArTcpConnection.h ../include/ArSocket.h \ + ../include/ArSimpleConnector.h ../include/ArRobotConnector.h \ + ../include/ArLaserConnector.h ../include/ArLogFileConnection.h \ + ../include/ArRobotPacket.h ../include/ArRobotPacketSender.h \ + ../include/ArRobotPacketReceiver.h \ + ../include/ArRobotConfigPacketReader.h ../include/ArRobotTypes.h \ + ../include/ArRobotParams.h ../include/ArConfig.h \ + ../include/ArConfigArg.h ../include/ArFileParser.h \ + ../include/ArHasFileName.h ../include/ArConfigGroup.h \ + ../include/ArRobot.h ../include/ArSyncTask.h ../include/ArTaskState.h \ + ../include/ArSensorReading.h ../include/ArTransform.h \ + ../include/ArCondition.h ../include/ArSyncLoop.h \ + ../include/ArASyncTask.h ../include/ArThread.h \ + ../include/ArRobotPacketReaderThread.h ../include/ArActionDesired.h \ + ../include/ArResolver.h ../include/ArInterpolation.h \ + ../include/ArKeyHandler.h ../include/ArCommands.h \ + ../include/ArJoyHandler.h ../include/ariaInternal.h \ + ../include/ArStringInfoGroup.h ../include/ArSonarDevice.h \ + ../include/ArRangeDevice.h ../include/ArRangeBuffer.h \ + ../include/ArDrawingData.h ../include/ArPriorityResolver.h \ + ../include/ArAction.h ../include/ArArg.h ../include/ArActionGroup.h \ + ../include/ArActionGroups.h ../include/ArActionColorFollow.h \ + ../include/ArACTS.h ../include/ArPTZ.h ../include/ArPTZConnector.h \ + ../include/ArActionDeceleratingLimiter.h \ + ../include/ArActionLimiterForwards.h \ + ../include/ArActionLimiterBackwards.h \ + ../include/ArActionLimiterTableSensor.h ../include/ArActionBumpers.h \ + ../include/ArActionIRs.h ../include/ArActionStallRecover.h \ + ../include/ArActionAvoidFront.h ../include/ArActionAvoidSide.h \ + ../include/ArActionConstantVelocity.h ../include/ArActionInput.h \ + ../include/ArActionRobotJoydrive.h ../include/ArActionJoydrive.h \ + ../include/ArActionKeydrive.h ../include/ArActionTriangleDriveTo.h \ + ../include/ArLineFinder.h ../include/ArActionTurn.h \ + ../include/ArActionRatioInput.h ../include/ArActionStop.h \ + ../include/ArActionGoto.h ../include/ArModule.h \ + ../include/ArModuleLoader.h ../include/ArRecurrentTask.h \ + ../include/ArGripper.h ../include/ArSonyPTZ.h ../include/ArRVisionPTZ.h \ + ../include/ArAMPTU.h ../include/ArP2Arm.h ../include/ArSick.h \ + ../include/ArLaser.h ../include/ArRangeDeviceThreaded.h \ + ../include/ArFunctorASyncTask.h ../include/ArLMS2xx.h \ + ../include/ArLMS2xxPacket.h ../include/ArLMS2xxPacketReceiver.h \ + ../include/ArLaserLogger.h ../include/ArIrrfDevice.h \ + ../include/ArDPPTU.h ../include/ArVCC4.h ../include/ArMode.h \ + ../include/ArModes.h ../include/ArTCMCompassRobot.h ../include/ArTCM2.h \ + ../include/ArNetServer.h ../include/ArSignalHandler.h \ + ../include/ArAnalogGyro.h ../include/ArMapInterface.h \ + ../include/ArMapObject.h ../include/ArMapUtils.h ../include/ArMap.h \ + ../include/ArMapComponents.h ../include/ArBumpers.h ../include/ArIRs.h \ + ../include/ArForbiddenRangeDevice.h ../include/ArVersalogicIO.h \ + ../include/ArMTXIO.h ../include/ArActionGotoStraight.h \ + ../include/ArDataLogger.h ../include/ArRobotJoyHandler.h \ + ../include/ArRatioInputKeydrive.h ../include/ArRatioInputJoydrive.h \ + ../include/ArRatioInputRobotJoydrive.h \ + ../include/ArActionMovementParameters.h ../include/ArSoundPlayer.h \ + ../include/ArSoundsQueue.h ../include/ArSpeech.h \ + ../include/ArCameraCollection.h ../include/ArCameraCommands.h \ + ../include/ArSonarAutoDisabler.h ../include/ArActionDriveDistance.h \ + ../include/ArLaserReflectorDevice.h ../include/ArRobotConfig.h \ + ../include/ArTCMCompassDirect.h ../include/ArNMEAParser.h \ + ../include/ArLaserFilter.h ../include/ArUrg.h ../include/ArGPS.h \ + ../include/ArTrimbleGPS.h ../include/ArNovatelGPS.h \ + ../include/ArGPSCoords.h ../include/ArSonarConnector.h \ + ../include/ArBatteryConnector.h ../include/ArLCDConnector.h \ + ../include/ArSonarMTX.h ../include/ArBatteryMTX.h ../include/ArLCDMTX.h \ + ../include/ArSimulatedLaser.h ../include/ArExitErrorSource.h \ + ../include/ArActionLimiterRot.h ../include/ArRobotBatteryPacketReader.h \ + ../include/ArLMS1XX.h ../include/ArUrg_2_0.h \ + ../include/ArActionMovementParametersDebugging.h ../include/ArZippable.h \ + ../include/ArS3Series.h ../include/ArSZSeries.h ../include/ArExport.h \ + include/ArServerModeStop.h include/ArServerMode.h include/ArServerBase.h \ + include/ArServerCommands.h include/ArServerClient.h \ + include/ArNetPacket.h include/ArNetPacketReceiverTcp.h \ + include/ArNetPacketSenderTcp.h include/ArServerClientData.h \ + include/ArServerClientIdentifier.h include/ArServerData.h \ + include/ArNetPacketReceiverUdp.h include/ArServerUserInfo.h +../obj/ArServerModeWander.o: src/ArServerModeWander.cpp ../include/Aria.h \ + ../include/ariaOSDef.h ../include/ariaTypedefs.h \ + ../include/ArSerialConnection.h ../include/ArDeviceConnection.h \ + ../include/ariaUtil.h ../include/ArLog.h ../include/ArMutex.h \ + ../include/ArFunctor.h ../include/ArArgumentParser.h \ + ../include/ArArgumentBuilder.h ../include/ArBasePacket.h \ + ../include/ArTcpConnection.h ../include/ArSocket.h \ + ../include/ArSimpleConnector.h ../include/ArRobotConnector.h \ + ../include/ArLaserConnector.h ../include/ArLogFileConnection.h \ + ../include/ArRobotPacket.h ../include/ArRobotPacketSender.h \ + ../include/ArRobotPacketReceiver.h \ + ../include/ArRobotConfigPacketReader.h ../include/ArRobotTypes.h \ + ../include/ArRobotParams.h ../include/ArConfig.h \ + ../include/ArConfigArg.h ../include/ArFileParser.h \ + ../include/ArHasFileName.h ../include/ArConfigGroup.h \ + ../include/ArRobot.h ../include/ArSyncTask.h ../include/ArTaskState.h \ + ../include/ArSensorReading.h ../include/ArTransform.h \ + ../include/ArCondition.h ../include/ArSyncLoop.h \ + ../include/ArASyncTask.h ../include/ArThread.h \ + ../include/ArRobotPacketReaderThread.h ../include/ArActionDesired.h \ + ../include/ArResolver.h ../include/ArInterpolation.h \ + ../include/ArKeyHandler.h ../include/ArCommands.h \ + ../include/ArJoyHandler.h ../include/ariaInternal.h \ + ../include/ArStringInfoGroup.h ../include/ArSonarDevice.h \ + ../include/ArRangeDevice.h ../include/ArRangeBuffer.h \ + ../include/ArDrawingData.h ../include/ArPriorityResolver.h \ + ../include/ArAction.h ../include/ArArg.h ../include/ArActionGroup.h \ + ../include/ArActionGroups.h ../include/ArActionColorFollow.h \ + ../include/ArACTS.h ../include/ArPTZ.h ../include/ArPTZConnector.h \ + ../include/ArActionDeceleratingLimiter.h \ + ../include/ArActionLimiterForwards.h \ + ../include/ArActionLimiterBackwards.h \ + ../include/ArActionLimiterTableSensor.h ../include/ArActionBumpers.h \ + ../include/ArActionIRs.h ../include/ArActionStallRecover.h \ + ../include/ArActionAvoidFront.h ../include/ArActionAvoidSide.h \ + ../include/ArActionConstantVelocity.h ../include/ArActionInput.h \ + ../include/ArActionRobotJoydrive.h ../include/ArActionJoydrive.h \ + ../include/ArActionKeydrive.h ../include/ArActionTriangleDriveTo.h \ + ../include/ArLineFinder.h ../include/ArActionTurn.h \ + ../include/ArActionRatioInput.h ../include/ArActionStop.h \ + ../include/ArActionGoto.h ../include/ArModule.h \ + ../include/ArModuleLoader.h ../include/ArRecurrentTask.h \ + ../include/ArGripper.h ../include/ArSonyPTZ.h ../include/ArRVisionPTZ.h \ + ../include/ArAMPTU.h ../include/ArP2Arm.h ../include/ArSick.h \ + ../include/ArLaser.h ../include/ArRangeDeviceThreaded.h \ + ../include/ArFunctorASyncTask.h ../include/ArLMS2xx.h \ + ../include/ArLMS2xxPacket.h ../include/ArLMS2xxPacketReceiver.h \ + ../include/ArLaserLogger.h ../include/ArIrrfDevice.h \ + ../include/ArDPPTU.h ../include/ArVCC4.h ../include/ArMode.h \ + ../include/ArModes.h ../include/ArTCMCompassRobot.h ../include/ArTCM2.h \ + ../include/ArNetServer.h ../include/ArSignalHandler.h \ + ../include/ArAnalogGyro.h ../include/ArMapInterface.h \ + ../include/ArMapObject.h ../include/ArMapUtils.h ../include/ArMap.h \ + ../include/ArMapComponents.h ../include/ArBumpers.h ../include/ArIRs.h \ + ../include/ArForbiddenRangeDevice.h ../include/ArVersalogicIO.h \ + ../include/ArMTXIO.h ../include/ArActionGotoStraight.h \ + ../include/ArDataLogger.h ../include/ArRobotJoyHandler.h \ + ../include/ArRatioInputKeydrive.h ../include/ArRatioInputJoydrive.h \ + ../include/ArRatioInputRobotJoydrive.h \ + ../include/ArActionMovementParameters.h ../include/ArSoundPlayer.h \ + ../include/ArSoundsQueue.h ../include/ArSpeech.h \ + ../include/ArCameraCollection.h ../include/ArCameraCommands.h \ + ../include/ArSonarAutoDisabler.h ../include/ArActionDriveDistance.h \ + ../include/ArLaserReflectorDevice.h ../include/ArRobotConfig.h \ + ../include/ArTCMCompassDirect.h ../include/ArNMEAParser.h \ + ../include/ArLaserFilter.h ../include/ArUrg.h ../include/ArGPS.h \ + ../include/ArTrimbleGPS.h ../include/ArNovatelGPS.h \ + ../include/ArGPSCoords.h ../include/ArSonarConnector.h \ + ../include/ArBatteryConnector.h ../include/ArLCDConnector.h \ + ../include/ArSonarMTX.h ../include/ArBatteryMTX.h ../include/ArLCDMTX.h \ + ../include/ArSimulatedLaser.h ../include/ArExitErrorSource.h \ + ../include/ArActionLimiterRot.h ../include/ArRobotBatteryPacketReader.h \ + ../include/ArLMS1XX.h ../include/ArUrg_2_0.h \ + ../include/ArActionMovementParametersDebugging.h ../include/ArZippable.h \ + ../include/ArS3Series.h ../include/ArSZSeries.h ../include/ArExport.h \ + include/ArServerModeWander.h ../include/ariaTypedefs.h \ + include/ArNetworking.h include/ArServerBase.h include/ArServerCommands.h \ + include/ArServerClient.h include/ArNetPacket.h \ + include/ArNetPacketReceiverTcp.h include/ArNetPacketSenderTcp.h \ + include/ArServerClientData.h include/ArServerClientIdentifier.h \ + include/ArServerData.h include/ArNetPacketReceiverUdp.h \ + include/ArServerUserInfo.h include/ArClientBase.h \ + include/ArClientCommands.h include/ArClientData.h include/ArMapChanger.h \ + ../include/ariaUtil.h ../include/ArMapInterface.h \ + ../include/ArMapUtils.h ../include/ArMutex.h \ + include/ArCentralForwarder.h include/ArClientSwitchManager.h \ + include/ArServerHandlerCamera.h \ + include/ArServerHandlerCameraCollection.h ../include/ArFunctor.h \ + ../include/ArCameraCollection.h include/ArServerHandlerCommMonitor.h \ + include/ArServerHandlerCommands.h include/ArServerHandlerPopup.h \ + include/ArServerInfoDrawings.h include/ArServerInfoRobot.h \ + include/ArServerInfoSensor.h include/ArServerHandlerMap.h \ + ../include/ArConfig.h include/ArServerMode.h include/ArServerModeDrive.h \ + include/ArServerModeRatioDrive.h include/ArServerModeStop.h \ + include/ArServerModeWander.h include/ArServerHandlerConfig.h \ + include/ArClientHandlerConfig.h include/ArHybridForwarderVideo.h \ + include/ArServerSimpleCommands.h include/ArServerFileUtils.h \ + include/ArClientFileUtils.h include/ArClientSimpleConnector.h \ + include/ArServerHandlerMapping.h include/ArTempDirectoryHelper.h \ + include/ArServerSimpleOpener.h include/ArServerInfoStrings.h \ + include/ArClientArgUtils.h include/ArCentralManager.h \ + include/ArServerModeIdle.h +../obj/ArServerSimpleCommands.o: src/ArServerSimpleCommands.cpp \ + ../include/Aria.h ../include/ariaOSDef.h ../include/ariaTypedefs.h \ + ../include/ArSerialConnection.h ../include/ArDeviceConnection.h \ + ../include/ariaUtil.h ../include/ArLog.h ../include/ArMutex.h \ + ../include/ArFunctor.h ../include/ArArgumentParser.h \ + ../include/ArArgumentBuilder.h ../include/ArBasePacket.h \ + ../include/ArTcpConnection.h ../include/ArSocket.h \ + ../include/ArSimpleConnector.h ../include/ArRobotConnector.h \ + ../include/ArLaserConnector.h ../include/ArLogFileConnection.h \ + ../include/ArRobotPacket.h ../include/ArRobotPacketSender.h \ + ../include/ArRobotPacketReceiver.h \ + ../include/ArRobotConfigPacketReader.h ../include/ArRobotTypes.h \ + ../include/ArRobotParams.h ../include/ArConfig.h \ + ../include/ArConfigArg.h ../include/ArFileParser.h \ + ../include/ArHasFileName.h ../include/ArConfigGroup.h \ + ../include/ArRobot.h ../include/ArSyncTask.h ../include/ArTaskState.h \ + ../include/ArSensorReading.h ../include/ArTransform.h \ + ../include/ArCondition.h ../include/ArSyncLoop.h \ + ../include/ArASyncTask.h ../include/ArThread.h \ + ../include/ArRobotPacketReaderThread.h ../include/ArActionDesired.h \ + ../include/ArResolver.h ../include/ArInterpolation.h \ + ../include/ArKeyHandler.h ../include/ArCommands.h \ + ../include/ArJoyHandler.h ../include/ariaInternal.h \ + ../include/ArStringInfoGroup.h ../include/ArSonarDevice.h \ + ../include/ArRangeDevice.h ../include/ArRangeBuffer.h \ + ../include/ArDrawingData.h ../include/ArPriorityResolver.h \ + ../include/ArAction.h ../include/ArArg.h ../include/ArActionGroup.h \ + ../include/ArActionGroups.h ../include/ArActionColorFollow.h \ + ../include/ArACTS.h ../include/ArPTZ.h ../include/ArPTZConnector.h \ + ../include/ArActionDeceleratingLimiter.h \ + ../include/ArActionLimiterForwards.h \ + ../include/ArActionLimiterBackwards.h \ + ../include/ArActionLimiterTableSensor.h ../include/ArActionBumpers.h \ + ../include/ArActionIRs.h ../include/ArActionStallRecover.h \ + ../include/ArActionAvoidFront.h ../include/ArActionAvoidSide.h \ + ../include/ArActionConstantVelocity.h ../include/ArActionInput.h \ + ../include/ArActionRobotJoydrive.h ../include/ArActionJoydrive.h \ + ../include/ArActionKeydrive.h ../include/ArActionTriangleDriveTo.h \ + ../include/ArLineFinder.h ../include/ArActionTurn.h \ + ../include/ArActionRatioInput.h ../include/ArActionStop.h \ + ../include/ArActionGoto.h ../include/ArModule.h \ + ../include/ArModuleLoader.h ../include/ArRecurrentTask.h \ + ../include/ArGripper.h ../include/ArSonyPTZ.h ../include/ArRVisionPTZ.h \ + ../include/ArAMPTU.h ../include/ArP2Arm.h ../include/ArSick.h \ + ../include/ArLaser.h ../include/ArRangeDeviceThreaded.h \ + ../include/ArFunctorASyncTask.h ../include/ArLMS2xx.h \ + ../include/ArLMS2xxPacket.h ../include/ArLMS2xxPacketReceiver.h \ + ../include/ArLaserLogger.h ../include/ArIrrfDevice.h \ + ../include/ArDPPTU.h ../include/ArVCC4.h ../include/ArMode.h \ + ../include/ArModes.h ../include/ArTCMCompassRobot.h ../include/ArTCM2.h \ + ../include/ArNetServer.h ../include/ArSignalHandler.h \ + ../include/ArAnalogGyro.h ../include/ArMapInterface.h \ + ../include/ArMapObject.h ../include/ArMapUtils.h ../include/ArMap.h \ + ../include/ArMapComponents.h ../include/ArBumpers.h ../include/ArIRs.h \ + ../include/ArForbiddenRangeDevice.h ../include/ArVersalogicIO.h \ + ../include/ArMTXIO.h ../include/ArActionGotoStraight.h \ + ../include/ArDataLogger.h ../include/ArRobotJoyHandler.h \ + ../include/ArRatioInputKeydrive.h ../include/ArRatioInputJoydrive.h \ + ../include/ArRatioInputRobotJoydrive.h \ + ../include/ArActionMovementParameters.h ../include/ArSoundPlayer.h \ + ../include/ArSoundsQueue.h ../include/ArSpeech.h \ + ../include/ArCameraCollection.h ../include/ArCameraCommands.h \ + ../include/ArSonarAutoDisabler.h ../include/ArActionDriveDistance.h \ + ../include/ArLaserReflectorDevice.h ../include/ArRobotConfig.h \ + ../include/ArTCMCompassDirect.h ../include/ArNMEAParser.h \ + ../include/ArLaserFilter.h ../include/ArUrg.h ../include/ArGPS.h \ + ../include/ArTrimbleGPS.h ../include/ArNovatelGPS.h \ + ../include/ArGPSCoords.h ../include/ArSonarConnector.h \ + ../include/ArBatteryConnector.h ../include/ArLCDConnector.h \ + ../include/ArSonarMTX.h ../include/ArBatteryMTX.h ../include/ArLCDMTX.h \ + ../include/ArSimulatedLaser.h ../include/ArExitErrorSource.h \ + ../include/ArActionLimiterRot.h ../include/ArRobotBatteryPacketReader.h \ + ../include/ArLMS1XX.h ../include/ArUrg_2_0.h \ + ../include/ArActionMovementParametersDebugging.h ../include/ArZippable.h \ + ../include/ArS3Series.h ../include/ArSZSeries.h ../include/ArExport.h \ + include/ArServerBase.h include/ArServerCommands.h \ + include/ArServerClient.h include/ArNetPacket.h \ + include/ArNetPacketReceiverTcp.h include/ArNetPacketSenderTcp.h \ + include/ArServerClientData.h include/ArServerClientIdentifier.h \ + include/ArServerData.h include/ArNetPacketReceiverUdp.h \ + include/ArServerUserInfo.h include/ArServerSimpleCommands.h \ + include/ArServerBase.h include/ArServerHandlerCommands.h \ + include/ArServerHandlerPopup.h +../obj/ArServerSimpleOpener.o: src/ArServerSimpleOpener.cpp ../include/Aria.h \ + ../include/ariaOSDef.h ../include/ariaTypedefs.h \ + ../include/ArSerialConnection.h ../include/ArDeviceConnection.h \ + ../include/ariaUtil.h ../include/ArLog.h ../include/ArMutex.h \ + ../include/ArFunctor.h ../include/ArArgumentParser.h \ + ../include/ArArgumentBuilder.h ../include/ArBasePacket.h \ + ../include/ArTcpConnection.h ../include/ArSocket.h \ + ../include/ArSimpleConnector.h ../include/ArRobotConnector.h \ + ../include/ArLaserConnector.h ../include/ArLogFileConnection.h \ + ../include/ArRobotPacket.h ../include/ArRobotPacketSender.h \ + ../include/ArRobotPacketReceiver.h \ + ../include/ArRobotConfigPacketReader.h ../include/ArRobotTypes.h \ + ../include/ArRobotParams.h ../include/ArConfig.h \ + ../include/ArConfigArg.h ../include/ArFileParser.h \ + ../include/ArHasFileName.h ../include/ArConfigGroup.h \ + ../include/ArRobot.h ../include/ArSyncTask.h ../include/ArTaskState.h \ + ../include/ArSensorReading.h ../include/ArTransform.h \ + ../include/ArCondition.h ../include/ArSyncLoop.h \ + ../include/ArASyncTask.h ../include/ArThread.h \ + ../include/ArRobotPacketReaderThread.h ../include/ArActionDesired.h \ + ../include/ArResolver.h ../include/ArInterpolation.h \ + ../include/ArKeyHandler.h ../include/ArCommands.h \ + ../include/ArJoyHandler.h ../include/ariaInternal.h \ + ../include/ArStringInfoGroup.h ../include/ArSonarDevice.h \ + ../include/ArRangeDevice.h ../include/ArRangeBuffer.h \ + ../include/ArDrawingData.h ../include/ArPriorityResolver.h \ + ../include/ArAction.h ../include/ArArg.h ../include/ArActionGroup.h \ + ../include/ArActionGroups.h ../include/ArActionColorFollow.h \ + ../include/ArACTS.h ../include/ArPTZ.h ../include/ArPTZConnector.h \ + ../include/ArActionDeceleratingLimiter.h \ + ../include/ArActionLimiterForwards.h \ + ../include/ArActionLimiterBackwards.h \ + ../include/ArActionLimiterTableSensor.h ../include/ArActionBumpers.h \ + ../include/ArActionIRs.h ../include/ArActionStallRecover.h \ + ../include/ArActionAvoidFront.h ../include/ArActionAvoidSide.h \ + ../include/ArActionConstantVelocity.h ../include/ArActionInput.h \ + ../include/ArActionRobotJoydrive.h ../include/ArActionJoydrive.h \ + ../include/ArActionKeydrive.h ../include/ArActionTriangleDriveTo.h \ + ../include/ArLineFinder.h ../include/ArActionTurn.h \ + ../include/ArActionRatioInput.h ../include/ArActionStop.h \ + ../include/ArActionGoto.h ../include/ArModule.h \ + ../include/ArModuleLoader.h ../include/ArRecurrentTask.h \ + ../include/ArGripper.h ../include/ArSonyPTZ.h ../include/ArRVisionPTZ.h \ + ../include/ArAMPTU.h ../include/ArP2Arm.h ../include/ArSick.h \ + ../include/ArLaser.h ../include/ArRangeDeviceThreaded.h \ + ../include/ArFunctorASyncTask.h ../include/ArLMS2xx.h \ + ../include/ArLMS2xxPacket.h ../include/ArLMS2xxPacketReceiver.h \ + ../include/ArLaserLogger.h ../include/ArIrrfDevice.h \ + ../include/ArDPPTU.h ../include/ArVCC4.h ../include/ArMode.h \ + ../include/ArModes.h ../include/ArTCMCompassRobot.h ../include/ArTCM2.h \ + ../include/ArNetServer.h ../include/ArSignalHandler.h \ + ../include/ArAnalogGyro.h ../include/ArMapInterface.h \ + ../include/ArMapObject.h ../include/ArMapUtils.h ../include/ArMap.h \ + ../include/ArMapComponents.h ../include/ArBumpers.h ../include/ArIRs.h \ + ../include/ArForbiddenRangeDevice.h ../include/ArVersalogicIO.h \ + ../include/ArMTXIO.h ../include/ArActionGotoStraight.h \ + ../include/ArDataLogger.h ../include/ArRobotJoyHandler.h \ + ../include/ArRatioInputKeydrive.h ../include/ArRatioInputJoydrive.h \ + ../include/ArRatioInputRobotJoydrive.h \ + ../include/ArActionMovementParameters.h ../include/ArSoundPlayer.h \ + ../include/ArSoundsQueue.h ../include/ArSpeech.h \ + ../include/ArCameraCollection.h ../include/ArCameraCommands.h \ + ../include/ArSonarAutoDisabler.h ../include/ArActionDriveDistance.h \ + ../include/ArLaserReflectorDevice.h ../include/ArRobotConfig.h \ + ../include/ArTCMCompassDirect.h ../include/ArNMEAParser.h \ + ../include/ArLaserFilter.h ../include/ArUrg.h ../include/ArGPS.h \ + ../include/ArTrimbleGPS.h ../include/ArNovatelGPS.h \ + ../include/ArGPSCoords.h ../include/ArSonarConnector.h \ + ../include/ArBatteryConnector.h ../include/ArLCDConnector.h \ + ../include/ArSonarMTX.h ../include/ArBatteryMTX.h ../include/ArLCDMTX.h \ + ../include/ArSimulatedLaser.h ../include/ArExitErrorSource.h \ + ../include/ArActionLimiterRot.h ../include/ArRobotBatteryPacketReader.h \ + ../include/ArLMS1XX.h ../include/ArUrg_2_0.h \ + ../include/ArActionMovementParametersDebugging.h ../include/ArZippable.h \ + ../include/ArS3Series.h ../include/ArSZSeries.h ../include/ArExport.h \ + include/ArServerBase.h include/ArServerCommands.h \ + include/ArServerClient.h include/ArNetPacket.h \ + include/ArNetPacketReceiverTcp.h include/ArNetPacketSenderTcp.h \ + include/ArServerClientData.h include/ArServerClientIdentifier.h \ + include/ArServerData.h include/ArNetPacketReceiverUdp.h \ + include/ArServerUserInfo.h include/ArServerSimpleOpener.h +../obj/ArServerUserInfo.o: src/ArServerUserInfo.cpp ../include/Aria.h \ + ../include/ariaOSDef.h ../include/ariaTypedefs.h \ + ../include/ArSerialConnection.h ../include/ArDeviceConnection.h \ + ../include/ariaUtil.h ../include/ArLog.h ../include/ArMutex.h \ + ../include/ArFunctor.h ../include/ArArgumentParser.h \ + ../include/ArArgumentBuilder.h ../include/ArBasePacket.h \ + ../include/ArTcpConnection.h ../include/ArSocket.h \ + ../include/ArSimpleConnector.h ../include/ArRobotConnector.h \ + ../include/ArLaserConnector.h ../include/ArLogFileConnection.h \ + ../include/ArRobotPacket.h ../include/ArRobotPacketSender.h \ + ../include/ArRobotPacketReceiver.h \ + ../include/ArRobotConfigPacketReader.h ../include/ArRobotTypes.h \ + ../include/ArRobotParams.h ../include/ArConfig.h \ + ../include/ArConfigArg.h ../include/ArFileParser.h \ + ../include/ArHasFileName.h ../include/ArConfigGroup.h \ + ../include/ArRobot.h ../include/ArSyncTask.h ../include/ArTaskState.h \ + ../include/ArSensorReading.h ../include/ArTransform.h \ + ../include/ArCondition.h ../include/ArSyncLoop.h \ + ../include/ArASyncTask.h ../include/ArThread.h \ + ../include/ArRobotPacketReaderThread.h ../include/ArActionDesired.h \ + ../include/ArResolver.h ../include/ArInterpolation.h \ + ../include/ArKeyHandler.h ../include/ArCommands.h \ + ../include/ArJoyHandler.h ../include/ariaInternal.h \ + ../include/ArStringInfoGroup.h ../include/ArSonarDevice.h \ + ../include/ArRangeDevice.h ../include/ArRangeBuffer.h \ + ../include/ArDrawingData.h ../include/ArPriorityResolver.h \ + ../include/ArAction.h ../include/ArArg.h ../include/ArActionGroup.h \ + ../include/ArActionGroups.h ../include/ArActionColorFollow.h \ + ../include/ArACTS.h ../include/ArPTZ.h ../include/ArPTZConnector.h \ + ../include/ArActionDeceleratingLimiter.h \ + ../include/ArActionLimiterForwards.h \ + ../include/ArActionLimiterBackwards.h \ + ../include/ArActionLimiterTableSensor.h ../include/ArActionBumpers.h \ + ../include/ArActionIRs.h ../include/ArActionStallRecover.h \ + ../include/ArActionAvoidFront.h ../include/ArActionAvoidSide.h \ + ../include/ArActionConstantVelocity.h ../include/ArActionInput.h \ + ../include/ArActionRobotJoydrive.h ../include/ArActionJoydrive.h \ + ../include/ArActionKeydrive.h ../include/ArActionTriangleDriveTo.h \ + ../include/ArLineFinder.h ../include/ArActionTurn.h \ + ../include/ArActionRatioInput.h ../include/ArActionStop.h \ + ../include/ArActionGoto.h ../include/ArModule.h \ + ../include/ArModuleLoader.h ../include/ArRecurrentTask.h \ + ../include/ArGripper.h ../include/ArSonyPTZ.h ../include/ArRVisionPTZ.h \ + ../include/ArAMPTU.h ../include/ArP2Arm.h ../include/ArSick.h \ + ../include/ArLaser.h ../include/ArRangeDeviceThreaded.h \ + ../include/ArFunctorASyncTask.h ../include/ArLMS2xx.h \ + ../include/ArLMS2xxPacket.h ../include/ArLMS2xxPacketReceiver.h \ + ../include/ArLaserLogger.h ../include/ArIrrfDevice.h \ + ../include/ArDPPTU.h ../include/ArVCC4.h ../include/ArMode.h \ + ../include/ArModes.h ../include/ArTCMCompassRobot.h ../include/ArTCM2.h \ + ../include/ArNetServer.h ../include/ArSignalHandler.h \ + ../include/ArAnalogGyro.h ../include/ArMapInterface.h \ + ../include/ArMapObject.h ../include/ArMapUtils.h ../include/ArMap.h \ + ../include/ArMapComponents.h ../include/ArBumpers.h ../include/ArIRs.h \ + ../include/ArForbiddenRangeDevice.h ../include/ArVersalogicIO.h \ + ../include/ArMTXIO.h ../include/ArActionGotoStraight.h \ + ../include/ArDataLogger.h ../include/ArRobotJoyHandler.h \ + ../include/ArRatioInputKeydrive.h ../include/ArRatioInputJoydrive.h \ + ../include/ArRatioInputRobotJoydrive.h \ + ../include/ArActionMovementParameters.h ../include/ArSoundPlayer.h \ + ../include/ArSoundsQueue.h ../include/ArSpeech.h \ + ../include/ArCameraCollection.h ../include/ArCameraCommands.h \ + ../include/ArSonarAutoDisabler.h ../include/ArActionDriveDistance.h \ + ../include/ArLaserReflectorDevice.h ../include/ArRobotConfig.h \ + ../include/ArTCMCompassDirect.h ../include/ArNMEAParser.h \ + ../include/ArLaserFilter.h ../include/ArUrg.h ../include/ArGPS.h \ + ../include/ArTrimbleGPS.h ../include/ArNovatelGPS.h \ + ../include/ArGPSCoords.h ../include/ArSonarConnector.h \ + ../include/ArBatteryConnector.h ../include/ArLCDConnector.h \ + ../include/ArSonarMTX.h ../include/ArBatteryMTX.h ../include/ArLCDMTX.h \ + ../include/ArSimulatedLaser.h ../include/ArExitErrorSource.h \ + ../include/ArActionLimiterRot.h ../include/ArRobotBatteryPacketReader.h \ + ../include/ArLMS1XX.h ../include/ArUrg_2_0.h \ + ../include/ArActionMovementParametersDebugging.h ../include/ArZippable.h \ + ../include/ArS3Series.h ../include/ArSZSeries.h ../include/ArExport.h \ + include/ArServerUserInfo.h ../include/md5.h +../obj/ArTempDirectoryHelper.o: src/ArTempDirectoryHelper.cpp \ + ../include/ArExport.h include/ArTempDirectoryHelper.h \ + ../include/ariaTypedefs.h ../include/ArFunctor.h \ + ../include/ariaTypedefs.h ../include/ariaOSDef.h ../include/ArLog.h \ + ../include/ArMutex.h ../include/ArFunctor.h ../include/ariaUtil.h \ + ../include/ArLog.h ../include/ArArgumentParser.h \ + ../include/ArArgumentBuilder.h +../obj/md5.o: src/md5.cpp ../include/ArExport.h ../include/md5.h +examples/clientCommandLister: examples/clientCommandLister.cpp ../include/Aria.h \ + ../include/ariaOSDef.h ../include/ariaTypedefs.h \ + ../include/ArSerialConnection.h ../include/ArDeviceConnection.h \ + ../include/ariaUtil.h ../include/ArLog.h ../include/ArMutex.h \ + ../include/ArFunctor.h ../include/ArArgumentParser.h \ + ../include/ArArgumentBuilder.h ../include/ArBasePacket.h \ + ../include/ArTcpConnection.h ../include/ArSocket.h \ + ../include/ArSimpleConnector.h ../include/ArRobotConnector.h \ + ../include/ArLaserConnector.h ../include/ArLogFileConnection.h \ + ../include/ArRobotPacket.h ../include/ArRobotPacketSender.h \ + ../include/ArRobotPacketReceiver.h \ + ../include/ArRobotConfigPacketReader.h ../include/ArRobotTypes.h \ + ../include/ArRobotParams.h ../include/ArConfig.h \ + ../include/ArConfigArg.h ../include/ArFileParser.h \ + ../include/ArHasFileName.h ../include/ArConfigGroup.h \ + ../include/ArRobot.h ../include/ArSyncTask.h ../include/ArTaskState.h \ + ../include/ArSensorReading.h ../include/ArTransform.h \ + ../include/ArCondition.h ../include/ArSyncLoop.h \ + ../include/ArASyncTask.h ../include/ArThread.h \ + ../include/ArRobotPacketReaderThread.h ../include/ArActionDesired.h \ + ../include/ArResolver.h ../include/ArInterpolation.h \ + ../include/ArKeyHandler.h ../include/ArCommands.h \ + ../include/ArJoyHandler.h ../include/ariaInternal.h \ + ../include/ArStringInfoGroup.h ../include/ArSonarDevice.h \ + ../include/ArRangeDevice.h ../include/ArRangeBuffer.h \ + ../include/ArDrawingData.h ../include/ArPriorityResolver.h \ + ../include/ArAction.h ../include/ArArg.h ../include/ArActionGroup.h \ + ../include/ArActionGroups.h ../include/ArActionColorFollow.h \ + ../include/ArACTS.h ../include/ArPTZ.h ../include/ArPTZConnector.h \ + ../include/ArActionDeceleratingLimiter.h \ + ../include/ArActionLimiterForwards.h \ + ../include/ArActionLimiterBackwards.h \ + ../include/ArActionLimiterTableSensor.h ../include/ArActionBumpers.h \ + ../include/ArActionIRs.h ../include/ArActionStallRecover.h \ + ../include/ArActionAvoidFront.h ../include/ArActionAvoidSide.h \ + ../include/ArActionConstantVelocity.h ../include/ArActionInput.h \ + ../include/ArActionRobotJoydrive.h ../include/ArActionJoydrive.h \ + ../include/ArActionKeydrive.h ../include/ArActionTriangleDriveTo.h \ + ../include/ArLineFinder.h ../include/ArActionTurn.h \ + ../include/ArActionRatioInput.h ../include/ArActionStop.h \ + ../include/ArActionGoto.h ../include/ArModule.h \ + ../include/ArModuleLoader.h ../include/ArRecurrentTask.h \ + ../include/ArGripper.h ../include/ArSonyPTZ.h ../include/ArRVisionPTZ.h \ + ../include/ArAMPTU.h ../include/ArP2Arm.h ../include/ArSick.h \ + ../include/ArLaser.h ../include/ArRangeDeviceThreaded.h \ + ../include/ArFunctorASyncTask.h ../include/ArLMS2xx.h \ + ../include/ArLMS2xxPacket.h ../include/ArLMS2xxPacketReceiver.h \ + ../include/ArLaserLogger.h ../include/ArIrrfDevice.h \ + ../include/ArDPPTU.h ../include/ArVCC4.h ../include/ArMode.h \ + ../include/ArModes.h ../include/ArTCMCompassRobot.h ../include/ArTCM2.h \ + ../include/ArNetServer.h ../include/ArSignalHandler.h \ + ../include/ArAnalogGyro.h ../include/ArMapInterface.h \ + ../include/ArMapObject.h ../include/ArMapUtils.h ../include/ArMap.h \ + ../include/ArMapComponents.h ../include/ArBumpers.h ../include/ArIRs.h \ + ../include/ArForbiddenRangeDevice.h ../include/ArVersalogicIO.h \ + ../include/ArMTXIO.h ../include/ArActionGotoStraight.h \ + ../include/ArDataLogger.h ../include/ArRobotJoyHandler.h \ + ../include/ArRatioInputKeydrive.h ../include/ArRatioInputJoydrive.h \ + ../include/ArRatioInputRobotJoydrive.h \ + ../include/ArActionMovementParameters.h ../include/ArSoundPlayer.h \ + ../include/ArSoundsQueue.h ../include/ArSpeech.h \ + ../include/ArCameraCollection.h ../include/ArCameraCommands.h \ + ../include/ArSonarAutoDisabler.h ../include/ArActionDriveDistance.h \ + ../include/ArLaserReflectorDevice.h ../include/ArRobotConfig.h \ + ../include/ArTCMCompassDirect.h ../include/ArNMEAParser.h \ + ../include/ArLaserFilter.h ../include/ArUrg.h ../include/ArGPS.h \ + ../include/ArTrimbleGPS.h ../include/ArNovatelGPS.h \ + ../include/ArGPSCoords.h ../include/ArSonarConnector.h \ + ../include/ArBatteryConnector.h ../include/ArLCDConnector.h \ + ../include/ArSonarMTX.h ../include/ArBatteryMTX.h ../include/ArLCDMTX.h \ + ../include/ArSimulatedLaser.h ../include/ArExitErrorSource.h \ + ../include/ArActionLimiterRot.h ../include/ArRobotBatteryPacketReader.h \ + ../include/ArLMS1XX.h ../include/ArUrg_2_0.h \ + ../include/ArActionMovementParametersDebugging.h ../include/ArZippable.h \ + ../include/ArS3Series.h ../include/ArSZSeries.h include/ArNetworking.h \ + include/ArServerBase.h include/ArServerCommands.h \ + include/ArServerClient.h include/ArNetPacket.h \ + include/ArNetPacketReceiverTcp.h include/ArNetPacketSenderTcp.h \ + include/ArServerClientData.h include/ArServerClientIdentifier.h \ + include/ArServerData.h include/ArNetPacketReceiverUdp.h \ + include/ArServerUserInfo.h include/ArClientBase.h \ + include/ArClientCommands.h include/ArClientData.h include/ArMapChanger.h \ + ../include/ariaTypedefs.h ../include/ariaUtil.h \ + ../include/ArMapInterface.h ../include/ArMapUtils.h ../include/ArMutex.h \ + include/ArCentralForwarder.h include/ArClientSwitchManager.h \ + include/ArServerHandlerCamera.h include/ArNetworking.h \ + include/ArServerHandlerCameraCollection.h ../include/ArExport.h \ + ../include/ArFunctor.h ../include/ArCameraCollection.h \ + include/ArServerHandlerCommMonitor.h include/ArServerHandlerCommands.h \ + include/ArServerHandlerPopup.h include/ArServerInfoDrawings.h \ + include/ArServerInfoRobot.h include/ArServerInfoSensor.h \ + include/ArServerHandlerMap.h ../include/ArConfig.h \ + include/ArServerMode.h include/ArServerModeDrive.h \ + include/ArServerModeRatioDrive.h include/ArServerModeStop.h \ + include/ArServerModeWander.h include/ArServerHandlerConfig.h \ + include/ArClientHandlerConfig.h include/ArHybridForwarderVideo.h \ + include/ArServerSimpleCommands.h include/ArServerFileUtils.h \ + include/ArClientFileUtils.h include/ArClientSimpleConnector.h \ + include/ArServerHandlerMapping.h include/ArTempDirectoryHelper.h \ + include/ArServerSimpleOpener.h include/ArServerInfoStrings.h \ + include/ArClientArgUtils.h include/ArCentralManager.h \ + include/ArServerModeIdle.h +examples/clientDemo: examples/clientDemo.cpp ../include/Aria.h \ + ../include/ariaOSDef.h ../include/ariaTypedefs.h \ + ../include/ArSerialConnection.h ../include/ArDeviceConnection.h \ + ../include/ariaUtil.h ../include/ArLog.h ../include/ArMutex.h \ + ../include/ArFunctor.h ../include/ArArgumentParser.h \ + ../include/ArArgumentBuilder.h ../include/ArBasePacket.h \ + ../include/ArTcpConnection.h ../include/ArSocket.h \ + ../include/ArSimpleConnector.h ../include/ArRobotConnector.h \ + ../include/ArLaserConnector.h ../include/ArLogFileConnection.h \ + ../include/ArRobotPacket.h ../include/ArRobotPacketSender.h \ + ../include/ArRobotPacketReceiver.h \ + ../include/ArRobotConfigPacketReader.h ../include/ArRobotTypes.h \ + ../include/ArRobotParams.h ../include/ArConfig.h \ + ../include/ArConfigArg.h ../include/ArFileParser.h \ + ../include/ArHasFileName.h ../include/ArConfigGroup.h \ + ../include/ArRobot.h ../include/ArSyncTask.h ../include/ArTaskState.h \ + ../include/ArSensorReading.h ../include/ArTransform.h \ + ../include/ArCondition.h ../include/ArSyncLoop.h \ + ../include/ArASyncTask.h ../include/ArThread.h \ + ../include/ArRobotPacketReaderThread.h ../include/ArActionDesired.h \ + ../include/ArResolver.h ../include/ArInterpolation.h \ + ../include/ArKeyHandler.h ../include/ArCommands.h \ + ../include/ArJoyHandler.h ../include/ariaInternal.h \ + ../include/ArStringInfoGroup.h ../include/ArSonarDevice.h \ + ../include/ArRangeDevice.h ../include/ArRangeBuffer.h \ + ../include/ArDrawingData.h ../include/ArPriorityResolver.h \ + ../include/ArAction.h ../include/ArArg.h ../include/ArActionGroup.h \ + ../include/ArActionGroups.h ../include/ArActionColorFollow.h \ + ../include/ArACTS.h ../include/ArPTZ.h ../include/ArPTZConnector.h \ + ../include/ArActionDeceleratingLimiter.h \ + ../include/ArActionLimiterForwards.h \ + ../include/ArActionLimiterBackwards.h \ + ../include/ArActionLimiterTableSensor.h ../include/ArActionBumpers.h \ + ../include/ArActionIRs.h ../include/ArActionStallRecover.h \ + ../include/ArActionAvoidFront.h ../include/ArActionAvoidSide.h \ + ../include/ArActionConstantVelocity.h ../include/ArActionInput.h \ + ../include/ArActionRobotJoydrive.h ../include/ArActionJoydrive.h \ + ../include/ArActionKeydrive.h ../include/ArActionTriangleDriveTo.h \ + ../include/ArLineFinder.h ../include/ArActionTurn.h \ + ../include/ArActionRatioInput.h ../include/ArActionStop.h \ + ../include/ArActionGoto.h ../include/ArModule.h \ + ../include/ArModuleLoader.h ../include/ArRecurrentTask.h \ + ../include/ArGripper.h ../include/ArSonyPTZ.h ../include/ArRVisionPTZ.h \ + ../include/ArAMPTU.h ../include/ArP2Arm.h ../include/ArSick.h \ + ../include/ArLaser.h ../include/ArRangeDeviceThreaded.h \ + ../include/ArFunctorASyncTask.h ../include/ArLMS2xx.h \ + ../include/ArLMS2xxPacket.h ../include/ArLMS2xxPacketReceiver.h \ + ../include/ArLaserLogger.h ../include/ArIrrfDevice.h \ + ../include/ArDPPTU.h ../include/ArVCC4.h ../include/ArMode.h \ + ../include/ArModes.h ../include/ArTCMCompassRobot.h ../include/ArTCM2.h \ + ../include/ArNetServer.h ../include/ArSignalHandler.h \ + ../include/ArAnalogGyro.h ../include/ArMapInterface.h \ + ../include/ArMapObject.h ../include/ArMapUtils.h ../include/ArMap.h \ + ../include/ArMapComponents.h ../include/ArBumpers.h ../include/ArIRs.h \ + ../include/ArForbiddenRangeDevice.h ../include/ArVersalogicIO.h \ + ../include/ArMTXIO.h ../include/ArActionGotoStraight.h \ + ../include/ArDataLogger.h ../include/ArRobotJoyHandler.h \ + ../include/ArRatioInputKeydrive.h ../include/ArRatioInputJoydrive.h \ + ../include/ArRatioInputRobotJoydrive.h \ + ../include/ArActionMovementParameters.h ../include/ArSoundPlayer.h \ + ../include/ArSoundsQueue.h ../include/ArSpeech.h \ + ../include/ArCameraCollection.h ../include/ArCameraCommands.h \ + ../include/ArSonarAutoDisabler.h ../include/ArActionDriveDistance.h \ + ../include/ArLaserReflectorDevice.h ../include/ArRobotConfig.h \ + ../include/ArTCMCompassDirect.h ../include/ArNMEAParser.h \ + ../include/ArLaserFilter.h ../include/ArUrg.h ../include/ArGPS.h \ + ../include/ArTrimbleGPS.h ../include/ArNovatelGPS.h \ + ../include/ArGPSCoords.h ../include/ArSonarConnector.h \ + ../include/ArBatteryConnector.h ../include/ArLCDConnector.h \ + ../include/ArSonarMTX.h ../include/ArBatteryMTX.h ../include/ArLCDMTX.h \ + ../include/ArSimulatedLaser.h ../include/ArExitErrorSource.h \ + ../include/ArActionLimiterRot.h ../include/ArRobotBatteryPacketReader.h \ + ../include/ArLMS1XX.h ../include/ArUrg_2_0.h \ + ../include/ArActionMovementParametersDebugging.h ../include/ArZippable.h \ + ../include/ArS3Series.h ../include/ArSZSeries.h include/ArNetworking.h \ + include/ArServerBase.h include/ArServerCommands.h \ + include/ArServerClient.h include/ArNetPacket.h \ + include/ArNetPacketReceiverTcp.h include/ArNetPacketSenderTcp.h \ + include/ArServerClientData.h include/ArServerClientIdentifier.h \ + include/ArServerData.h include/ArNetPacketReceiverUdp.h \ + include/ArServerUserInfo.h include/ArClientBase.h \ + include/ArClientCommands.h include/ArClientData.h include/ArMapChanger.h \ + ../include/ariaTypedefs.h ../include/ariaUtil.h \ + ../include/ArMapInterface.h ../include/ArMapUtils.h ../include/ArMutex.h \ + include/ArCentralForwarder.h include/ArClientSwitchManager.h \ + include/ArServerHandlerCamera.h include/ArNetworking.h \ + include/ArServerHandlerCameraCollection.h ../include/ArExport.h \ + ../include/ArFunctor.h ../include/ArCameraCollection.h \ + include/ArServerHandlerCommMonitor.h include/ArServerHandlerCommands.h \ + include/ArServerHandlerPopup.h include/ArServerInfoDrawings.h \ + include/ArServerInfoRobot.h include/ArServerInfoSensor.h \ + include/ArServerHandlerMap.h ../include/ArConfig.h \ + include/ArServerMode.h include/ArServerModeDrive.h \ + include/ArServerModeRatioDrive.h include/ArServerModeStop.h \ + include/ArServerModeWander.h include/ArServerHandlerConfig.h \ + include/ArClientHandlerConfig.h include/ArHybridForwarderVideo.h \ + include/ArServerSimpleCommands.h include/ArServerFileUtils.h \ + include/ArClientFileUtils.h include/ArClientSimpleConnector.h \ + include/ArServerHandlerMapping.h include/ArTempDirectoryHelper.h \ + include/ArServerSimpleOpener.h include/ArServerInfoStrings.h \ + include/ArClientArgUtils.h include/ArCentralManager.h \ + include/ArServerModeIdle.h +examples/configClient: examples/configClient.cpp ../include/Aria.h \ + ../include/ariaOSDef.h ../include/ariaTypedefs.h \ + ../include/ArSerialConnection.h ../include/ArDeviceConnection.h \ + ../include/ariaUtil.h ../include/ArLog.h ../include/ArMutex.h \ + ../include/ArFunctor.h ../include/ArArgumentParser.h \ + ../include/ArArgumentBuilder.h ../include/ArBasePacket.h \ + ../include/ArTcpConnection.h ../include/ArSocket.h \ + ../include/ArSimpleConnector.h ../include/ArRobotConnector.h \ + ../include/ArLaserConnector.h ../include/ArLogFileConnection.h \ + ../include/ArRobotPacket.h ../include/ArRobotPacketSender.h \ + ../include/ArRobotPacketReceiver.h \ + ../include/ArRobotConfigPacketReader.h ../include/ArRobotTypes.h \ + ../include/ArRobotParams.h ../include/ArConfig.h \ + ../include/ArConfigArg.h ../include/ArFileParser.h \ + ../include/ArHasFileName.h ../include/ArConfigGroup.h \ + ../include/ArRobot.h ../include/ArSyncTask.h ../include/ArTaskState.h \ + ../include/ArSensorReading.h ../include/ArTransform.h \ + ../include/ArCondition.h ../include/ArSyncLoop.h \ + ../include/ArASyncTask.h ../include/ArThread.h \ + ../include/ArRobotPacketReaderThread.h ../include/ArActionDesired.h \ + ../include/ArResolver.h ../include/ArInterpolation.h \ + ../include/ArKeyHandler.h ../include/ArCommands.h \ + ../include/ArJoyHandler.h ../include/ariaInternal.h \ + ../include/ArStringInfoGroup.h ../include/ArSonarDevice.h \ + ../include/ArRangeDevice.h ../include/ArRangeBuffer.h \ + ../include/ArDrawingData.h ../include/ArPriorityResolver.h \ + ../include/ArAction.h ../include/ArArg.h ../include/ArActionGroup.h \ + ../include/ArActionGroups.h ../include/ArActionColorFollow.h \ + ../include/ArACTS.h ../include/ArPTZ.h ../include/ArPTZConnector.h \ + ../include/ArActionDeceleratingLimiter.h \ + ../include/ArActionLimiterForwards.h \ + ../include/ArActionLimiterBackwards.h \ + ../include/ArActionLimiterTableSensor.h ../include/ArActionBumpers.h \ + ../include/ArActionIRs.h ../include/ArActionStallRecover.h \ + ../include/ArActionAvoidFront.h ../include/ArActionAvoidSide.h \ + ../include/ArActionConstantVelocity.h ../include/ArActionInput.h \ + ../include/ArActionRobotJoydrive.h ../include/ArActionJoydrive.h \ + ../include/ArActionKeydrive.h ../include/ArActionTriangleDriveTo.h \ + ../include/ArLineFinder.h ../include/ArActionTurn.h \ + ../include/ArActionRatioInput.h ../include/ArActionStop.h \ + ../include/ArActionGoto.h ../include/ArModule.h \ + ../include/ArModuleLoader.h ../include/ArRecurrentTask.h \ + ../include/ArGripper.h ../include/ArSonyPTZ.h ../include/ArRVisionPTZ.h \ + ../include/ArAMPTU.h ../include/ArP2Arm.h ../include/ArSick.h \ + ../include/ArLaser.h ../include/ArRangeDeviceThreaded.h \ + ../include/ArFunctorASyncTask.h ../include/ArLMS2xx.h \ + ../include/ArLMS2xxPacket.h ../include/ArLMS2xxPacketReceiver.h \ + ../include/ArLaserLogger.h ../include/ArIrrfDevice.h \ + ../include/ArDPPTU.h ../include/ArVCC4.h ../include/ArMode.h \ + ../include/ArModes.h ../include/ArTCMCompassRobot.h ../include/ArTCM2.h \ + ../include/ArNetServer.h ../include/ArSignalHandler.h \ + ../include/ArAnalogGyro.h ../include/ArMapInterface.h \ + ../include/ArMapObject.h ../include/ArMapUtils.h ../include/ArMap.h \ + ../include/ArMapComponents.h ../include/ArBumpers.h ../include/ArIRs.h \ + ../include/ArForbiddenRangeDevice.h ../include/ArVersalogicIO.h \ + ../include/ArMTXIO.h ../include/ArActionGotoStraight.h \ + ../include/ArDataLogger.h ../include/ArRobotJoyHandler.h \ + ../include/ArRatioInputKeydrive.h ../include/ArRatioInputJoydrive.h \ + ../include/ArRatioInputRobotJoydrive.h \ + ../include/ArActionMovementParameters.h ../include/ArSoundPlayer.h \ + ../include/ArSoundsQueue.h ../include/ArSpeech.h \ + ../include/ArCameraCollection.h ../include/ArCameraCommands.h \ + ../include/ArSonarAutoDisabler.h ../include/ArActionDriveDistance.h \ + ../include/ArLaserReflectorDevice.h ../include/ArRobotConfig.h \ + ../include/ArTCMCompassDirect.h ../include/ArNMEAParser.h \ + ../include/ArLaserFilter.h ../include/ArUrg.h ../include/ArGPS.h \ + ../include/ArTrimbleGPS.h ../include/ArNovatelGPS.h \ + ../include/ArGPSCoords.h ../include/ArSonarConnector.h \ + ../include/ArBatteryConnector.h ../include/ArLCDConnector.h \ + ../include/ArSonarMTX.h ../include/ArBatteryMTX.h ../include/ArLCDMTX.h \ + ../include/ArSimulatedLaser.h ../include/ArExitErrorSource.h \ + ../include/ArActionLimiterRot.h ../include/ArRobotBatteryPacketReader.h \ + ../include/ArLMS1XX.h ../include/ArUrg_2_0.h \ + ../include/ArActionMovementParametersDebugging.h ../include/ArZippable.h \ + ../include/ArS3Series.h ../include/ArSZSeries.h include/ArNetworking.h \ + include/ArServerBase.h include/ArServerCommands.h \ + include/ArServerClient.h include/ArNetPacket.h \ + include/ArNetPacketReceiverTcp.h include/ArNetPacketSenderTcp.h \ + include/ArServerClientData.h include/ArServerClientIdentifier.h \ + include/ArServerData.h include/ArNetPacketReceiverUdp.h \ + include/ArServerUserInfo.h include/ArClientBase.h \ + include/ArClientCommands.h include/ArClientData.h include/ArMapChanger.h \ + ../include/ariaTypedefs.h ../include/ariaUtil.h \ + ../include/ArMapInterface.h ../include/ArMapUtils.h ../include/ArMutex.h \ + include/ArCentralForwarder.h include/ArClientSwitchManager.h \ + include/ArServerHandlerCamera.h include/ArNetworking.h \ + include/ArServerHandlerCameraCollection.h ../include/ArExport.h \ + ../include/ArFunctor.h ../include/ArCameraCollection.h \ + include/ArServerHandlerCommMonitor.h include/ArServerHandlerCommands.h \ + include/ArServerHandlerPopup.h include/ArServerInfoDrawings.h \ + include/ArServerInfoRobot.h include/ArServerInfoSensor.h \ + include/ArServerHandlerMap.h ../include/ArConfig.h \ + include/ArServerMode.h include/ArServerModeDrive.h \ + include/ArServerModeRatioDrive.h include/ArServerModeStop.h \ + include/ArServerModeWander.h include/ArServerHandlerConfig.h \ + include/ArClientHandlerConfig.h include/ArHybridForwarderVideo.h \ + include/ArServerSimpleCommands.h include/ArServerFileUtils.h \ + include/ArClientFileUtils.h include/ArClientSimpleConnector.h \ + include/ArServerHandlerMapping.h include/ArTempDirectoryHelper.h \ + include/ArServerSimpleOpener.h include/ArServerInfoStrings.h \ + include/ArClientArgUtils.h include/ArCentralManager.h \ + include/ArServerModeIdle.h +examples/configClientToServer: examples/configClientToServer.cpp \ + ../include/Aria.h ../include/ariaOSDef.h ../include/ariaTypedefs.h \ + ../include/ArSerialConnection.h ../include/ArDeviceConnection.h \ + ../include/ariaUtil.h ../include/ArLog.h ../include/ArMutex.h \ + ../include/ArFunctor.h ../include/ArArgumentParser.h \ + ../include/ArArgumentBuilder.h ../include/ArBasePacket.h \ + ../include/ArTcpConnection.h ../include/ArSocket.h \ + ../include/ArSimpleConnector.h ../include/ArRobotConnector.h \ + ../include/ArLaserConnector.h ../include/ArLogFileConnection.h \ + ../include/ArRobotPacket.h ../include/ArRobotPacketSender.h \ + ../include/ArRobotPacketReceiver.h \ + ../include/ArRobotConfigPacketReader.h ../include/ArRobotTypes.h \ + ../include/ArRobotParams.h ../include/ArConfig.h \ + ../include/ArConfigArg.h ../include/ArFileParser.h \ + ../include/ArHasFileName.h ../include/ArConfigGroup.h \ + ../include/ArRobot.h ../include/ArSyncTask.h ../include/ArTaskState.h \ + ../include/ArSensorReading.h ../include/ArTransform.h \ + ../include/ArCondition.h ../include/ArSyncLoop.h \ + ../include/ArASyncTask.h ../include/ArThread.h \ + ../include/ArRobotPacketReaderThread.h ../include/ArActionDesired.h \ + ../include/ArResolver.h ../include/ArInterpolation.h \ + ../include/ArKeyHandler.h ../include/ArCommands.h \ + ../include/ArJoyHandler.h ../include/ariaInternal.h \ + ../include/ArStringInfoGroup.h ../include/ArSonarDevice.h \ + ../include/ArRangeDevice.h ../include/ArRangeBuffer.h \ + ../include/ArDrawingData.h ../include/ArPriorityResolver.h \ + ../include/ArAction.h ../include/ArArg.h ../include/ArActionGroup.h \ + ../include/ArActionGroups.h ../include/ArActionColorFollow.h \ + ../include/ArACTS.h ../include/ArPTZ.h ../include/ArPTZConnector.h \ + ../include/ArActionDeceleratingLimiter.h \ + ../include/ArActionLimiterForwards.h \ + ../include/ArActionLimiterBackwards.h \ + ../include/ArActionLimiterTableSensor.h ../include/ArActionBumpers.h \ + ../include/ArActionIRs.h ../include/ArActionStallRecover.h \ + ../include/ArActionAvoidFront.h ../include/ArActionAvoidSide.h \ + ../include/ArActionConstantVelocity.h ../include/ArActionInput.h \ + ../include/ArActionRobotJoydrive.h ../include/ArActionJoydrive.h \ + ../include/ArActionKeydrive.h ../include/ArActionTriangleDriveTo.h \ + ../include/ArLineFinder.h ../include/ArActionTurn.h \ + ../include/ArActionRatioInput.h ../include/ArActionStop.h \ + ../include/ArActionGoto.h ../include/ArModule.h \ + ../include/ArModuleLoader.h ../include/ArRecurrentTask.h \ + ../include/ArGripper.h ../include/ArSonyPTZ.h ../include/ArRVisionPTZ.h \ + ../include/ArAMPTU.h ../include/ArP2Arm.h ../include/ArSick.h \ + ../include/ArLaser.h ../include/ArRangeDeviceThreaded.h \ + ../include/ArFunctorASyncTask.h ../include/ArLMS2xx.h \ + ../include/ArLMS2xxPacket.h ../include/ArLMS2xxPacketReceiver.h \ + ../include/ArLaserLogger.h ../include/ArIrrfDevice.h \ + ../include/ArDPPTU.h ../include/ArVCC4.h ../include/ArMode.h \ + ../include/ArModes.h ../include/ArTCMCompassRobot.h ../include/ArTCM2.h \ + ../include/ArNetServer.h ../include/ArSignalHandler.h \ + ../include/ArAnalogGyro.h ../include/ArMapInterface.h \ + ../include/ArMapObject.h ../include/ArMapUtils.h ../include/ArMap.h \ + ../include/ArMapComponents.h ../include/ArBumpers.h ../include/ArIRs.h \ + ../include/ArForbiddenRangeDevice.h ../include/ArVersalogicIO.h \ + ../include/ArMTXIO.h ../include/ArActionGotoStraight.h \ + ../include/ArDataLogger.h ../include/ArRobotJoyHandler.h \ + ../include/ArRatioInputKeydrive.h ../include/ArRatioInputJoydrive.h \ + ../include/ArRatioInputRobotJoydrive.h \ + ../include/ArActionMovementParameters.h ../include/ArSoundPlayer.h \ + ../include/ArSoundsQueue.h ../include/ArSpeech.h \ + ../include/ArCameraCollection.h ../include/ArCameraCommands.h \ + ../include/ArSonarAutoDisabler.h ../include/ArActionDriveDistance.h \ + ../include/ArLaserReflectorDevice.h ../include/ArRobotConfig.h \ + ../include/ArTCMCompassDirect.h ../include/ArNMEAParser.h \ + ../include/ArLaserFilter.h ../include/ArUrg.h ../include/ArGPS.h \ + ../include/ArTrimbleGPS.h ../include/ArNovatelGPS.h \ + ../include/ArGPSCoords.h ../include/ArSonarConnector.h \ + ../include/ArBatteryConnector.h ../include/ArLCDConnector.h \ + ../include/ArSonarMTX.h ../include/ArBatteryMTX.h ../include/ArLCDMTX.h \ + ../include/ArSimulatedLaser.h ../include/ArExitErrorSource.h \ + ../include/ArActionLimiterRot.h ../include/ArRobotBatteryPacketReader.h \ + ../include/ArLMS1XX.h ../include/ArUrg_2_0.h \ + ../include/ArActionMovementParametersDebugging.h ../include/ArZippable.h \ + ../include/ArS3Series.h ../include/ArSZSeries.h include/ArNetworking.h \ + include/ArServerBase.h include/ArServerCommands.h \ + include/ArServerClient.h include/ArNetPacket.h \ + include/ArNetPacketReceiverTcp.h include/ArNetPacketSenderTcp.h \ + include/ArServerClientData.h include/ArServerClientIdentifier.h \ + include/ArServerData.h include/ArNetPacketReceiverUdp.h \ + include/ArServerUserInfo.h include/ArClientBase.h \ + include/ArClientCommands.h include/ArClientData.h include/ArMapChanger.h \ + ../include/ariaTypedefs.h ../include/ariaUtil.h \ + ../include/ArMapInterface.h ../include/ArMapUtils.h ../include/ArMutex.h \ + include/ArCentralForwarder.h include/ArClientSwitchManager.h \ + include/ArServerHandlerCamera.h include/ArNetworking.h \ + include/ArServerHandlerCameraCollection.h ../include/ArExport.h \ + ../include/ArFunctor.h ../include/ArCameraCollection.h \ + include/ArServerHandlerCommMonitor.h include/ArServerHandlerCommands.h \ + include/ArServerHandlerPopup.h include/ArServerInfoDrawings.h \ + include/ArServerInfoRobot.h include/ArServerInfoSensor.h \ + include/ArServerHandlerMap.h ../include/ArConfig.h \ + include/ArServerMode.h include/ArServerModeDrive.h \ + include/ArServerModeRatioDrive.h include/ArServerModeStop.h \ + include/ArServerModeWander.h include/ArServerHandlerConfig.h \ + include/ArClientHandlerConfig.h include/ArHybridForwarderVideo.h \ + include/ArServerSimpleCommands.h include/ArServerFileUtils.h \ + include/ArClientFileUtils.h include/ArClientSimpleConnector.h \ + include/ArServerHandlerMapping.h include/ArTempDirectoryHelper.h \ + include/ArServerSimpleOpener.h include/ArServerInfoStrings.h \ + include/ArClientArgUtils.h include/ArCentralManager.h \ + include/ArServerModeIdle.h +examples/configServer: examples/configServer.cpp ../include/Aria.h \ + ../include/ariaOSDef.h ../include/ariaTypedefs.h \ + ../include/ArSerialConnection.h ../include/ArDeviceConnection.h \ + ../include/ariaUtil.h ../include/ArLog.h ../include/ArMutex.h \ + ../include/ArFunctor.h ../include/ArArgumentParser.h \ + ../include/ArArgumentBuilder.h ../include/ArBasePacket.h \ + ../include/ArTcpConnection.h ../include/ArSocket.h \ + ../include/ArSimpleConnector.h ../include/ArRobotConnector.h \ + ../include/ArLaserConnector.h ../include/ArLogFileConnection.h \ + ../include/ArRobotPacket.h ../include/ArRobotPacketSender.h \ + ../include/ArRobotPacketReceiver.h \ + ../include/ArRobotConfigPacketReader.h ../include/ArRobotTypes.h \ + ../include/ArRobotParams.h ../include/ArConfig.h \ + ../include/ArConfigArg.h ../include/ArFileParser.h \ + ../include/ArHasFileName.h ../include/ArConfigGroup.h \ + ../include/ArRobot.h ../include/ArSyncTask.h ../include/ArTaskState.h \ + ../include/ArSensorReading.h ../include/ArTransform.h \ + ../include/ArCondition.h ../include/ArSyncLoop.h \ + ../include/ArASyncTask.h ../include/ArThread.h \ + ../include/ArRobotPacketReaderThread.h ../include/ArActionDesired.h \ + ../include/ArResolver.h ../include/ArInterpolation.h \ + ../include/ArKeyHandler.h ../include/ArCommands.h \ + ../include/ArJoyHandler.h ../include/ariaInternal.h \ + ../include/ArStringInfoGroup.h ../include/ArSonarDevice.h \ + ../include/ArRangeDevice.h ../include/ArRangeBuffer.h \ + ../include/ArDrawingData.h ../include/ArPriorityResolver.h \ + ../include/ArAction.h ../include/ArArg.h ../include/ArActionGroup.h \ + ../include/ArActionGroups.h ../include/ArActionColorFollow.h \ + ../include/ArACTS.h ../include/ArPTZ.h ../include/ArPTZConnector.h \ + ../include/ArActionDeceleratingLimiter.h \ + ../include/ArActionLimiterForwards.h \ + ../include/ArActionLimiterBackwards.h \ + ../include/ArActionLimiterTableSensor.h ../include/ArActionBumpers.h \ + ../include/ArActionIRs.h ../include/ArActionStallRecover.h \ + ../include/ArActionAvoidFront.h ../include/ArActionAvoidSide.h \ + ../include/ArActionConstantVelocity.h ../include/ArActionInput.h \ + ../include/ArActionRobotJoydrive.h ../include/ArActionJoydrive.h \ + ../include/ArActionKeydrive.h ../include/ArActionTriangleDriveTo.h \ + ../include/ArLineFinder.h ../include/ArActionTurn.h \ + ../include/ArActionRatioInput.h ../include/ArActionStop.h \ + ../include/ArActionGoto.h ../include/ArModule.h \ + ../include/ArModuleLoader.h ../include/ArRecurrentTask.h \ + ../include/ArGripper.h ../include/ArSonyPTZ.h ../include/ArRVisionPTZ.h \ + ../include/ArAMPTU.h ../include/ArP2Arm.h ../include/ArSick.h \ + ../include/ArLaser.h ../include/ArRangeDeviceThreaded.h \ + ../include/ArFunctorASyncTask.h ../include/ArLMS2xx.h \ + ../include/ArLMS2xxPacket.h ../include/ArLMS2xxPacketReceiver.h \ + ../include/ArLaserLogger.h ../include/ArIrrfDevice.h \ + ../include/ArDPPTU.h ../include/ArVCC4.h ../include/ArMode.h \ + ../include/ArModes.h ../include/ArTCMCompassRobot.h ../include/ArTCM2.h \ + ../include/ArNetServer.h ../include/ArSignalHandler.h \ + ../include/ArAnalogGyro.h ../include/ArMapInterface.h \ + ../include/ArMapObject.h ../include/ArMapUtils.h ../include/ArMap.h \ + ../include/ArMapComponents.h ../include/ArBumpers.h ../include/ArIRs.h \ + ../include/ArForbiddenRangeDevice.h ../include/ArVersalogicIO.h \ + ../include/ArMTXIO.h ../include/ArActionGotoStraight.h \ + ../include/ArDataLogger.h ../include/ArRobotJoyHandler.h \ + ../include/ArRatioInputKeydrive.h ../include/ArRatioInputJoydrive.h \ + ../include/ArRatioInputRobotJoydrive.h \ + ../include/ArActionMovementParameters.h ../include/ArSoundPlayer.h \ + ../include/ArSoundsQueue.h ../include/ArSpeech.h \ + ../include/ArCameraCollection.h ../include/ArCameraCommands.h \ + ../include/ArSonarAutoDisabler.h ../include/ArActionDriveDistance.h \ + ../include/ArLaserReflectorDevice.h ../include/ArRobotConfig.h \ + ../include/ArTCMCompassDirect.h ../include/ArNMEAParser.h \ + ../include/ArLaserFilter.h ../include/ArUrg.h ../include/ArGPS.h \ + ../include/ArTrimbleGPS.h ../include/ArNovatelGPS.h \ + ../include/ArGPSCoords.h ../include/ArSonarConnector.h \ + ../include/ArBatteryConnector.h ../include/ArLCDConnector.h \ + ../include/ArSonarMTX.h ../include/ArBatteryMTX.h ../include/ArLCDMTX.h \ + ../include/ArSimulatedLaser.h ../include/ArExitErrorSource.h \ + ../include/ArActionLimiterRot.h ../include/ArRobotBatteryPacketReader.h \ + ../include/ArLMS1XX.h ../include/ArUrg_2_0.h \ + ../include/ArActionMovementParametersDebugging.h ../include/ArZippable.h \ + ../include/ArS3Series.h ../include/ArSZSeries.h include/ArNetworking.h \ + include/ArServerBase.h include/ArServerCommands.h \ + include/ArServerClient.h include/ArNetPacket.h \ + include/ArNetPacketReceiverTcp.h include/ArNetPacketSenderTcp.h \ + include/ArServerClientData.h include/ArServerClientIdentifier.h \ + include/ArServerData.h include/ArNetPacketReceiverUdp.h \ + include/ArServerUserInfo.h include/ArClientBase.h \ + include/ArClientCommands.h include/ArClientData.h include/ArMapChanger.h \ + ../include/ariaTypedefs.h ../include/ariaUtil.h \ + ../include/ArMapInterface.h ../include/ArMapUtils.h ../include/ArMutex.h \ + include/ArCentralForwarder.h include/ArClientSwitchManager.h \ + include/ArServerHandlerCamera.h include/ArNetworking.h \ + include/ArServerHandlerCameraCollection.h ../include/ArExport.h \ + ../include/ArFunctor.h ../include/ArCameraCollection.h \ + include/ArServerHandlerCommMonitor.h include/ArServerHandlerCommands.h \ + include/ArServerHandlerPopup.h include/ArServerInfoDrawings.h \ + include/ArServerInfoRobot.h include/ArServerInfoSensor.h \ + include/ArServerHandlerMap.h ../include/ArConfig.h \ + include/ArServerMode.h include/ArServerModeDrive.h \ + include/ArServerModeRatioDrive.h include/ArServerModeStop.h \ + include/ArServerModeWander.h include/ArServerHandlerConfig.h \ + include/ArClientHandlerConfig.h include/ArHybridForwarderVideo.h \ + include/ArServerSimpleCommands.h include/ArServerFileUtils.h \ + include/ArClientFileUtils.h include/ArClientSimpleConnector.h \ + include/ArServerHandlerMapping.h include/ArTempDirectoryHelper.h \ + include/ArServerSimpleOpener.h include/ArServerInfoStrings.h \ + include/ArClientArgUtils.h include/ArCentralManager.h \ + include/ArServerModeIdle.h +examples/configServerRobot: examples/configServerRobot.cpp ../include/Aria.h \ + ../include/ariaOSDef.h ../include/ariaTypedefs.h \ + ../include/ArSerialConnection.h ../include/ArDeviceConnection.h \ + ../include/ariaUtil.h ../include/ArLog.h ../include/ArMutex.h \ + ../include/ArFunctor.h ../include/ArArgumentParser.h \ + ../include/ArArgumentBuilder.h ../include/ArBasePacket.h \ + ../include/ArTcpConnection.h ../include/ArSocket.h \ + ../include/ArSimpleConnector.h ../include/ArRobotConnector.h \ + ../include/ArLaserConnector.h ../include/ArLogFileConnection.h \ + ../include/ArRobotPacket.h ../include/ArRobotPacketSender.h \ + ../include/ArRobotPacketReceiver.h \ + ../include/ArRobotConfigPacketReader.h ../include/ArRobotTypes.h \ + ../include/ArRobotParams.h ../include/ArConfig.h \ + ../include/ArConfigArg.h ../include/ArFileParser.h \ + ../include/ArHasFileName.h ../include/ArConfigGroup.h \ + ../include/ArRobot.h ../include/ArSyncTask.h ../include/ArTaskState.h \ + ../include/ArSensorReading.h ../include/ArTransform.h \ + ../include/ArCondition.h ../include/ArSyncLoop.h \ + ../include/ArASyncTask.h ../include/ArThread.h \ + ../include/ArRobotPacketReaderThread.h ../include/ArActionDesired.h \ + ../include/ArResolver.h ../include/ArInterpolation.h \ + ../include/ArKeyHandler.h ../include/ArCommands.h \ + ../include/ArJoyHandler.h ../include/ariaInternal.h \ + ../include/ArStringInfoGroup.h ../include/ArSonarDevice.h \ + ../include/ArRangeDevice.h ../include/ArRangeBuffer.h \ + ../include/ArDrawingData.h ../include/ArPriorityResolver.h \ + ../include/ArAction.h ../include/ArArg.h ../include/ArActionGroup.h \ + ../include/ArActionGroups.h ../include/ArActionColorFollow.h \ + ../include/ArACTS.h ../include/ArPTZ.h ../include/ArPTZConnector.h \ + ../include/ArActionDeceleratingLimiter.h \ + ../include/ArActionLimiterForwards.h \ + ../include/ArActionLimiterBackwards.h \ + ../include/ArActionLimiterTableSensor.h ../include/ArActionBumpers.h \ + ../include/ArActionIRs.h ../include/ArActionStallRecover.h \ + ../include/ArActionAvoidFront.h ../include/ArActionAvoidSide.h \ + ../include/ArActionConstantVelocity.h ../include/ArActionInput.h \ + ../include/ArActionRobotJoydrive.h ../include/ArActionJoydrive.h \ + ../include/ArActionKeydrive.h ../include/ArActionTriangleDriveTo.h \ + ../include/ArLineFinder.h ../include/ArActionTurn.h \ + ../include/ArActionRatioInput.h ../include/ArActionStop.h \ + ../include/ArActionGoto.h ../include/ArModule.h \ + ../include/ArModuleLoader.h ../include/ArRecurrentTask.h \ + ../include/ArGripper.h ../include/ArSonyPTZ.h ../include/ArRVisionPTZ.h \ + ../include/ArAMPTU.h ../include/ArP2Arm.h ../include/ArSick.h \ + ../include/ArLaser.h ../include/ArRangeDeviceThreaded.h \ + ../include/ArFunctorASyncTask.h ../include/ArLMS2xx.h \ + ../include/ArLMS2xxPacket.h ../include/ArLMS2xxPacketReceiver.h \ + ../include/ArLaserLogger.h ../include/ArIrrfDevice.h \ + ../include/ArDPPTU.h ../include/ArVCC4.h ../include/ArMode.h \ + ../include/ArModes.h ../include/ArTCMCompassRobot.h ../include/ArTCM2.h \ + ../include/ArNetServer.h ../include/ArSignalHandler.h \ + ../include/ArAnalogGyro.h ../include/ArMapInterface.h \ + ../include/ArMapObject.h ../include/ArMapUtils.h ../include/ArMap.h \ + ../include/ArMapComponents.h ../include/ArBumpers.h ../include/ArIRs.h \ + ../include/ArForbiddenRangeDevice.h ../include/ArVersalogicIO.h \ + ../include/ArMTXIO.h ../include/ArActionGotoStraight.h \ + ../include/ArDataLogger.h ../include/ArRobotJoyHandler.h \ + ../include/ArRatioInputKeydrive.h ../include/ArRatioInputJoydrive.h \ + ../include/ArRatioInputRobotJoydrive.h \ + ../include/ArActionMovementParameters.h ../include/ArSoundPlayer.h \ + ../include/ArSoundsQueue.h ../include/ArSpeech.h \ + ../include/ArCameraCollection.h ../include/ArCameraCommands.h \ + ../include/ArSonarAutoDisabler.h ../include/ArActionDriveDistance.h \ + ../include/ArLaserReflectorDevice.h ../include/ArRobotConfig.h \ + ../include/ArTCMCompassDirect.h ../include/ArNMEAParser.h \ + ../include/ArLaserFilter.h ../include/ArUrg.h ../include/ArGPS.h \ + ../include/ArTrimbleGPS.h ../include/ArNovatelGPS.h \ + ../include/ArGPSCoords.h ../include/ArSonarConnector.h \ + ../include/ArBatteryConnector.h ../include/ArLCDConnector.h \ + ../include/ArSonarMTX.h ../include/ArBatteryMTX.h ../include/ArLCDMTX.h \ + ../include/ArSimulatedLaser.h ../include/ArExitErrorSource.h \ + ../include/ArActionLimiterRot.h ../include/ArRobotBatteryPacketReader.h \ + ../include/ArLMS1XX.h ../include/ArUrg_2_0.h \ + ../include/ArActionMovementParametersDebugging.h ../include/ArZippable.h \ + ../include/ArS3Series.h ../include/ArSZSeries.h include/ArNetworking.h \ + include/ArServerBase.h include/ArServerCommands.h \ + include/ArServerClient.h include/ArNetPacket.h \ + include/ArNetPacketReceiverTcp.h include/ArNetPacketSenderTcp.h \ + include/ArServerClientData.h include/ArServerClientIdentifier.h \ + include/ArServerData.h include/ArNetPacketReceiverUdp.h \ + include/ArServerUserInfo.h include/ArClientBase.h \ + include/ArClientCommands.h include/ArClientData.h include/ArMapChanger.h \ + ../include/ariaTypedefs.h ../include/ariaUtil.h \ + ../include/ArMapInterface.h ../include/ArMapUtils.h ../include/ArMutex.h \ + include/ArCentralForwarder.h include/ArClientSwitchManager.h \ + include/ArServerHandlerCamera.h include/ArNetworking.h \ + include/ArServerHandlerCameraCollection.h ../include/ArExport.h \ + ../include/ArFunctor.h ../include/ArCameraCollection.h \ + include/ArServerHandlerCommMonitor.h include/ArServerHandlerCommands.h \ + include/ArServerHandlerPopup.h include/ArServerInfoDrawings.h \ + include/ArServerInfoRobot.h include/ArServerInfoSensor.h \ + include/ArServerHandlerMap.h ../include/ArConfig.h \ + include/ArServerMode.h include/ArServerModeDrive.h \ + include/ArServerModeRatioDrive.h include/ArServerModeStop.h \ + include/ArServerModeWander.h include/ArServerHandlerConfig.h \ + include/ArClientHandlerConfig.h include/ArHybridForwarderVideo.h \ + include/ArServerSimpleCommands.h include/ArServerFileUtils.h \ + include/ArClientFileUtils.h include/ArClientSimpleConnector.h \ + include/ArServerHandlerMapping.h include/ArTempDirectoryHelper.h \ + include/ArServerSimpleOpener.h include/ArServerInfoStrings.h \ + include/ArClientArgUtils.h include/ArCentralManager.h \ + include/ArServerModeIdle.h +examples/drawingsExample: examples/drawingsExample.cpp ../include/Aria.h \ + ../include/ariaOSDef.h ../include/ariaTypedefs.h \ + ../include/ArSerialConnection.h ../include/ArDeviceConnection.h \ + ../include/ariaUtil.h ../include/ArLog.h ../include/ArMutex.h \ + ../include/ArFunctor.h ../include/ArArgumentParser.h \ + ../include/ArArgumentBuilder.h ../include/ArBasePacket.h \ + ../include/ArTcpConnection.h ../include/ArSocket.h \ + ../include/ArSimpleConnector.h ../include/ArRobotConnector.h \ + ../include/ArLaserConnector.h ../include/ArLogFileConnection.h \ + ../include/ArRobotPacket.h ../include/ArRobotPacketSender.h \ + ../include/ArRobotPacketReceiver.h \ + ../include/ArRobotConfigPacketReader.h ../include/ArRobotTypes.h \ + ../include/ArRobotParams.h ../include/ArConfig.h \ + ../include/ArConfigArg.h ../include/ArFileParser.h \ + ../include/ArHasFileName.h ../include/ArConfigGroup.h \ + ../include/ArRobot.h ../include/ArSyncTask.h ../include/ArTaskState.h \ + ../include/ArSensorReading.h ../include/ArTransform.h \ + ../include/ArCondition.h ../include/ArSyncLoop.h \ + ../include/ArASyncTask.h ../include/ArThread.h \ + ../include/ArRobotPacketReaderThread.h ../include/ArActionDesired.h \ + ../include/ArResolver.h ../include/ArInterpolation.h \ + ../include/ArKeyHandler.h ../include/ArCommands.h \ + ../include/ArJoyHandler.h ../include/ariaInternal.h \ + ../include/ArStringInfoGroup.h ../include/ArSonarDevice.h \ + ../include/ArRangeDevice.h ../include/ArRangeBuffer.h \ + ../include/ArDrawingData.h ../include/ArPriorityResolver.h \ + ../include/ArAction.h ../include/ArArg.h ../include/ArActionGroup.h \ + ../include/ArActionGroups.h ../include/ArActionColorFollow.h \ + ../include/ArACTS.h ../include/ArPTZ.h ../include/ArPTZConnector.h \ + ../include/ArActionDeceleratingLimiter.h \ + ../include/ArActionLimiterForwards.h \ + ../include/ArActionLimiterBackwards.h \ + ../include/ArActionLimiterTableSensor.h ../include/ArActionBumpers.h \ + ../include/ArActionIRs.h ../include/ArActionStallRecover.h \ + ../include/ArActionAvoidFront.h ../include/ArActionAvoidSide.h \ + ../include/ArActionConstantVelocity.h ../include/ArActionInput.h \ + ../include/ArActionRobotJoydrive.h ../include/ArActionJoydrive.h \ + ../include/ArActionKeydrive.h ../include/ArActionTriangleDriveTo.h \ + ../include/ArLineFinder.h ../include/ArActionTurn.h \ + ../include/ArActionRatioInput.h ../include/ArActionStop.h \ + ../include/ArActionGoto.h ../include/ArModule.h \ + ../include/ArModuleLoader.h ../include/ArRecurrentTask.h \ + ../include/ArGripper.h ../include/ArSonyPTZ.h ../include/ArRVisionPTZ.h \ + ../include/ArAMPTU.h ../include/ArP2Arm.h ../include/ArSick.h \ + ../include/ArLaser.h ../include/ArRangeDeviceThreaded.h \ + ../include/ArFunctorASyncTask.h ../include/ArLMS2xx.h \ + ../include/ArLMS2xxPacket.h ../include/ArLMS2xxPacketReceiver.h \ + ../include/ArLaserLogger.h ../include/ArIrrfDevice.h \ + ../include/ArDPPTU.h ../include/ArVCC4.h ../include/ArMode.h \ + ../include/ArModes.h ../include/ArTCMCompassRobot.h ../include/ArTCM2.h \ + ../include/ArNetServer.h ../include/ArSignalHandler.h \ + ../include/ArAnalogGyro.h ../include/ArMapInterface.h \ + ../include/ArMapObject.h ../include/ArMapUtils.h ../include/ArMap.h \ + ../include/ArMapComponents.h ../include/ArBumpers.h ../include/ArIRs.h \ + ../include/ArForbiddenRangeDevice.h ../include/ArVersalogicIO.h \ + ../include/ArMTXIO.h ../include/ArActionGotoStraight.h \ + ../include/ArDataLogger.h ../include/ArRobotJoyHandler.h \ + ../include/ArRatioInputKeydrive.h ../include/ArRatioInputJoydrive.h \ + ../include/ArRatioInputRobotJoydrive.h \ + ../include/ArActionMovementParameters.h ../include/ArSoundPlayer.h \ + ../include/ArSoundsQueue.h ../include/ArSpeech.h \ + ../include/ArCameraCollection.h ../include/ArCameraCommands.h \ + ../include/ArSonarAutoDisabler.h ../include/ArActionDriveDistance.h \ + ../include/ArLaserReflectorDevice.h ../include/ArRobotConfig.h \ + ../include/ArTCMCompassDirect.h ../include/ArNMEAParser.h \ + ../include/ArLaserFilter.h ../include/ArUrg.h ../include/ArGPS.h \ + ../include/ArTrimbleGPS.h ../include/ArNovatelGPS.h \ + ../include/ArGPSCoords.h ../include/ArSonarConnector.h \ + ../include/ArBatteryConnector.h ../include/ArLCDConnector.h \ + ../include/ArSonarMTX.h ../include/ArBatteryMTX.h ../include/ArLCDMTX.h \ + ../include/ArSimulatedLaser.h ../include/ArExitErrorSource.h \ + ../include/ArActionLimiterRot.h ../include/ArRobotBatteryPacketReader.h \ + ../include/ArLMS1XX.h ../include/ArUrg_2_0.h \ + ../include/ArActionMovementParametersDebugging.h ../include/ArZippable.h \ + ../include/ArS3Series.h ../include/ArSZSeries.h include/ArNetworking.h \ + include/ArServerBase.h include/ArServerCommands.h \ + include/ArServerClient.h include/ArNetPacket.h \ + include/ArNetPacketReceiverTcp.h include/ArNetPacketSenderTcp.h \ + include/ArServerClientData.h include/ArServerClientIdentifier.h \ + include/ArServerData.h include/ArNetPacketReceiverUdp.h \ + include/ArServerUserInfo.h include/ArClientBase.h \ + include/ArClientCommands.h include/ArClientData.h include/ArMapChanger.h \ + ../include/ariaTypedefs.h ../include/ariaUtil.h \ + ../include/ArMapInterface.h ../include/ArMapUtils.h ../include/ArMutex.h \ + include/ArCentralForwarder.h include/ArClientSwitchManager.h \ + include/ArServerHandlerCamera.h include/ArNetworking.h \ + include/ArServerHandlerCameraCollection.h ../include/ArExport.h \ + ../include/ArFunctor.h ../include/ArCameraCollection.h \ + include/ArServerHandlerCommMonitor.h include/ArServerHandlerCommands.h \ + include/ArServerHandlerPopup.h include/ArServerInfoDrawings.h \ + include/ArServerInfoRobot.h include/ArServerInfoSensor.h \ + include/ArServerHandlerMap.h ../include/ArConfig.h \ + include/ArServerMode.h include/ArServerModeDrive.h \ + include/ArServerModeRatioDrive.h include/ArServerModeStop.h \ + include/ArServerModeWander.h include/ArServerHandlerConfig.h \ + include/ArClientHandlerConfig.h include/ArHybridForwarderVideo.h \ + include/ArServerSimpleCommands.h include/ArServerFileUtils.h \ + include/ArClientFileUtils.h include/ArClientSimpleConnector.h \ + include/ArServerHandlerMapping.h include/ArTempDirectoryHelper.h \ + include/ArServerSimpleOpener.h include/ArServerInfoStrings.h \ + include/ArClientArgUtils.h include/ArCentralManager.h \ + include/ArServerModeIdle.h +examples/drawingsExampleWithRobot: examples/drawingsExampleWithRobot.cpp \ + ../include/Aria.h ../include/ariaOSDef.h ../include/ariaTypedefs.h \ + ../include/ArSerialConnection.h ../include/ArDeviceConnection.h \ + ../include/ariaUtil.h ../include/ArLog.h ../include/ArMutex.h \ + ../include/ArFunctor.h ../include/ArArgumentParser.h \ + ../include/ArArgumentBuilder.h ../include/ArBasePacket.h \ + ../include/ArTcpConnection.h ../include/ArSocket.h \ + ../include/ArSimpleConnector.h ../include/ArRobotConnector.h \ + ../include/ArLaserConnector.h ../include/ArLogFileConnection.h \ + ../include/ArRobotPacket.h ../include/ArRobotPacketSender.h \ + ../include/ArRobotPacketReceiver.h \ + ../include/ArRobotConfigPacketReader.h ../include/ArRobotTypes.h \ + ../include/ArRobotParams.h ../include/ArConfig.h \ + ../include/ArConfigArg.h ../include/ArFileParser.h \ + ../include/ArHasFileName.h ../include/ArConfigGroup.h \ + ../include/ArRobot.h ../include/ArSyncTask.h ../include/ArTaskState.h \ + ../include/ArSensorReading.h ../include/ArTransform.h \ + ../include/ArCondition.h ../include/ArSyncLoop.h \ + ../include/ArASyncTask.h ../include/ArThread.h \ + ../include/ArRobotPacketReaderThread.h ../include/ArActionDesired.h \ + ../include/ArResolver.h ../include/ArInterpolation.h \ + ../include/ArKeyHandler.h ../include/ArCommands.h \ + ../include/ArJoyHandler.h ../include/ariaInternal.h \ + ../include/ArStringInfoGroup.h ../include/ArSonarDevice.h \ + ../include/ArRangeDevice.h ../include/ArRangeBuffer.h \ + ../include/ArDrawingData.h ../include/ArPriorityResolver.h \ + ../include/ArAction.h ../include/ArArg.h ../include/ArActionGroup.h \ + ../include/ArActionGroups.h ../include/ArActionColorFollow.h \ + ../include/ArACTS.h ../include/ArPTZ.h ../include/ArPTZConnector.h \ + ../include/ArActionDeceleratingLimiter.h \ + ../include/ArActionLimiterForwards.h \ + ../include/ArActionLimiterBackwards.h \ + ../include/ArActionLimiterTableSensor.h ../include/ArActionBumpers.h \ + ../include/ArActionIRs.h ../include/ArActionStallRecover.h \ + ../include/ArActionAvoidFront.h ../include/ArActionAvoidSide.h \ + ../include/ArActionConstantVelocity.h ../include/ArActionInput.h \ + ../include/ArActionRobotJoydrive.h ../include/ArActionJoydrive.h \ + ../include/ArActionKeydrive.h ../include/ArActionTriangleDriveTo.h \ + ../include/ArLineFinder.h ../include/ArActionTurn.h \ + ../include/ArActionRatioInput.h ../include/ArActionStop.h \ + ../include/ArActionGoto.h ../include/ArModule.h \ + ../include/ArModuleLoader.h ../include/ArRecurrentTask.h \ + ../include/ArGripper.h ../include/ArSonyPTZ.h ../include/ArRVisionPTZ.h \ + ../include/ArAMPTU.h ../include/ArP2Arm.h ../include/ArSick.h \ + ../include/ArLaser.h ../include/ArRangeDeviceThreaded.h \ + ../include/ArFunctorASyncTask.h ../include/ArLMS2xx.h \ + ../include/ArLMS2xxPacket.h ../include/ArLMS2xxPacketReceiver.h \ + ../include/ArLaserLogger.h ../include/ArIrrfDevice.h \ + ../include/ArDPPTU.h ../include/ArVCC4.h ../include/ArMode.h \ + ../include/ArModes.h ../include/ArTCMCompassRobot.h ../include/ArTCM2.h \ + ../include/ArNetServer.h ../include/ArSignalHandler.h \ + ../include/ArAnalogGyro.h ../include/ArMapInterface.h \ + ../include/ArMapObject.h ../include/ArMapUtils.h ../include/ArMap.h \ + ../include/ArMapComponents.h ../include/ArBumpers.h ../include/ArIRs.h \ + ../include/ArForbiddenRangeDevice.h ../include/ArVersalogicIO.h \ + ../include/ArMTXIO.h ../include/ArActionGotoStraight.h \ + ../include/ArDataLogger.h ../include/ArRobotJoyHandler.h \ + ../include/ArRatioInputKeydrive.h ../include/ArRatioInputJoydrive.h \ + ../include/ArRatioInputRobotJoydrive.h \ + ../include/ArActionMovementParameters.h ../include/ArSoundPlayer.h \ + ../include/ArSoundsQueue.h ../include/ArSpeech.h \ + ../include/ArCameraCollection.h ../include/ArCameraCommands.h \ + ../include/ArSonarAutoDisabler.h ../include/ArActionDriveDistance.h \ + ../include/ArLaserReflectorDevice.h ../include/ArRobotConfig.h \ + ../include/ArTCMCompassDirect.h ../include/ArNMEAParser.h \ + ../include/ArLaserFilter.h ../include/ArUrg.h ../include/ArGPS.h \ + ../include/ArTrimbleGPS.h ../include/ArNovatelGPS.h \ + ../include/ArGPSCoords.h ../include/ArSonarConnector.h \ + ../include/ArBatteryConnector.h ../include/ArLCDConnector.h \ + ../include/ArSonarMTX.h ../include/ArBatteryMTX.h ../include/ArLCDMTX.h \ + ../include/ArSimulatedLaser.h ../include/ArExitErrorSource.h \ + ../include/ArActionLimiterRot.h ../include/ArRobotBatteryPacketReader.h \ + ../include/ArLMS1XX.h ../include/ArUrg_2_0.h \ + ../include/ArActionMovementParametersDebugging.h ../include/ArZippable.h \ + ../include/ArS3Series.h ../include/ArSZSeries.h include/ArNetworking.h \ + include/ArServerBase.h include/ArServerCommands.h \ + include/ArServerClient.h include/ArNetPacket.h \ + include/ArNetPacketReceiverTcp.h include/ArNetPacketSenderTcp.h \ + include/ArServerClientData.h include/ArServerClientIdentifier.h \ + include/ArServerData.h include/ArNetPacketReceiverUdp.h \ + include/ArServerUserInfo.h include/ArClientBase.h \ + include/ArClientCommands.h include/ArClientData.h include/ArMapChanger.h \ + ../include/ariaTypedefs.h ../include/ariaUtil.h \ + ../include/ArMapInterface.h ../include/ArMapUtils.h ../include/ArMutex.h \ + include/ArCentralForwarder.h include/ArClientSwitchManager.h \ + include/ArServerHandlerCamera.h include/ArNetworking.h \ + include/ArServerHandlerCameraCollection.h ../include/ArExport.h \ + ../include/ArFunctor.h ../include/ArCameraCollection.h \ + include/ArServerHandlerCommMonitor.h include/ArServerHandlerCommands.h \ + include/ArServerHandlerPopup.h include/ArServerInfoDrawings.h \ + include/ArServerInfoRobot.h include/ArServerInfoSensor.h \ + include/ArServerHandlerMap.h ../include/ArConfig.h \ + include/ArServerMode.h include/ArServerModeDrive.h \ + include/ArServerModeRatioDrive.h include/ArServerModeStop.h \ + include/ArServerModeWander.h include/ArServerHandlerConfig.h \ + include/ArClientHandlerConfig.h include/ArHybridForwarderVideo.h \ + include/ArServerSimpleCommands.h include/ArServerFileUtils.h \ + include/ArClientFileUtils.h include/ArClientSimpleConnector.h \ + include/ArServerHandlerMapping.h include/ArTempDirectoryHelper.h \ + include/ArServerSimpleOpener.h include/ArServerInfoStrings.h \ + include/ArClientArgUtils.h include/ArCentralManager.h \ + include/ArServerModeIdle.h +examples/getVideoExample: examples/getVideoExample.cpp ../include/Aria.h \ + ../include/ariaOSDef.h ../include/ariaTypedefs.h \ + ../include/ArSerialConnection.h ../include/ArDeviceConnection.h \ + ../include/ariaUtil.h ../include/ArLog.h ../include/ArMutex.h \ + ../include/ArFunctor.h ../include/ArArgumentParser.h \ + ../include/ArArgumentBuilder.h ../include/ArBasePacket.h \ + ../include/ArTcpConnection.h ../include/ArSocket.h \ + ../include/ArSimpleConnector.h ../include/ArRobotConnector.h \ + ../include/ArLaserConnector.h ../include/ArLogFileConnection.h \ + ../include/ArRobotPacket.h ../include/ArRobotPacketSender.h \ + ../include/ArRobotPacketReceiver.h \ + ../include/ArRobotConfigPacketReader.h ../include/ArRobotTypes.h \ + ../include/ArRobotParams.h ../include/ArConfig.h \ + ../include/ArConfigArg.h ../include/ArFileParser.h \ + ../include/ArHasFileName.h ../include/ArConfigGroup.h \ + ../include/ArRobot.h ../include/ArSyncTask.h ../include/ArTaskState.h \ + ../include/ArSensorReading.h ../include/ArTransform.h \ + ../include/ArCondition.h ../include/ArSyncLoop.h \ + ../include/ArASyncTask.h ../include/ArThread.h \ + ../include/ArRobotPacketReaderThread.h ../include/ArActionDesired.h \ + ../include/ArResolver.h ../include/ArInterpolation.h \ + ../include/ArKeyHandler.h ../include/ArCommands.h \ + ../include/ArJoyHandler.h ../include/ariaInternal.h \ + ../include/ArStringInfoGroup.h ../include/ArSonarDevice.h \ + ../include/ArRangeDevice.h ../include/ArRangeBuffer.h \ + ../include/ArDrawingData.h ../include/ArPriorityResolver.h \ + ../include/ArAction.h ../include/ArArg.h ../include/ArActionGroup.h \ + ../include/ArActionGroups.h ../include/ArActionColorFollow.h \ + ../include/ArACTS.h ../include/ArPTZ.h ../include/ArPTZConnector.h \ + ../include/ArActionDeceleratingLimiter.h \ + ../include/ArActionLimiterForwards.h \ + ../include/ArActionLimiterBackwards.h \ + ../include/ArActionLimiterTableSensor.h ../include/ArActionBumpers.h \ + ../include/ArActionIRs.h ../include/ArActionStallRecover.h \ + ../include/ArActionAvoidFront.h ../include/ArActionAvoidSide.h \ + ../include/ArActionConstantVelocity.h ../include/ArActionInput.h \ + ../include/ArActionRobotJoydrive.h ../include/ArActionJoydrive.h \ + ../include/ArActionKeydrive.h ../include/ArActionTriangleDriveTo.h \ + ../include/ArLineFinder.h ../include/ArActionTurn.h \ + ../include/ArActionRatioInput.h ../include/ArActionStop.h \ + ../include/ArActionGoto.h ../include/ArModule.h \ + ../include/ArModuleLoader.h ../include/ArRecurrentTask.h \ + ../include/ArGripper.h ../include/ArSonyPTZ.h ../include/ArRVisionPTZ.h \ + ../include/ArAMPTU.h ../include/ArP2Arm.h ../include/ArSick.h \ + ../include/ArLaser.h ../include/ArRangeDeviceThreaded.h \ + ../include/ArFunctorASyncTask.h ../include/ArLMS2xx.h \ + ../include/ArLMS2xxPacket.h ../include/ArLMS2xxPacketReceiver.h \ + ../include/ArLaserLogger.h ../include/ArIrrfDevice.h \ + ../include/ArDPPTU.h ../include/ArVCC4.h ../include/ArMode.h \ + ../include/ArModes.h ../include/ArTCMCompassRobot.h ../include/ArTCM2.h \ + ../include/ArNetServer.h ../include/ArSignalHandler.h \ + ../include/ArAnalogGyro.h ../include/ArMapInterface.h \ + ../include/ArMapObject.h ../include/ArMapUtils.h ../include/ArMap.h \ + ../include/ArMapComponents.h ../include/ArBumpers.h ../include/ArIRs.h \ + ../include/ArForbiddenRangeDevice.h ../include/ArVersalogicIO.h \ + ../include/ArMTXIO.h ../include/ArActionGotoStraight.h \ + ../include/ArDataLogger.h ../include/ArRobotJoyHandler.h \ + ../include/ArRatioInputKeydrive.h ../include/ArRatioInputJoydrive.h \ + ../include/ArRatioInputRobotJoydrive.h \ + ../include/ArActionMovementParameters.h ../include/ArSoundPlayer.h \ + ../include/ArSoundsQueue.h ../include/ArSpeech.h \ + ../include/ArCameraCollection.h ../include/ArCameraCommands.h \ + ../include/ArSonarAutoDisabler.h ../include/ArActionDriveDistance.h \ + ../include/ArLaserReflectorDevice.h ../include/ArRobotConfig.h \ + ../include/ArTCMCompassDirect.h ../include/ArNMEAParser.h \ + ../include/ArLaserFilter.h ../include/ArUrg.h ../include/ArGPS.h \ + ../include/ArTrimbleGPS.h ../include/ArNovatelGPS.h \ + ../include/ArGPSCoords.h ../include/ArSonarConnector.h \ + ../include/ArBatteryConnector.h ../include/ArLCDConnector.h \ + ../include/ArSonarMTX.h ../include/ArBatteryMTX.h ../include/ArLCDMTX.h \ + ../include/ArSimulatedLaser.h ../include/ArExitErrorSource.h \ + ../include/ArActionLimiterRot.h ../include/ArRobotBatteryPacketReader.h \ + ../include/ArLMS1XX.h ../include/ArUrg_2_0.h \ + ../include/ArActionMovementParametersDebugging.h ../include/ArZippable.h \ + ../include/ArS3Series.h ../include/ArSZSeries.h include/ArNetworking.h \ + include/ArServerBase.h include/ArServerCommands.h \ + include/ArServerClient.h include/ArNetPacket.h \ + include/ArNetPacketReceiverTcp.h include/ArNetPacketSenderTcp.h \ + include/ArServerClientData.h include/ArServerClientIdentifier.h \ + include/ArServerData.h include/ArNetPacketReceiverUdp.h \ + include/ArServerUserInfo.h include/ArClientBase.h \ + include/ArClientCommands.h include/ArClientData.h include/ArMapChanger.h \ + ../include/ariaTypedefs.h ../include/ariaUtil.h \ + ../include/ArMapInterface.h ../include/ArMapUtils.h ../include/ArMutex.h \ + include/ArCentralForwarder.h include/ArClientSwitchManager.h \ + include/ArServerHandlerCamera.h include/ArNetworking.h \ + include/ArServerHandlerCameraCollection.h ../include/ArExport.h \ + ../include/ArFunctor.h ../include/ArCameraCollection.h \ + include/ArServerHandlerCommMonitor.h include/ArServerHandlerCommands.h \ + include/ArServerHandlerPopup.h include/ArServerInfoDrawings.h \ + include/ArServerInfoRobot.h include/ArServerInfoSensor.h \ + include/ArServerHandlerMap.h ../include/ArConfig.h \ + include/ArServerMode.h include/ArServerModeDrive.h \ + include/ArServerModeRatioDrive.h include/ArServerModeStop.h \ + include/ArServerModeWander.h include/ArServerHandlerConfig.h \ + include/ArClientHandlerConfig.h include/ArHybridForwarderVideo.h \ + include/ArServerSimpleCommands.h include/ArServerFileUtils.h \ + include/ArClientFileUtils.h include/ArClientSimpleConnector.h \ + include/ArServerHandlerMapping.h include/ArTempDirectoryHelper.h \ + include/ArServerSimpleOpener.h include/ArServerInfoStrings.h \ + include/ArClientArgUtils.h include/ArCentralManager.h \ + include/ArServerModeIdle.h +examples/popupExample: examples/popupExample.cpp ../include/Aria.h \ + ../include/ariaOSDef.h ../include/ariaTypedefs.h \ + ../include/ArSerialConnection.h ../include/ArDeviceConnection.h \ + ../include/ariaUtil.h ../include/ArLog.h ../include/ArMutex.h \ + ../include/ArFunctor.h ../include/ArArgumentParser.h \ + ../include/ArArgumentBuilder.h ../include/ArBasePacket.h \ + ../include/ArTcpConnection.h ../include/ArSocket.h \ + ../include/ArSimpleConnector.h ../include/ArRobotConnector.h \ + ../include/ArLaserConnector.h ../include/ArLogFileConnection.h \ + ../include/ArRobotPacket.h ../include/ArRobotPacketSender.h \ + ../include/ArRobotPacketReceiver.h \ + ../include/ArRobotConfigPacketReader.h ../include/ArRobotTypes.h \ + ../include/ArRobotParams.h ../include/ArConfig.h \ + ../include/ArConfigArg.h ../include/ArFileParser.h \ + ../include/ArHasFileName.h ../include/ArConfigGroup.h \ + ../include/ArRobot.h ../include/ArSyncTask.h ../include/ArTaskState.h \ + ../include/ArSensorReading.h ../include/ArTransform.h \ + ../include/ArCondition.h ../include/ArSyncLoop.h \ + ../include/ArASyncTask.h ../include/ArThread.h \ + ../include/ArRobotPacketReaderThread.h ../include/ArActionDesired.h \ + ../include/ArResolver.h ../include/ArInterpolation.h \ + ../include/ArKeyHandler.h ../include/ArCommands.h \ + ../include/ArJoyHandler.h ../include/ariaInternal.h \ + ../include/ArStringInfoGroup.h ../include/ArSonarDevice.h \ + ../include/ArRangeDevice.h ../include/ArRangeBuffer.h \ + ../include/ArDrawingData.h ../include/ArPriorityResolver.h \ + ../include/ArAction.h ../include/ArArg.h ../include/ArActionGroup.h \ + ../include/ArActionGroups.h ../include/ArActionColorFollow.h \ + ../include/ArACTS.h ../include/ArPTZ.h ../include/ArPTZConnector.h \ + ../include/ArActionDeceleratingLimiter.h \ + ../include/ArActionLimiterForwards.h \ + ../include/ArActionLimiterBackwards.h \ + ../include/ArActionLimiterTableSensor.h ../include/ArActionBumpers.h \ + ../include/ArActionIRs.h ../include/ArActionStallRecover.h \ + ../include/ArActionAvoidFront.h ../include/ArActionAvoidSide.h \ + ../include/ArActionConstantVelocity.h ../include/ArActionInput.h \ + ../include/ArActionRobotJoydrive.h ../include/ArActionJoydrive.h \ + ../include/ArActionKeydrive.h ../include/ArActionTriangleDriveTo.h \ + ../include/ArLineFinder.h ../include/ArActionTurn.h \ + ../include/ArActionRatioInput.h ../include/ArActionStop.h \ + ../include/ArActionGoto.h ../include/ArModule.h \ + ../include/ArModuleLoader.h ../include/ArRecurrentTask.h \ + ../include/ArGripper.h ../include/ArSonyPTZ.h ../include/ArRVisionPTZ.h \ + ../include/ArAMPTU.h ../include/ArP2Arm.h ../include/ArSick.h \ + ../include/ArLaser.h ../include/ArRangeDeviceThreaded.h \ + ../include/ArFunctorASyncTask.h ../include/ArLMS2xx.h \ + ../include/ArLMS2xxPacket.h ../include/ArLMS2xxPacketReceiver.h \ + ../include/ArLaserLogger.h ../include/ArIrrfDevice.h \ + ../include/ArDPPTU.h ../include/ArVCC4.h ../include/ArMode.h \ + ../include/ArModes.h ../include/ArTCMCompassRobot.h ../include/ArTCM2.h \ + ../include/ArNetServer.h ../include/ArSignalHandler.h \ + ../include/ArAnalogGyro.h ../include/ArMapInterface.h \ + ../include/ArMapObject.h ../include/ArMapUtils.h ../include/ArMap.h \ + ../include/ArMapComponents.h ../include/ArBumpers.h ../include/ArIRs.h \ + ../include/ArForbiddenRangeDevice.h ../include/ArVersalogicIO.h \ + ../include/ArMTXIO.h ../include/ArActionGotoStraight.h \ + ../include/ArDataLogger.h ../include/ArRobotJoyHandler.h \ + ../include/ArRatioInputKeydrive.h ../include/ArRatioInputJoydrive.h \ + ../include/ArRatioInputRobotJoydrive.h \ + ../include/ArActionMovementParameters.h ../include/ArSoundPlayer.h \ + ../include/ArSoundsQueue.h ../include/ArSpeech.h \ + ../include/ArCameraCollection.h ../include/ArCameraCommands.h \ + ../include/ArSonarAutoDisabler.h ../include/ArActionDriveDistance.h \ + ../include/ArLaserReflectorDevice.h ../include/ArRobotConfig.h \ + ../include/ArTCMCompassDirect.h ../include/ArNMEAParser.h \ + ../include/ArLaserFilter.h ../include/ArUrg.h ../include/ArGPS.h \ + ../include/ArTrimbleGPS.h ../include/ArNovatelGPS.h \ + ../include/ArGPSCoords.h ../include/ArSonarConnector.h \ + ../include/ArBatteryConnector.h ../include/ArLCDConnector.h \ + ../include/ArSonarMTX.h ../include/ArBatteryMTX.h ../include/ArLCDMTX.h \ + ../include/ArSimulatedLaser.h ../include/ArExitErrorSource.h \ + ../include/ArActionLimiterRot.h ../include/ArRobotBatteryPacketReader.h \ + ../include/ArLMS1XX.h ../include/ArUrg_2_0.h \ + ../include/ArActionMovementParametersDebugging.h ../include/ArZippable.h \ + ../include/ArS3Series.h ../include/ArSZSeries.h include/ArNetworking.h \ + include/ArServerBase.h include/ArServerCommands.h \ + include/ArServerClient.h include/ArNetPacket.h \ + include/ArNetPacketReceiverTcp.h include/ArNetPacketSenderTcp.h \ + include/ArServerClientData.h include/ArServerClientIdentifier.h \ + include/ArServerData.h include/ArNetPacketReceiverUdp.h \ + include/ArServerUserInfo.h include/ArClientBase.h \ + include/ArClientCommands.h include/ArClientData.h include/ArMapChanger.h \ + ../include/ariaTypedefs.h ../include/ariaUtil.h \ + ../include/ArMapInterface.h ../include/ArMapUtils.h ../include/ArMutex.h \ + include/ArCentralForwarder.h include/ArClientSwitchManager.h \ + include/ArServerHandlerCamera.h include/ArNetworking.h \ + include/ArServerHandlerCameraCollection.h ../include/ArExport.h \ + ../include/ArFunctor.h ../include/ArCameraCollection.h \ + include/ArServerHandlerCommMonitor.h include/ArServerHandlerCommands.h \ + include/ArServerHandlerPopup.h include/ArServerInfoDrawings.h \ + include/ArServerInfoRobot.h include/ArServerInfoSensor.h \ + include/ArServerHandlerMap.h ../include/ArConfig.h \ + include/ArServerMode.h include/ArServerModeDrive.h \ + include/ArServerModeRatioDrive.h include/ArServerModeStop.h \ + include/ArServerModeWander.h include/ArServerHandlerConfig.h \ + include/ArClientHandlerConfig.h include/ArHybridForwarderVideo.h \ + include/ArServerSimpleCommands.h include/ArServerFileUtils.h \ + include/ArClientFileUtils.h include/ArClientSimpleConnector.h \ + include/ArServerHandlerMapping.h include/ArTempDirectoryHelper.h \ + include/ArServerSimpleOpener.h include/ArServerInfoStrings.h \ + include/ArClientArgUtils.h include/ArCentralManager.h \ + include/ArServerModeIdle.h +examples/proprietaryDirectoryEmptier: examples/proprietaryDirectoryEmptier.cpp \ + ../include/Aria.h ../include/ariaOSDef.h ../include/ariaTypedefs.h \ + ../include/ArSerialConnection.h ../include/ArDeviceConnection.h \ + ../include/ariaUtil.h ../include/ArLog.h ../include/ArMutex.h \ + ../include/ArFunctor.h ../include/ArArgumentParser.h \ + ../include/ArArgumentBuilder.h ../include/ArBasePacket.h \ + ../include/ArTcpConnection.h ../include/ArSocket.h \ + ../include/ArSimpleConnector.h ../include/ArRobotConnector.h \ + ../include/ArLaserConnector.h ../include/ArLogFileConnection.h \ + ../include/ArRobotPacket.h ../include/ArRobotPacketSender.h \ + ../include/ArRobotPacketReceiver.h \ + ../include/ArRobotConfigPacketReader.h ../include/ArRobotTypes.h \ + ../include/ArRobotParams.h ../include/ArConfig.h \ + ../include/ArConfigArg.h ../include/ArFileParser.h \ + ../include/ArHasFileName.h ../include/ArConfigGroup.h \ + ../include/ArRobot.h ../include/ArSyncTask.h ../include/ArTaskState.h \ + ../include/ArSensorReading.h ../include/ArTransform.h \ + ../include/ArCondition.h ../include/ArSyncLoop.h \ + ../include/ArASyncTask.h ../include/ArThread.h \ + ../include/ArRobotPacketReaderThread.h ../include/ArActionDesired.h \ + ../include/ArResolver.h ../include/ArInterpolation.h \ + ../include/ArKeyHandler.h ../include/ArCommands.h \ + ../include/ArJoyHandler.h ../include/ariaInternal.h \ + ../include/ArStringInfoGroup.h ../include/ArSonarDevice.h \ + ../include/ArRangeDevice.h ../include/ArRangeBuffer.h \ + ../include/ArDrawingData.h ../include/ArPriorityResolver.h \ + ../include/ArAction.h ../include/ArArg.h ../include/ArActionGroup.h \ + ../include/ArActionGroups.h ../include/ArActionColorFollow.h \ + ../include/ArACTS.h ../include/ArPTZ.h ../include/ArPTZConnector.h \ + ../include/ArActionDeceleratingLimiter.h \ + ../include/ArActionLimiterForwards.h \ + ../include/ArActionLimiterBackwards.h \ + ../include/ArActionLimiterTableSensor.h ../include/ArActionBumpers.h \ + ../include/ArActionIRs.h ../include/ArActionStallRecover.h \ + ../include/ArActionAvoidFront.h ../include/ArActionAvoidSide.h \ + ../include/ArActionConstantVelocity.h ../include/ArActionInput.h \ + ../include/ArActionRobotJoydrive.h ../include/ArActionJoydrive.h \ + ../include/ArActionKeydrive.h ../include/ArActionTriangleDriveTo.h \ + ../include/ArLineFinder.h ../include/ArActionTurn.h \ + ../include/ArActionRatioInput.h ../include/ArActionStop.h \ + ../include/ArActionGoto.h ../include/ArModule.h \ + ../include/ArModuleLoader.h ../include/ArRecurrentTask.h \ + ../include/ArGripper.h ../include/ArSonyPTZ.h ../include/ArRVisionPTZ.h \ + ../include/ArAMPTU.h ../include/ArP2Arm.h ../include/ArSick.h \ + ../include/ArLaser.h ../include/ArRangeDeviceThreaded.h \ + ../include/ArFunctorASyncTask.h ../include/ArLMS2xx.h \ + ../include/ArLMS2xxPacket.h ../include/ArLMS2xxPacketReceiver.h \ + ../include/ArLaserLogger.h ../include/ArIrrfDevice.h \ + ../include/ArDPPTU.h ../include/ArVCC4.h ../include/ArMode.h \ + ../include/ArModes.h ../include/ArTCMCompassRobot.h ../include/ArTCM2.h \ + ../include/ArNetServer.h ../include/ArSignalHandler.h \ + ../include/ArAnalogGyro.h ../include/ArMapInterface.h \ + ../include/ArMapObject.h ../include/ArMapUtils.h ../include/ArMap.h \ + ../include/ArMapComponents.h ../include/ArBumpers.h ../include/ArIRs.h \ + ../include/ArForbiddenRangeDevice.h ../include/ArVersalogicIO.h \ + ../include/ArMTXIO.h ../include/ArActionGotoStraight.h \ + ../include/ArDataLogger.h ../include/ArRobotJoyHandler.h \ + ../include/ArRatioInputKeydrive.h ../include/ArRatioInputJoydrive.h \ + ../include/ArRatioInputRobotJoydrive.h \ + ../include/ArActionMovementParameters.h ../include/ArSoundPlayer.h \ + ../include/ArSoundsQueue.h ../include/ArSpeech.h \ + ../include/ArCameraCollection.h ../include/ArCameraCommands.h \ + ../include/ArSonarAutoDisabler.h ../include/ArActionDriveDistance.h \ + ../include/ArLaserReflectorDevice.h ../include/ArRobotConfig.h \ + ../include/ArTCMCompassDirect.h ../include/ArNMEAParser.h \ + ../include/ArLaserFilter.h ../include/ArUrg.h ../include/ArGPS.h \ + ../include/ArTrimbleGPS.h ../include/ArNovatelGPS.h \ + ../include/ArGPSCoords.h ../include/ArSonarConnector.h \ + ../include/ArBatteryConnector.h ../include/ArLCDConnector.h \ + ../include/ArSonarMTX.h ../include/ArBatteryMTX.h ../include/ArLCDMTX.h \ + ../include/ArSimulatedLaser.h ../include/ArExitErrorSource.h \ + ../include/ArActionLimiterRot.h ../include/ArRobotBatteryPacketReader.h \ + ../include/ArLMS1XX.h ../include/ArUrg_2_0.h \ + ../include/ArActionMovementParametersDebugging.h ../include/ArZippable.h \ + ../include/ArS3Series.h ../include/ArSZSeries.h include/ArNetworking.h \ + include/ArServerBase.h include/ArServerCommands.h \ + include/ArServerClient.h include/ArNetPacket.h \ + include/ArNetPacketReceiverTcp.h include/ArNetPacketSenderTcp.h \ + include/ArServerClientData.h include/ArServerClientIdentifier.h \ + include/ArServerData.h include/ArNetPacketReceiverUdp.h \ + include/ArServerUserInfo.h include/ArClientBase.h \ + include/ArClientCommands.h include/ArClientData.h include/ArMapChanger.h \ + ../include/ariaTypedefs.h ../include/ariaUtil.h \ + ../include/ArMapInterface.h ../include/ArMapUtils.h ../include/ArMutex.h \ + include/ArCentralForwarder.h include/ArClientSwitchManager.h \ + include/ArServerHandlerCamera.h include/ArNetworking.h \ + include/ArServerHandlerCameraCollection.h ../include/ArExport.h \ + ../include/ArFunctor.h ../include/ArCameraCollection.h \ + include/ArServerHandlerCommMonitor.h include/ArServerHandlerCommands.h \ + include/ArServerHandlerPopup.h include/ArServerInfoDrawings.h \ + include/ArServerInfoRobot.h include/ArServerInfoSensor.h \ + include/ArServerHandlerMap.h ../include/ArConfig.h \ + include/ArServerMode.h include/ArServerModeDrive.h \ + include/ArServerModeRatioDrive.h include/ArServerModeStop.h \ + include/ArServerModeWander.h include/ArServerHandlerConfig.h \ + include/ArClientHandlerConfig.h include/ArHybridForwarderVideo.h \ + include/ArServerSimpleCommands.h include/ArServerFileUtils.h \ + include/ArClientFileUtils.h include/ArClientSimpleConnector.h \ + include/ArServerHandlerMapping.h include/ArTempDirectoryHelper.h \ + include/ArServerSimpleOpener.h include/ArServerInfoStrings.h \ + include/ArClientArgUtils.h include/ArCentralManager.h \ + include/ArServerModeIdle.h +examples/proprietaryGetSnapshots: examples/proprietaryGetSnapshots.cpp \ + ../include/Aria.h ../include/ariaOSDef.h ../include/ariaTypedefs.h \ + ../include/ArSerialConnection.h ../include/ArDeviceConnection.h \ + ../include/ariaUtil.h ../include/ArLog.h ../include/ArMutex.h \ + ../include/ArFunctor.h ../include/ArArgumentParser.h \ + ../include/ArArgumentBuilder.h ../include/ArBasePacket.h \ + ../include/ArTcpConnection.h ../include/ArSocket.h \ + ../include/ArSimpleConnector.h ../include/ArRobotConnector.h \ + ../include/ArLaserConnector.h ../include/ArLogFileConnection.h \ + ../include/ArRobotPacket.h ../include/ArRobotPacketSender.h \ + ../include/ArRobotPacketReceiver.h \ + ../include/ArRobotConfigPacketReader.h ../include/ArRobotTypes.h \ + ../include/ArRobotParams.h ../include/ArConfig.h \ + ../include/ArConfigArg.h ../include/ArFileParser.h \ + ../include/ArHasFileName.h ../include/ArConfigGroup.h \ + ../include/ArRobot.h ../include/ArSyncTask.h ../include/ArTaskState.h \ + ../include/ArSensorReading.h ../include/ArTransform.h \ + ../include/ArCondition.h ../include/ArSyncLoop.h \ + ../include/ArASyncTask.h ../include/ArThread.h \ + ../include/ArRobotPacketReaderThread.h ../include/ArActionDesired.h \ + ../include/ArResolver.h ../include/ArInterpolation.h \ + ../include/ArKeyHandler.h ../include/ArCommands.h \ + ../include/ArJoyHandler.h ../include/ariaInternal.h \ + ../include/ArStringInfoGroup.h ../include/ArSonarDevice.h \ + ../include/ArRangeDevice.h ../include/ArRangeBuffer.h \ + ../include/ArDrawingData.h ../include/ArPriorityResolver.h \ + ../include/ArAction.h ../include/ArArg.h ../include/ArActionGroup.h \ + ../include/ArActionGroups.h ../include/ArActionColorFollow.h \ + ../include/ArACTS.h ../include/ArPTZ.h ../include/ArPTZConnector.h \ + ../include/ArActionDeceleratingLimiter.h \ + ../include/ArActionLimiterForwards.h \ + ../include/ArActionLimiterBackwards.h \ + ../include/ArActionLimiterTableSensor.h ../include/ArActionBumpers.h \ + ../include/ArActionIRs.h ../include/ArActionStallRecover.h \ + ../include/ArActionAvoidFront.h ../include/ArActionAvoidSide.h \ + ../include/ArActionConstantVelocity.h ../include/ArActionInput.h \ + ../include/ArActionRobotJoydrive.h ../include/ArActionJoydrive.h \ + ../include/ArActionKeydrive.h ../include/ArActionTriangleDriveTo.h \ + ../include/ArLineFinder.h ../include/ArActionTurn.h \ + ../include/ArActionRatioInput.h ../include/ArActionStop.h \ + ../include/ArActionGoto.h ../include/ArModule.h \ + ../include/ArModuleLoader.h ../include/ArRecurrentTask.h \ + ../include/ArGripper.h ../include/ArSonyPTZ.h ../include/ArRVisionPTZ.h \ + ../include/ArAMPTU.h ../include/ArP2Arm.h ../include/ArSick.h \ + ../include/ArLaser.h ../include/ArRangeDeviceThreaded.h \ + ../include/ArFunctorASyncTask.h ../include/ArLMS2xx.h \ + ../include/ArLMS2xxPacket.h ../include/ArLMS2xxPacketReceiver.h \ + ../include/ArLaserLogger.h ../include/ArIrrfDevice.h \ + ../include/ArDPPTU.h ../include/ArVCC4.h ../include/ArMode.h \ + ../include/ArModes.h ../include/ArTCMCompassRobot.h ../include/ArTCM2.h \ + ../include/ArNetServer.h ../include/ArSignalHandler.h \ + ../include/ArAnalogGyro.h ../include/ArMapInterface.h \ + ../include/ArMapObject.h ../include/ArMapUtils.h ../include/ArMap.h \ + ../include/ArMapComponents.h ../include/ArBumpers.h ../include/ArIRs.h \ + ../include/ArForbiddenRangeDevice.h ../include/ArVersalogicIO.h \ + ../include/ArMTXIO.h ../include/ArActionGotoStraight.h \ + ../include/ArDataLogger.h ../include/ArRobotJoyHandler.h \ + ../include/ArRatioInputKeydrive.h ../include/ArRatioInputJoydrive.h \ + ../include/ArRatioInputRobotJoydrive.h \ + ../include/ArActionMovementParameters.h ../include/ArSoundPlayer.h \ + ../include/ArSoundsQueue.h ../include/ArSpeech.h \ + ../include/ArCameraCollection.h ../include/ArCameraCommands.h \ + ../include/ArSonarAutoDisabler.h ../include/ArActionDriveDistance.h \ + ../include/ArLaserReflectorDevice.h ../include/ArRobotConfig.h \ + ../include/ArTCMCompassDirect.h ../include/ArNMEAParser.h \ + ../include/ArLaserFilter.h ../include/ArUrg.h ../include/ArGPS.h \ + ../include/ArTrimbleGPS.h ../include/ArNovatelGPS.h \ + ../include/ArGPSCoords.h ../include/ArSonarConnector.h \ + ../include/ArBatteryConnector.h ../include/ArLCDConnector.h \ + ../include/ArSonarMTX.h ../include/ArBatteryMTX.h ../include/ArLCDMTX.h \ + ../include/ArSimulatedLaser.h ../include/ArExitErrorSource.h \ + ../include/ArActionLimiterRot.h ../include/ArRobotBatteryPacketReader.h \ + ../include/ArLMS1XX.h ../include/ArUrg_2_0.h \ + ../include/ArActionMovementParametersDebugging.h ../include/ArZippable.h \ + ../include/ArS3Series.h ../include/ArSZSeries.h include/ArNetworking.h \ + include/ArServerBase.h include/ArServerCommands.h \ + include/ArServerClient.h include/ArNetPacket.h \ + include/ArNetPacketReceiverTcp.h include/ArNetPacketSenderTcp.h \ + include/ArServerClientData.h include/ArServerClientIdentifier.h \ + include/ArServerData.h include/ArNetPacketReceiverUdp.h \ + include/ArServerUserInfo.h include/ArClientBase.h \ + include/ArClientCommands.h include/ArClientData.h include/ArMapChanger.h \ + ../include/ariaTypedefs.h ../include/ariaUtil.h \ + ../include/ArMapInterface.h ../include/ArMapUtils.h ../include/ArMutex.h \ + include/ArCentralForwarder.h include/ArClientSwitchManager.h \ + include/ArServerHandlerCamera.h include/ArNetworking.h \ + include/ArServerHandlerCameraCollection.h ../include/ArExport.h \ + ../include/ArFunctor.h ../include/ArCameraCollection.h \ + include/ArServerHandlerCommMonitor.h include/ArServerHandlerCommands.h \ + include/ArServerHandlerPopup.h include/ArServerInfoDrawings.h \ + include/ArServerInfoRobot.h include/ArServerInfoSensor.h \ + include/ArServerHandlerMap.h ../include/ArConfig.h \ + include/ArServerMode.h include/ArServerModeDrive.h \ + include/ArServerModeRatioDrive.h include/ArServerModeStop.h \ + include/ArServerModeWander.h include/ArServerHandlerConfig.h \ + include/ArClientHandlerConfig.h include/ArHybridForwarderVideo.h \ + include/ArServerSimpleCommands.h include/ArServerFileUtils.h \ + include/ArClientFileUtils.h include/ArClientSimpleConnector.h \ + include/ArServerHandlerMapping.h include/ArTempDirectoryHelper.h \ + include/ArServerSimpleOpener.h include/ArServerInfoStrings.h \ + include/ArClientArgUtils.h include/ArCentralManager.h \ + include/ArServerModeIdle.h +examples/ptzCameraClientExample: examples/ptzCameraClientExample.cpp \ + ../include/Aria.h ../include/ariaOSDef.h ../include/ariaTypedefs.h \ + ../include/ArSerialConnection.h ../include/ArDeviceConnection.h \ + ../include/ariaUtil.h ../include/ArLog.h ../include/ArMutex.h \ + ../include/ArFunctor.h ../include/ArArgumentParser.h \ + ../include/ArArgumentBuilder.h ../include/ArBasePacket.h \ + ../include/ArTcpConnection.h ../include/ArSocket.h \ + ../include/ArSimpleConnector.h ../include/ArRobotConnector.h \ + ../include/ArLaserConnector.h ../include/ArLogFileConnection.h \ + ../include/ArRobotPacket.h ../include/ArRobotPacketSender.h \ + ../include/ArRobotPacketReceiver.h \ + ../include/ArRobotConfigPacketReader.h ../include/ArRobotTypes.h \ + ../include/ArRobotParams.h ../include/ArConfig.h \ + ../include/ArConfigArg.h ../include/ArFileParser.h \ + ../include/ArHasFileName.h ../include/ArConfigGroup.h \ + ../include/ArRobot.h ../include/ArSyncTask.h ../include/ArTaskState.h \ + ../include/ArSensorReading.h ../include/ArTransform.h \ + ../include/ArCondition.h ../include/ArSyncLoop.h \ + ../include/ArASyncTask.h ../include/ArThread.h \ + ../include/ArRobotPacketReaderThread.h ../include/ArActionDesired.h \ + ../include/ArResolver.h ../include/ArInterpolation.h \ + ../include/ArKeyHandler.h ../include/ArCommands.h \ + ../include/ArJoyHandler.h ../include/ariaInternal.h \ + ../include/ArStringInfoGroup.h ../include/ArSonarDevice.h \ + ../include/ArRangeDevice.h ../include/ArRangeBuffer.h \ + ../include/ArDrawingData.h ../include/ArPriorityResolver.h \ + ../include/ArAction.h ../include/ArArg.h ../include/ArActionGroup.h \ + ../include/ArActionGroups.h ../include/ArActionColorFollow.h \ + ../include/ArACTS.h ../include/ArPTZ.h ../include/ArPTZConnector.h \ + ../include/ArActionDeceleratingLimiter.h \ + ../include/ArActionLimiterForwards.h \ + ../include/ArActionLimiterBackwards.h \ + ../include/ArActionLimiterTableSensor.h ../include/ArActionBumpers.h \ + ../include/ArActionIRs.h ../include/ArActionStallRecover.h \ + ../include/ArActionAvoidFront.h ../include/ArActionAvoidSide.h \ + ../include/ArActionConstantVelocity.h ../include/ArActionInput.h \ + ../include/ArActionRobotJoydrive.h ../include/ArActionJoydrive.h \ + ../include/ArActionKeydrive.h ../include/ArActionTriangleDriveTo.h \ + ../include/ArLineFinder.h ../include/ArActionTurn.h \ + ../include/ArActionRatioInput.h ../include/ArActionStop.h \ + ../include/ArActionGoto.h ../include/ArModule.h \ + ../include/ArModuleLoader.h ../include/ArRecurrentTask.h \ + ../include/ArGripper.h ../include/ArSonyPTZ.h ../include/ArRVisionPTZ.h \ + ../include/ArAMPTU.h ../include/ArP2Arm.h ../include/ArSick.h \ + ../include/ArLaser.h ../include/ArRangeDeviceThreaded.h \ + ../include/ArFunctorASyncTask.h ../include/ArLMS2xx.h \ + ../include/ArLMS2xxPacket.h ../include/ArLMS2xxPacketReceiver.h \ + ../include/ArLaserLogger.h ../include/ArIrrfDevice.h \ + ../include/ArDPPTU.h ../include/ArVCC4.h ../include/ArMode.h \ + ../include/ArModes.h ../include/ArTCMCompassRobot.h ../include/ArTCM2.h \ + ../include/ArNetServer.h ../include/ArSignalHandler.h \ + ../include/ArAnalogGyro.h ../include/ArMapInterface.h \ + ../include/ArMapObject.h ../include/ArMapUtils.h ../include/ArMap.h \ + ../include/ArMapComponents.h ../include/ArBumpers.h ../include/ArIRs.h \ + ../include/ArForbiddenRangeDevice.h ../include/ArVersalogicIO.h \ + ../include/ArMTXIO.h ../include/ArActionGotoStraight.h \ + ../include/ArDataLogger.h ../include/ArRobotJoyHandler.h \ + ../include/ArRatioInputKeydrive.h ../include/ArRatioInputJoydrive.h \ + ../include/ArRatioInputRobotJoydrive.h \ + ../include/ArActionMovementParameters.h ../include/ArSoundPlayer.h \ + ../include/ArSoundsQueue.h ../include/ArSpeech.h \ + ../include/ArCameraCollection.h ../include/ArCameraCommands.h \ + ../include/ArSonarAutoDisabler.h ../include/ArActionDriveDistance.h \ + ../include/ArLaserReflectorDevice.h ../include/ArRobotConfig.h \ + ../include/ArTCMCompassDirect.h ../include/ArNMEAParser.h \ + ../include/ArLaserFilter.h ../include/ArUrg.h ../include/ArGPS.h \ + ../include/ArTrimbleGPS.h ../include/ArNovatelGPS.h \ + ../include/ArGPSCoords.h ../include/ArSonarConnector.h \ + ../include/ArBatteryConnector.h ../include/ArLCDConnector.h \ + ../include/ArSonarMTX.h ../include/ArBatteryMTX.h ../include/ArLCDMTX.h \ + ../include/ArSimulatedLaser.h ../include/ArExitErrorSource.h \ + ../include/ArActionLimiterRot.h ../include/ArRobotBatteryPacketReader.h \ + ../include/ArLMS1XX.h ../include/ArUrg_2_0.h \ + ../include/ArActionMovementParametersDebugging.h ../include/ArZippable.h \ + ../include/ArS3Series.h ../include/ArSZSeries.h include/ArNetworking.h \ + include/ArServerBase.h include/ArServerCommands.h \ + include/ArServerClient.h include/ArNetPacket.h \ + include/ArNetPacketReceiverTcp.h include/ArNetPacketSenderTcp.h \ + include/ArServerClientData.h include/ArServerClientIdentifier.h \ + include/ArServerData.h include/ArNetPacketReceiverUdp.h \ + include/ArServerUserInfo.h include/ArClientBase.h \ + include/ArClientCommands.h include/ArClientData.h include/ArMapChanger.h \ + ../include/ariaTypedefs.h ../include/ariaUtil.h \ + ../include/ArMapInterface.h ../include/ArMapUtils.h ../include/ArMutex.h \ + include/ArCentralForwarder.h include/ArClientSwitchManager.h \ + include/ArServerHandlerCamera.h include/ArNetworking.h \ + include/ArServerHandlerCameraCollection.h ../include/ArExport.h \ + ../include/ArFunctor.h ../include/ArCameraCollection.h \ + include/ArServerHandlerCommMonitor.h include/ArServerHandlerCommands.h \ + include/ArServerHandlerPopup.h include/ArServerInfoDrawings.h \ + include/ArServerInfoRobot.h include/ArServerInfoSensor.h \ + include/ArServerHandlerMap.h ../include/ArConfig.h \ + include/ArServerMode.h include/ArServerModeDrive.h \ + include/ArServerModeRatioDrive.h include/ArServerModeStop.h \ + include/ArServerModeWander.h include/ArServerHandlerConfig.h \ + include/ArClientHandlerConfig.h include/ArHybridForwarderVideo.h \ + include/ArServerSimpleCommands.h include/ArServerFileUtils.h \ + include/ArClientFileUtils.h include/ArClientSimpleConnector.h \ + include/ArServerHandlerMapping.h include/ArTempDirectoryHelper.h \ + include/ArServerSimpleOpener.h include/ArServerInfoStrings.h \ + include/ArClientArgUtils.h include/ArCentralManager.h \ + include/ArServerModeIdle.h +examples/serverDemo: examples/serverDemo.cpp ../include/Aria.h \ + ../include/ariaOSDef.h ../include/ariaTypedefs.h \ + ../include/ArSerialConnection.h ../include/ArDeviceConnection.h \ + ../include/ariaUtil.h ../include/ArLog.h ../include/ArMutex.h \ + ../include/ArFunctor.h ../include/ArArgumentParser.h \ + ../include/ArArgumentBuilder.h ../include/ArBasePacket.h \ + ../include/ArTcpConnection.h ../include/ArSocket.h \ + ../include/ArSimpleConnector.h ../include/ArRobotConnector.h \ + ../include/ArLaserConnector.h ../include/ArLogFileConnection.h \ + ../include/ArRobotPacket.h ../include/ArRobotPacketSender.h \ + ../include/ArRobotPacketReceiver.h \ + ../include/ArRobotConfigPacketReader.h ../include/ArRobotTypes.h \ + ../include/ArRobotParams.h ../include/ArConfig.h \ + ../include/ArConfigArg.h ../include/ArFileParser.h \ + ../include/ArHasFileName.h ../include/ArConfigGroup.h \ + ../include/ArRobot.h ../include/ArSyncTask.h ../include/ArTaskState.h \ + ../include/ArSensorReading.h ../include/ArTransform.h \ + ../include/ArCondition.h ../include/ArSyncLoop.h \ + ../include/ArASyncTask.h ../include/ArThread.h \ + ../include/ArRobotPacketReaderThread.h ../include/ArActionDesired.h \ + ../include/ArResolver.h ../include/ArInterpolation.h \ + ../include/ArKeyHandler.h ../include/ArCommands.h \ + ../include/ArJoyHandler.h ../include/ariaInternal.h \ + ../include/ArStringInfoGroup.h ../include/ArSonarDevice.h \ + ../include/ArRangeDevice.h ../include/ArRangeBuffer.h \ + ../include/ArDrawingData.h ../include/ArPriorityResolver.h \ + ../include/ArAction.h ../include/ArArg.h ../include/ArActionGroup.h \ + ../include/ArActionGroups.h ../include/ArActionColorFollow.h \ + ../include/ArACTS.h ../include/ArPTZ.h ../include/ArPTZConnector.h \ + ../include/ArActionDeceleratingLimiter.h \ + ../include/ArActionLimiterForwards.h \ + ../include/ArActionLimiterBackwards.h \ + ../include/ArActionLimiterTableSensor.h ../include/ArActionBumpers.h \ + ../include/ArActionIRs.h ../include/ArActionStallRecover.h \ + ../include/ArActionAvoidFront.h ../include/ArActionAvoidSide.h \ + ../include/ArActionConstantVelocity.h ../include/ArActionInput.h \ + ../include/ArActionRobotJoydrive.h ../include/ArActionJoydrive.h \ + ../include/ArActionKeydrive.h ../include/ArActionTriangleDriveTo.h \ + ../include/ArLineFinder.h ../include/ArActionTurn.h \ + ../include/ArActionRatioInput.h ../include/ArActionStop.h \ + ../include/ArActionGoto.h ../include/ArModule.h \ + ../include/ArModuleLoader.h ../include/ArRecurrentTask.h \ + ../include/ArGripper.h ../include/ArSonyPTZ.h ../include/ArRVisionPTZ.h \ + ../include/ArAMPTU.h ../include/ArP2Arm.h ../include/ArSick.h \ + ../include/ArLaser.h ../include/ArRangeDeviceThreaded.h \ + ../include/ArFunctorASyncTask.h ../include/ArLMS2xx.h \ + ../include/ArLMS2xxPacket.h ../include/ArLMS2xxPacketReceiver.h \ + ../include/ArLaserLogger.h ../include/ArIrrfDevice.h \ + ../include/ArDPPTU.h ../include/ArVCC4.h ../include/ArMode.h \ + ../include/ArModes.h ../include/ArTCMCompassRobot.h ../include/ArTCM2.h \ + ../include/ArNetServer.h ../include/ArSignalHandler.h \ + ../include/ArAnalogGyro.h ../include/ArMapInterface.h \ + ../include/ArMapObject.h ../include/ArMapUtils.h ../include/ArMap.h \ + ../include/ArMapComponents.h ../include/ArBumpers.h ../include/ArIRs.h \ + ../include/ArForbiddenRangeDevice.h ../include/ArVersalogicIO.h \ + ../include/ArMTXIO.h ../include/ArActionGotoStraight.h \ + ../include/ArDataLogger.h ../include/ArRobotJoyHandler.h \ + ../include/ArRatioInputKeydrive.h ../include/ArRatioInputJoydrive.h \ + ../include/ArRatioInputRobotJoydrive.h \ + ../include/ArActionMovementParameters.h ../include/ArSoundPlayer.h \ + ../include/ArSoundsQueue.h ../include/ArSpeech.h \ + ../include/ArCameraCollection.h ../include/ArCameraCommands.h \ + ../include/ArSonarAutoDisabler.h ../include/ArActionDriveDistance.h \ + ../include/ArLaserReflectorDevice.h ../include/ArRobotConfig.h \ + ../include/ArTCMCompassDirect.h ../include/ArNMEAParser.h \ + ../include/ArLaserFilter.h ../include/ArUrg.h ../include/ArGPS.h \ + ../include/ArTrimbleGPS.h ../include/ArNovatelGPS.h \ + ../include/ArGPSCoords.h ../include/ArSonarConnector.h \ + ../include/ArBatteryConnector.h ../include/ArLCDConnector.h \ + ../include/ArSonarMTX.h ../include/ArBatteryMTX.h ../include/ArLCDMTX.h \ + ../include/ArSimulatedLaser.h ../include/ArExitErrorSource.h \ + ../include/ArActionLimiterRot.h ../include/ArRobotBatteryPacketReader.h \ + ../include/ArLMS1XX.h ../include/ArUrg_2_0.h \ + ../include/ArActionMovementParametersDebugging.h ../include/ArZippable.h \ + ../include/ArS3Series.h ../include/ArSZSeries.h include/ArNetworking.h \ + include/ArServerBase.h include/ArServerCommands.h \ + include/ArServerClient.h include/ArNetPacket.h \ + include/ArNetPacketReceiverTcp.h include/ArNetPacketSenderTcp.h \ + include/ArServerClientData.h include/ArServerClientIdentifier.h \ + include/ArServerData.h include/ArNetPacketReceiverUdp.h \ + include/ArServerUserInfo.h include/ArClientBase.h \ + include/ArClientCommands.h include/ArClientData.h include/ArMapChanger.h \ + ../include/ariaTypedefs.h ../include/ariaUtil.h \ + ../include/ArMapInterface.h ../include/ArMapUtils.h ../include/ArMutex.h \ + include/ArCentralForwarder.h include/ArClientSwitchManager.h \ + include/ArServerHandlerCamera.h include/ArNetworking.h \ + include/ArServerHandlerCameraCollection.h ../include/ArExport.h \ + ../include/ArFunctor.h ../include/ArCameraCollection.h \ + include/ArServerHandlerCommMonitor.h include/ArServerHandlerCommands.h \ + include/ArServerHandlerPopup.h include/ArServerInfoDrawings.h \ + include/ArServerInfoRobot.h include/ArServerInfoSensor.h \ + include/ArServerHandlerMap.h ../include/ArConfig.h \ + include/ArServerMode.h include/ArServerModeDrive.h \ + include/ArServerModeRatioDrive.h include/ArServerModeStop.h \ + include/ArServerModeWander.h include/ArServerHandlerConfig.h \ + include/ArClientHandlerConfig.h include/ArHybridForwarderVideo.h \ + include/ArServerSimpleCommands.h include/ArServerFileUtils.h \ + include/ArClientFileUtils.h include/ArClientSimpleConnector.h \ + include/ArServerHandlerMapping.h include/ArTempDirectoryHelper.h \ + include/ArServerSimpleOpener.h include/ArServerInfoStrings.h \ + include/ArClientArgUtils.h include/ArCentralManager.h \ + include/ArServerModeIdle.h ../include/ArSonarMTX.h +examples/simpleServerExample: examples/simpleServerExample.cpp ../include/Aria.h \ + ../include/ariaOSDef.h ../include/ariaTypedefs.h \ + ../include/ArSerialConnection.h ../include/ArDeviceConnection.h \ + ../include/ariaUtil.h ../include/ArLog.h ../include/ArMutex.h \ + ../include/ArFunctor.h ../include/ArArgumentParser.h \ + ../include/ArArgumentBuilder.h ../include/ArBasePacket.h \ + ../include/ArTcpConnection.h ../include/ArSocket.h \ + ../include/ArSimpleConnector.h ../include/ArRobotConnector.h \ + ../include/ArLaserConnector.h ../include/ArLogFileConnection.h \ + ../include/ArRobotPacket.h ../include/ArRobotPacketSender.h \ + ../include/ArRobotPacketReceiver.h \ + ../include/ArRobotConfigPacketReader.h ../include/ArRobotTypes.h \ + ../include/ArRobotParams.h ../include/ArConfig.h \ + ../include/ArConfigArg.h ../include/ArFileParser.h \ + ../include/ArHasFileName.h ../include/ArConfigGroup.h \ + ../include/ArRobot.h ../include/ArSyncTask.h ../include/ArTaskState.h \ + ../include/ArSensorReading.h ../include/ArTransform.h \ + ../include/ArCondition.h ../include/ArSyncLoop.h \ + ../include/ArASyncTask.h ../include/ArThread.h \ + ../include/ArRobotPacketReaderThread.h ../include/ArActionDesired.h \ + ../include/ArResolver.h ../include/ArInterpolation.h \ + ../include/ArKeyHandler.h ../include/ArCommands.h \ + ../include/ArJoyHandler.h ../include/ariaInternal.h \ + ../include/ArStringInfoGroup.h ../include/ArSonarDevice.h \ + ../include/ArRangeDevice.h ../include/ArRangeBuffer.h \ + ../include/ArDrawingData.h ../include/ArPriorityResolver.h \ + ../include/ArAction.h ../include/ArArg.h ../include/ArActionGroup.h \ + ../include/ArActionGroups.h ../include/ArActionColorFollow.h \ + ../include/ArACTS.h ../include/ArPTZ.h ../include/ArPTZConnector.h \ + ../include/ArActionDeceleratingLimiter.h \ + ../include/ArActionLimiterForwards.h \ + ../include/ArActionLimiterBackwards.h \ + ../include/ArActionLimiterTableSensor.h ../include/ArActionBumpers.h \ + ../include/ArActionIRs.h ../include/ArActionStallRecover.h \ + ../include/ArActionAvoidFront.h ../include/ArActionAvoidSide.h \ + ../include/ArActionConstantVelocity.h ../include/ArActionInput.h \ + ../include/ArActionRobotJoydrive.h ../include/ArActionJoydrive.h \ + ../include/ArActionKeydrive.h ../include/ArActionTriangleDriveTo.h \ + ../include/ArLineFinder.h ../include/ArActionTurn.h \ + ../include/ArActionRatioInput.h ../include/ArActionStop.h \ + ../include/ArActionGoto.h ../include/ArModule.h \ + ../include/ArModuleLoader.h ../include/ArRecurrentTask.h \ + ../include/ArGripper.h ../include/ArSonyPTZ.h ../include/ArRVisionPTZ.h \ + ../include/ArAMPTU.h ../include/ArP2Arm.h ../include/ArSick.h \ + ../include/ArLaser.h ../include/ArRangeDeviceThreaded.h \ + ../include/ArFunctorASyncTask.h ../include/ArLMS2xx.h \ + ../include/ArLMS2xxPacket.h ../include/ArLMS2xxPacketReceiver.h \ + ../include/ArLaserLogger.h ../include/ArIrrfDevice.h \ + ../include/ArDPPTU.h ../include/ArVCC4.h ../include/ArMode.h \ + ../include/ArModes.h ../include/ArTCMCompassRobot.h ../include/ArTCM2.h \ + ../include/ArNetServer.h ../include/ArSignalHandler.h \ + ../include/ArAnalogGyro.h ../include/ArMapInterface.h \ + ../include/ArMapObject.h ../include/ArMapUtils.h ../include/ArMap.h \ + ../include/ArMapComponents.h ../include/ArBumpers.h ../include/ArIRs.h \ + ../include/ArForbiddenRangeDevice.h ../include/ArVersalogicIO.h \ + ../include/ArMTXIO.h ../include/ArActionGotoStraight.h \ + ../include/ArDataLogger.h ../include/ArRobotJoyHandler.h \ + ../include/ArRatioInputKeydrive.h ../include/ArRatioInputJoydrive.h \ + ../include/ArRatioInputRobotJoydrive.h \ + ../include/ArActionMovementParameters.h ../include/ArSoundPlayer.h \ + ../include/ArSoundsQueue.h ../include/ArSpeech.h \ + ../include/ArCameraCollection.h ../include/ArCameraCommands.h \ + ../include/ArSonarAutoDisabler.h ../include/ArActionDriveDistance.h \ + ../include/ArLaserReflectorDevice.h ../include/ArRobotConfig.h \ + ../include/ArTCMCompassDirect.h ../include/ArNMEAParser.h \ + ../include/ArLaserFilter.h ../include/ArUrg.h ../include/ArGPS.h \ + ../include/ArTrimbleGPS.h ../include/ArNovatelGPS.h \ + ../include/ArGPSCoords.h ../include/ArSonarConnector.h \ + ../include/ArBatteryConnector.h ../include/ArLCDConnector.h \ + ../include/ArSonarMTX.h ../include/ArBatteryMTX.h ../include/ArLCDMTX.h \ + ../include/ArSimulatedLaser.h ../include/ArExitErrorSource.h \ + ../include/ArActionLimiterRot.h ../include/ArRobotBatteryPacketReader.h \ + ../include/ArLMS1XX.h ../include/ArUrg_2_0.h \ + ../include/ArActionMovementParametersDebugging.h ../include/ArZippable.h \ + ../include/ArS3Series.h ../include/ArSZSeries.h include/ArNetworking.h \ + include/ArServerBase.h include/ArServerCommands.h \ + include/ArServerClient.h include/ArNetPacket.h \ + include/ArNetPacketReceiverTcp.h include/ArNetPacketSenderTcp.h \ + include/ArServerClientData.h include/ArServerClientIdentifier.h \ + include/ArServerData.h include/ArNetPacketReceiverUdp.h \ + include/ArServerUserInfo.h include/ArClientBase.h \ + include/ArClientCommands.h include/ArClientData.h include/ArMapChanger.h \ + ../include/ariaTypedefs.h ../include/ariaUtil.h \ + ../include/ArMapInterface.h ../include/ArMapUtils.h ../include/ArMutex.h \ + include/ArCentralForwarder.h include/ArClientSwitchManager.h \ + include/ArServerHandlerCamera.h include/ArNetworking.h \ + include/ArServerHandlerCameraCollection.h ../include/ArExport.h \ + ../include/ArFunctor.h ../include/ArCameraCollection.h \ + include/ArServerHandlerCommMonitor.h include/ArServerHandlerCommands.h \ + include/ArServerHandlerPopup.h include/ArServerInfoDrawings.h \ + include/ArServerInfoRobot.h include/ArServerInfoSensor.h \ + include/ArServerHandlerMap.h ../include/ArConfig.h \ + include/ArServerMode.h include/ArServerModeDrive.h \ + include/ArServerModeRatioDrive.h include/ArServerModeStop.h \ + include/ArServerModeWander.h include/ArServerHandlerConfig.h \ + include/ArClientHandlerConfig.h include/ArHybridForwarderVideo.h \ + include/ArServerSimpleCommands.h include/ArServerFileUtils.h \ + include/ArClientFileUtils.h include/ArClientSimpleConnector.h \ + include/ArServerHandlerMapping.h include/ArTempDirectoryHelper.h \ + include/ArServerSimpleOpener.h include/ArServerInfoStrings.h \ + include/ArClientArgUtils.h include/ArCentralManager.h \ + include/ArServerModeIdle.h diff --git a/Legacy/Aria/ArNetworking/docs/figures/ArNetworking_overview.png b/Legacy/Aria/ArNetworking/docs/figures/ArNetworking_overview.png new file mode 100644 index 0000000000000000000000000000000000000000..1157e36a69498ffeee379bb1b2c2e23d032f806d GIT binary patch literal 60624 zcmb@uWmuJK)GfRS5fBgoL6DFTP)g|rX{EbSI;BAxRFn`&=?*Cc1f)yp4(SHz5TqNv zx!mu2o$LE?{++e=cI#sKtoym|8Dow)<`bl(AdQPnhK)cVaG%OZs2~uir3eICDkdtt zqn0#P2LD5GQjr!z6!wy@!5=V;WThn#SIB?T>T;ss9V~kpZ6^fcdOz|%l&TLasqp4? z=cn?L*T-;B2+8QCYwA8D5cd#IC7!6cO>9oT(j$_-y8d_EnrKa36umf|CQa*`k+{53 z$RG0$#YRC=%0_k;o6|28nHi0K&fIRn!(^0{{4BHm%d@KH;-c6gwaY;dUzzW?_PM*) z;j)>z`AW>>c5iQw3a30Fd^17}lbW0p1u-P&;o;%#&PSc~^((WGkpB8K37dgTJq{k8 z*;VvIx(CQtUT*GcRJlPFqm-ecp@YK?Ljj|&^c{D1_wCt+qFRrqPoHXQlj32BnjjFO z{I9mWE>2y<0>6CO@W&#|nwhTitXS+?Tr?32OiWBvE1z!)sQLG5YislUH4=}?beF?S zZm9rYY`HsLbvStUmA}K)<;7^xb4`Pb){l2DFE4rTqzTWbVq`8 zPMDaPO-xM0#Ksosls#i6zI*46Tq5_Mi?gFInnenViXzUdN(u@JCMG7XuH}V=g-VQi zRgRx!=u|W{ua;t;!$NDF*HnTtSoJEEl$83*tTib^ddH&UQGIX+%hT^&ls^~_3|&brd;WY@GSX2-1-_L!W{(SMwk+GM)grK+mx<6WNe z(o$7T%_2QQL`#c)sTr;g3PN}o?uLb#nTCeO%iEiRoLo*$&dbY-oPr`pA$fgy+04e~ z>*vp9j!Vz%?6z6;tNq`<4{rJ0*eK@Wa*(5#N+5Q6wC%e!RR!B9;<3*NFJ|Vivazf; zDFyHOFD@+|Y>qp@UfXaB3Dtf5`W0^e`^(9g@#@snR4r!M!dN*rR@RxCSKGTwT|$C_ zt)Ud2b3a}yB=h$q@s+}LPEJm&tgLPjGr!Q_nEcA( z;{Num@9ttpN=k~;a<`#IMM=rShYx?-^M+B07*spw6&Dv*R8*+pq7ad6(IZ6V(XU^B zwK?_}jLvSh9{&9^R&1=L6<1eRr^ReG^JgIQx>LgF$cPy`$5p-CPR6V489_?B;e7R< zKY!lkv7M^(JSs8mvazvgY;44%;OF!_v=Iw5K^mO^KYu8di16db%8nZxE$^6`(Y)WMS9|hmUlH+2qnUSfdLlXazWoq!GNYJw;iJ|8U^)dTLL5` zvA=%(s&ZPP6!PHY;yU>CSyuc#&b(vQty{NPSy=^MZRu6o&-dJBqEnZQd08SvuA>oVfZS_%G5;I z>S}5a&EYDyu-~n(uiIeD4{p!Y3E0p1EzUjRPE=xKW@LQ9)~~JpxipUIL2iD&&w8lL z$hWjK(USa-+FC(*`JVMrbVLLS1S3Ye5DsKelE8pp{Mr!+s~Z9gFFvYs1yNJead7M{ zb;ZICba%m)bX+_9+>N?KbORBHgP4;wTtWX@oKOE)ug3LH42v!*8d`EvlD`-Ps`;rZ zr}&C&`9vv92S>-qDjE)t;(R00O}RjX((QArTL|ITN{l8e=;WLhN^txF*2vIi*KjdX z>%KQMG?XbFR#J-2&&LP*+11!cBO=lO`}6ws>qH*Ak-@Y?ZIA8l)s$x_xCq$3td`XhOgza9@!jy?t8IO)DYJ}o}8Q<%dFkFvPVcrI9i}v zVbT$4)|0>|AONA1!?VI-AR{S>JddK*ejXL?wvt{P8r~;94h{xi1`~_Zdg2%({`~oKh&vE{vbA;{2*f!! zILbB9FmPU&iJ6o`q~VB=`R;MBe*Gq;^J@P*oTym3{l)1)TPTGwgOi-RJcXd!-%k%z zL&^Dm73vGnzfDLWt9fPI8nUyu7d7$I_0Pn-63Ra}`-?@lg8nI?>=7NE$=|u3a@-x- zsBhoCy^c#pM}&=wgY)Urr^cqHg0ElWI?(UuJTUnb8#~A;uRH{%0A7em4Ngi-Oza=- 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%0A1*&iqbC;_FGm>eQ z81~uSCl_ip@axD3P1z0Xg3rq`J(D~SZKZ$DOPL5UBmQ)TX$FnzbscG9TYCLLfQrz; z-Cd&M^XE~QGq4HC^T~eSyw2BONZpRlJ%`DUK>!sq>w}YvV0UZ~fOLNDkZ-gv6&1 zba!b=#4B;LB>N@4<<4qW85S>Ems$giqNQ!8FN;VwZ;*KPs#xzG2H(bv^-`vRmqP3d z7Q6J(m|I!32~e>}H+_k3@*4l_@T`{$m0nM2{&a<`JI8-#N~X~@fGEEq8sS?^EiFg= z%yjzvLdQ!PvGLipX>wc9(hT-e#-C(bz*{K!j$SEr8idSQcl)^5$u*wqr1ehi>R{XM z{Wj`aVz9t|ayt8fjqx$7GfM5O^#ZK1)CkFgI?=v%gs4M*>mxYQkOY zc1a>vK#LVfTDbca<#~@2Qzq`z(~Dd~;4*!?G(`Kzi~wtAXAN#P-JWk1Zgl88tK+S_ zym{7i>WnyAK58{@?=7Xkw7Y?bQtz%z03@OQW_*<2RR;BA~ zZD~sD1i7cD=XO}RUk5)&O!_ds)Z)rXsvR$ABy_2SWFEp-;J@c zd+zZu?DISu2(=SkI-QN)NK-W(ZVi(s9KA8xO;|JDIX49SvAu%>wViUnlmVYeWhC?k zGJRX5ukQn{ZWL1d1lsb3`g+~g`o}=g6%Hz6Po{j1xOB;H_Bu4Vm=Nqf5ZPHtH&l5q z-Ms0JGxxBkwxISnwMim;8%zx54}3Lq0lgErGE7QF@{tV;=n6GFvMY_N1QZ#HgPJZ% zEM)P*%n<{m+I5{J={IQ72PwTVxuH7WsCxJTz!NTG6{(d-+SS%apFUkdH7D!M9LIKw z$_;yc>6x7^)yXo`y)~?@#pk}C@`=0<-eDd8RmIUCzf@G>d1{>4DoN4)0jOCpmM81W zvneet-GRJ6B_+zZQwvYL?bnY?NM4*czX-3REah@nqI%3;kl6aKU)fttTq4?_%>E=9Z93Nz%T45c!s^^t_=?93@sIRK(z zKx&dq%)~c%xd0?FO>BeN~bQ_S;) zWLFA2&(~f0(wrpIXRMUCr06m!o@m(ZOZr?eL>?$nWuMbt$=fC8UTrTLCWi_Dm~i23 zNn6-|c88f$LgZfUlIdG8ddzZ>kRfjGq1UCT z$m!P&A0=%lE7HiPWzp@0a<5(2zOFxBZWVsD6WOrzK?OgRU|P7WtPXnw2duTXw;(Ht z&-`_NWkNxp*)y<{@P7SqPjXe$Y?5Rp((Vo zaEGH=Iy66V6_k6ps{hXa$=us|d#==Rske1+ir|U+aPnzF2 zF4VTd-_xj=bXP`Hkn?I=c_;qC*S~!;^2NkN&oP2BTn|uV?)by}dy~favL9am`Ay5= zKjy0~&lO&S$Ew;Re-;1!{Wkb!$tZ1Yxq~86c)ydXM94AYMX#E6w>>Q>YWMeF^?cY* zG(M={T|xKF3@(NTlDHA0sY&yNpeD4zRLO#q~(H#AM_NEx4OC$P?6%|$uOe<@ZT-OF)Xep z7@Vp2OKq4>h~oeaAX-7`v%6DojHRZuwJd6U>_8*_?%nMJb5x`T>ga68vx4|V?87x{ z(vI&V6BWW9S|MLWIYTQfFGm77tt{@`xhKhvR!zFI1I}W4j4NQQ24N zjszA}$TZzn-x2t$t)&|eD3Cu$sTp2Awe!wb7k15mefRg`c)+z%0H!U!=|#$@G;zy; zjBg7I_3Z3aF*}rc4Qu!P+c)BOukAbjlkc8hHb20cTac(R?IOd9k>T~l!|nIyLWcJe znG&FMbPzZnj64l&e1Z1W!8|^pPYJscq1_XfhYs@M*^mA!uapK+&RYj31on=Pk3XXJ z>fdScjV{M`_Gx!>Ux$<4Zt);2SgHx){vtc%H#xvXk)@Yt87#XH9=;rh z3z905240h9ks=pPDII2ZKRJ02WO?NXDLz+M&sL+^>j%m0v9AXQZZ%}Y3yhui6z@ND zy4~}CN=a|^-CG)T$uiw#vRl&;b2>;jpbvO2&3K1}4@g7DXleD*xp$`*Lq4(h=n)#6 z;yzJlnxyBc_R~<33XXI|U%ArOM#^j8_j1%&|r?Dk*q7Yzr|N_4PYY zEx83HPjij~m2(L)xn_>+9l}2E*38gQ&xG+>zLryH z)8x9T*uQTChiMX>q;GpG{eHjN?4Pr8!lfahFZ&PO&@a)=3MW*WMXqzWLb!H|D9D0> z9G_p#%FjP!Ui+0(n_Hrt_Z&t4ir;1yMnXwhQj=qeNL7>5!h0U-{ zKsgW0*kbgzH0cBlEnRV^+TNG^!-Z!_Sb^@^=%v=5 zmc9P8@9qwo$T{DT^VzkMn+cuwa|Jv+I?T}MBW?ub$N!X#j^1u{i+T+G%cDO|QgjN# zu^o!L0n8B{)*p|wPVqq&+t8-dq(({xoQn&h!9{v(1L-QvUtp1WQvIPwT+6d?mS@tL zN1fh}>3E|dw%}rG=BvIAVxj^Y6d^+IP6xww_1A?lF5pWjFVVm2PxS0gd;VEDbwlyl zUCz*vhMP^-GVsv{~+BeWi0q!0W)7>Z%#aV6Zuwa5$Qi#?%IeL)v zbS4xRIu7V3KDcYumtb+>axuN1zNnLcy^0_VJ@0#elgF%T=&mK8^(0cryW2;{s4lKM-}SBB2fP{Hf|ds@AI?D<+!o!DFULhWBGv5(Uu{kXe8-Ao-dZa2E6e@3`|} z?k@NQV8uj}B0RX!hFyVyi%8E4*L%)yNdG=xO=xQ9(O|@i4*{w1Xh(@5fm5 z(W9ZsHuAX#8U$pm-0kgsVab&t2rCB+SOK+5Zx}tON?dz=WDBB`#EiCy!XGo)=NTcG zl$+?#2#19W4UpS>I*qY`!-Fs`DoRR93NESd#4YxqOPoiK=9+O(<6PcI^(Rf7xPwdy zlYOj`+-PU-(?f6enR21E{^WEhFHTFwuO>47kEE&bNOkDi2Kf2-^4bs3ht}3sgkI$6 zlkx8%R(<|see*|Ci`Oaq7c-ffi09Aksd-{?8N&xQ2^PG>22MMknkf%7cosNtw ze)dehd-uy2zfD26&6_mdNyKOU1^HZ4!$xMoqqN5|sxV*F{lzv!#UfXAZaSE71R^Jx z;LJ%zFU86&Gd3Pe_cKUK*|n{XtQlwZmZRW23W_*(Ec(8|QjF@21+xPmL?X?eF`p%o}Nw}Xa2&>)N~wjaAb!F z+6Bj?{k=wTAJ$oc3=e!iN&M|GalH-$48F4P7NdU9N5Q*%?KIxX^-KGZJV1s<^s~^! zGa!y+WeYMrJU%?wjgM@-{S?vOK~FB;H{9Es#V|&8RWr!xiM^?Msu? zFlkbjmFYLW;CHWlzcyu2J8J0yG3a_hlMie{f4hmPX&4K@fn_EckD}d9WmVM}kG5Ze zK^~$spy1N}3+glc#j==)MkfnD3B0G|R$oZnO^a?_Tf1HYz->EvQvX^qNR*YIxlWm6 z2Kdj!3ra)%m(2!(Cj!qS8x%~K;>86h81Usa+by-$BVTEy62zzt%A69LeUAlIU9I?0 zL8j`LiLihP9;mb&9P%oh@I$1{WW;rS$WO}Iv@{n(!vdft>+(0CsBNIZZa5Qb9Ao17 z6=d7I7b;fFR4#*;H#&O7+@uvxc^qH?4rH&LQ&C1PxwQNy;geKg#N~PTZXZ7UkmHE1 z0Ab%-t>N0Or4kAaA0Ain@))Q}%g9_sj{5a$6NTbMqbn_9e?+yO+A&;l;-9 z0+~<7$nRZp3%w~#jg8#KNRLqP&s?_bl-0`nUmd1yq_!r@;dDq#NnJ`vSaNO4MJ&`p z^6s|vG2V$)MWS$BZ=0fGKp1cXIU@JL*W@0+Eni>}>h3Mu{4XivfB^~#LC;^Zw6Vch zGS>BWyVRMIM|fVy@dQlcRU2NuBQ5kvvDIJQ5bJ-~XHmN&-A|ExUBotwEE6C#@$zLxkG;UgN?KZ)t70{? zie7)mcM#EAG-WAS6@=L0c*~b!(=T4#)W8bWYU z{lP({r3pO-Zp&{^8Fs7_I|!s?F0`App_=HfsF+vjEZ|?1K0vV;U(I%(LrVaQ$6fOI z^XFf9fYPhhCGN^~_rzi8U*6o~r*#GlxcT(yR-WyzU%$A%0-hdL7t>Xq@Q^NF&loHr z5BvJkEicd(l#;Zh>#n%vy?BZ=4e+2)3%I01P^1W;jq#l>@|y2oWqWFn-m>awiSv17 zn(Pq!2yyGRxS_4E2r|<|y`~3P^Ol1iOvW3DE|u~9@8NNt0b7)bgo{H4i#`7&L%cwhWRSwKyUD-+OW}`!+ zK9weqCi4IBSaqS~)@@91C6E#MPjIIN20lirCN#C+Vshig4I=WJvEsW0TKuT6<7w^K zkop29hB_O=JK!~o`#(5Wf;|Dp0XvjNZez)={a+Y#sophHa+9k%&LoVu1EE6*2CqP^ z3ZN;rMsb)dkV}-bZWwl9H!7VUhU#dtm^@cn68~yiBZJzM%Mv~e*Fo|Vx;r+-ocXBY zFE)MIGB@NURvxX)ovWvnjJHFlgn&B*%Jysr-f+Z zFWv@D$ylcH@$$F(Q2L%6yVi(4l{K;Qhwu3wI6&&V2&WnX663^n_UPWTz5BjS4&&B6 z898?9P{j3e{e{n1N3bKwr!QiRj?Pakje~SYDjR$S8tS8MkBQeaJ}6~#(b_4ETVlqD zub4YzBV9K14V}U@2Y*j8C9(wHz#bDeo}c|N1kA;Dq87~S$yvyxxONC@EJWzZlQal% z+m+V!J4KFz#B!{*HVcT4&(^PJX!FC2fVAlS+qM%>Ui7%INJKpj+e$zn36lG*U`|>Pnf2| z95psI<%f(rd~^A**@L7c+MymsL^N!HLJS}R`42{s_`JO30gunY#>4gis9x>~v`<5WypmFFWn}|a{&T)fdz+sNWlL&EA|P$vMmCSvGwGA? z5D3VAU$-BDg8$6D(PGyvJkSO0KTA1j<(<7m6U>Cz46Gg4$^GtfJ>}%wn`@H8T)*yv z6+?_hiWA|}e%jDq6%j`$>X3e8HT?oxEpRb57IfE}7N0{^jU=p|`H@uT>|CPyVs<`v zG&zlMhXGL|-N`YsM0Sb)pt2=nD=02bqww^X zLPmYVXW`PNeS7uNLg8dne+Lp;=Ai)SHSp5zchGZe`#Zva__Bf{znYSFIb zZn?Sk6y!*o+-R64!V;Usjo=!EY?*62i__y+`xe&=cnU(?wmOgBLS<-XjJBU zZ~9T|fm#B=@x839==o-P!)lW|=CQb=$y=%XbaYa&SH#mp)%jJy73qL8R`8jsD?3XRH1vu6gpeZ1+L#d#07MZD`?qOTmRXLfUId@ zVddPc!hJ=@z_2H`PoECl8q=sPrk4*Gb+6J{Kt$~AxlnP>cr?H3=Yxk2GpTo>sVO_X znMBq&>88n=T)k&lwlXGyW}ND(s@{G2q+#jP{^a*|6S}&T33GM6E+idcj6$U|$sS#f zPJqJS=d{k5JGcJJ7ns(0c-;YYMa>g->o5^J$Vcui4F?ty!2=Z+mQ z3*l8v!lSRA4#W~pGSRbk-{~4-orehgNFq0;zM!o2_?p9vbsov?Je%b5{-ph+5!_(! z@z}0#s!R2g!%e)XsHeRA-g9VfDZA;vMZ}MZN?X&@OxcMMiyXu^jVjoJ#$0t5q}4gC%FS{n~-hLD-qs4jBxK zqiLLUh;4pm_%yn5nsI~r>57vmJw$gp6jbkRpXj-Bh{z!7!(o&y>sGJcOpsS{Zydn& zKXT-S^xIzad;yzK2`5m2@h7?3l&~9OCKg;hMktcy#}x227#nW0QuRnA$Hug+nd4 zVQr~F57GF1P1tE(lPsuZ3b^W@5{W2;Vl>6|r!xyV!R9H?g36T-PmfMB0YXMbrmptJ z@tqb}8Mtv(P?Am}&!=8SkWJPCWqkOU*ougUnnYAr-AsqoW8@ELw@s34t~uU1H5R?j zf|C>2$Ao#hkgWumqowhS;<2Z6%`}h|QcXD$efW$uCm%(*`tRJ|X18!Q=oL?-^=am> z&9vcj)XdDyg*;@!goxFiQ>Q%i%+AY0ve`(kvc#d6y!@;r6D9(DFYVvl0MMiBx{Y}e z9lLjw@B&o8QEsl4l?T8*#TezS;*y<0pzhFt8*-%Ob@{gVq*Q=f>?&rojw|eA1idoB z>6IQK_58e$EzRE@#!C6A7*r|9vc2h8)b|}m0_jJfIHPzcCohk2E9AJf3?jyfF@X4R zvsYAXY-z$O`Wh4HasVHyQ(AjFy@n4<+h+=83__P#0ZjUCCP;W4^S4CvivKN;%9Se{ zp-TEl46BxrTt!%vpT1C+%;{!w*E}W^G*P35VbuscVgz9a07lD1O^t(%%@g;D>04?} z)NS0>r?1dW4fjvBwS^rB5WLw;b(h8pjbKu$(kpAa9$ixa;3FsZ?$s;LWB&bpv&^}z zD5THN4SxOU(#H@yXYM%7;|lu zni@)pRx;9PyB2EZ$URO}Lv1&2pA1ao+!e>fTty$h9N zwm%3*BG~oL?AaZ!sPvHV4-U>DkVZt%I7m852;vf)XkV*hz#Q(*^r=zP5a2of@Gi{D z#oguR&*8l(x>l>pV-!GI21R|R_KP*6_`Z=3;;Q`S%0pdh>MIEerymOE!^g)5tK{&b zM|8!z`7^$-QpmJ_mvE#L98^FyUAi6)#owhC!kh%(qaFY~bkBu{E5As48;ch#P$mtG zKnFyATiMiYlq>v8kn60vD?s%iAA=YIomzgMRMn4+Aq!EKzhB69v+%!i-H# zfe%7rHV-0%2&TGN7*lDW>zc?OqBfu!JhRK>{!+<-@b~v$!3VOj&Yn8(pu!1Noa2fW zg|7wwbc<1ZwhRC>MZ*LjI8<{DHWXNICoW-Njy@h8KDR&EKb%Q#zb=_R6&<41(j8Xp zBP4rkYtwDluEj8303X|XhzafdXiF$gs7%0_aUxtmV&!%rK>rkvIcqW4ci+AbDxJ}V zlfHpCfq@SAsYW3UZ=bHSwstf0T;EXoCayor_Bo!8@a=I(F~gy@zxL%J~+TozYirm)ChelTN6m zol{?6s!S^H2K7%FKmqaSI_)Zd4ZjV{Cn+QEcjQRXbKRAYPR2REk-x-5Jc5lVusaUg zMS~nQB~=@isXu>>AmqZV8W<_dqAL3S@o6mwj$T`g90A$GICnrHAUftMfD<|s4W`+4$ zm~qKd+EuY%KQ?xq)p|#=3ZRpdO{8Wd5yk;tUN#>IFOqIR*2xPsUk&mIo^4 zB8$v&MZ3Gf3l;OvHwkI1A^|7k&AgIEN+OS-U7=%CZ2C= zYSb?4&zNzSf^(w5V~R=uF#*#>_7fKydyV$eZ_?xu!jM1kZ@~>VIy#j&&Nva;D9A%g zoNQ-5@x02#^B^{g#X$xN=IexkGF2X#90%DF`D%wYSBvq_x-apYlkggy_A}fqcX@AB zjmS!>k;yCDlOFqSyE85g98T9~Z3{bGz20wPv3APOC)Y{?B!KP)N(uH?MYex^>nQ&| zh!cjo7rCpoI2~W~%^?_h-FLe5T1RT5!BP=vY345^36VpkR#H>l8quDhVNuEo&hoHT zN)ju*X0m#8CKbJghBH?#1sfD(=7u+W^pyP^2lL|V)~vyn2P#0w?S>zY`Z@KQ_7OT3 zY5TN(z8fdT^C#vCExEV^)fRWDF|U&A&(63G{69^5@4jrGUG)+E$vcxT}P`(AL&0 z)j9IowH;Ll1cPpCnSDJ6YBYMft@PcUeDQfVg-xy=uWM_kfHQR6>=HZQx~}c>=zwGr z@WE0m9~@ItF<|h8;h>t=>+Qi7CG?s0b?v7lTMFrjhKAAI>{l&q30uQ9EVOV?@_eZ6 z5;R0{VS@4#m5lGlqoM|QjTy3hoLRu6{WmT5K2x`gkY6-6qA+~H+=#t{w|fhI$v<8Afjs3$ zeSOb;)3~TJH&z|0?gLP8T+7Zf3Tz13186c|C$t^<1p0KFit+1Pw6(HQ?_bahotWa!k`{Eq|82|y@$Vx|=cV*fGu25O zD>4DD0OL)1cZh)pSCW%aN!kqjgdef7@tuam)zWKT_D<_3m-56`K3G4@qsVRc`p4%E zLi^?AMGo8VUJ{GX$;W+a>eDS>{D|5HG@kcxVRC@E#x4%%pB936vxL`)Pc0WMdqci{E_DVj|GeBF znojYe-9wf`hGdh#19_*u#?dizYprF1Sqo!uNNS$A#EfDD;r--tckqa2Xab(eFOcaE zKY5=uPvgreig}?A{l_PoC&bOVm~XNBqnQtR3*C*E@yQ|eQ&tYoAHDa`0HZval*P-+ zlWwLhHQC_cTfLvw_Fs4VI$oL)5Ubny*%b?|3cITomG2*kj1%pO_vh~z8x%^3hOf-~ z4@C3FZfO=)OW*Cf&^-0t?RFpgbRMLsT+(CgT{6>-16Y;Z&=t4$bejsId&fw2fVUqP z$ec){Cz|El*wds=@7UBgRDs@s?o*HV^K*Z@m-V$C4$IFu0gm;OSOQJ<@)dbB^6Iy(X+UCI5_(?ynlYXKT7xWiU!EZL~NX{X)| z>uq+eH3zDz?TX!Ebo@`9%HOmNdq2C;H}mpH`%N?r+2>m~Z?3G~{bYx;+!&jYaRP^@TL)qC1K*=QR{i`Y2F(&aBN#%y|ijM$3O;K|P{K-e@@KQ({+$dtCnftcJ%V)NnINNet|xG`ZaO2Zg$$}O_N4miYrvt5MOprVQ!f2 z$;}dP$UTbk4K#v3k-Y*{Ay0F44@$PIiKIYEsD3w#Mv={(cF<^>uJ6mqv#e> zl~3g_Scz>PEYs@MF)r6LN6lJ8VdJZJs!TwzwVC4WN8q7*(>Q3BU5<=d)#G(Vrxc=W zX2mQ$o%D=r5_}IIexvs3`fheVpOO@rZ*##dVNcDHCnua7+W!tUip?^^_V=MWqju~m zy*oaB^tTeJnjL|gt=_wv67wzZbGZCExFNhQ8u4&@oGoh;`Gh*7JcKGupKQZ!Dw`#x{kM{&z07EfD2+ic8( zVMp(Sd&bzvY+irDY@~atSW(8tkce(o@7~2(WtKgB7|*Z;5(!hqbw7=q4r)4W+z9?$ z&K-1A7_%ICY^RUi6kTLXSA%XeTvG>irV3zl#%l&lJ$;FO@Kfh}l5D3mRzF)4-a7Qi z34o25GUeMQ7r2R0guh!!GkQt0jG3@v6GowLTU@RyuK3p-Yf1CP%i@z3R_)s_W^54k)2HItr<`A!RQjkheEj(1vSejz;{u=bwsJkaWxyG+L9*Ct&N{4zg@E5XscAKX$%>J` z3BzY7l$=wq1GVBLDl2#}*#zTEHZ|M3V-G^`StDFWEc~}ZE6G%~W`uTYPcldjkbnSrjPG}hh9GpMD%jD0~numK^t^&}g z?gJD`Z^QB3WIli`X2!F1G3zl;i*FNM|1s$jWmb+`-3W2>nD~T`pz?&587>N8NlC@ zjgPP+mKu<2S!AI%Bye+W*|KkU?l!b2J$b9wyv(;`oa(S)Q2-A}^t$hxhH&o5lka)s z%Becz-wobFWl&OD%590A0soG9dC#osTw%G%WSQlIw9k-ddej%rM8iViR1Prn?V7$v zKON_@NEzU^`2O6so16)JpS-7@#?%K{@A=7^X36UnCua*X)VU7_n07RZ9?Q&26tPID zz(wpL8I^)6V*?ebd6y34og_NFrFX+WbBoVA8H|-0)l;z+w?qm4e+^~c+>FILf5fcD zIOHBw$grMGKYy;ZocGwm^0XmBu*YwznSXrObsyvyP$DuhIC7Ld4=m2F(#=mBm^fi$ zueeo;^frJm+uPYOWhvXm(aU_{-;d>X$)00>9?Ra0+I?C977c4}oT`lJXnLknb!L!c zcs2Vj=AmYR#aC1?=z4Rzc8`m{_}%Sv^9ucq2lx0Zv`ozRY!{V@nyqPlE>|Msee@mn z9&>-)XQ!=vy~D@jRSM*th7F@E#0yd$YTAzE)og!R-nMy`2BF+lx6yOmPU`n9IDOXJMNOgr_%(6^pfYf_>3kyu0~Q69#L0m>8X0J+NXcZ zpJ*YTMhb?9NPwSTf&J07zqGWwy2vZtye6mL+c{N8G64M0lF6fl!J3Q_WZqL(%$+Oa zC4OPjL zU&vX{hqa2rUkd$k^jjj_@xJA`R^e^E^T&d-y&n5qTtCobN{%R4>=N5iP$q%;@=if! zJ*aKK8wZROi6lSORt+445!}jzMl^W5ReJe4OH1$Hw@;V{YuOo@es{)LwD?9up>n-L zfX~Wen&?LKQwVIeG&O0y6Pb6xZ+xm$PHyfCL^a$KD1Z3KfP;$kcX~$_79L*WX0qSm zk<{4DC#@FGrDmn1(l5VXsT)x!& z=d31<=)SLy#d3&~h#1GZjdhVA_VRSdQX;i|3u{yEQ@6jraqtF7*H8P7DWkJzdIQpI zAObRMS}9>%UI3z5s;DV@V;yO}K;snQ{PBXRpadv*ZHyYpaA~oIHEdukCv88cMhE5q zcYQ=cyKWuj#tauE4>rsRL6?qaE!&w%PsgWH%i=d|y?#BCW#gvGrQUupO3aPmg{a|# zu`s!}>@o)w#oSMma~aeB@V$`_6Q_6IXMO+3a4sT_Htg)Hrixo>KSwvtRaN`4VwvyU zAxu>YJQid3d>u$ApJM6?#muEcpaHVKf~kLf4#W?X5nQ5kzNLaa10X-o0miQ)r25}3J5-Ogyv9Nd;9Cm4u6-)P*V=JF(Zs=R?dv`lI`A0 zpz}j%HS_oX!uT^61}ZJzwrv|vi!X*b<27}BDxJDcAQzy8=(*ob{VM46A|ik@`9J)Q zACFpPvgB#R_vKsEmiAOopxZL^=+VvW)OYhV4=1@ z@uwPY8<<5Q5*;yO9dqeR{<)g8ibh|I$S5@_pYgyXpAip5ug@%T(7JH?jh(#tiN}OL ztdqPFBvDom6M(2ssu3I$yD)Xl1;2Bo0d3pTh6y}kjb$!30bJof)P|GkcDCUHt zM+&if>WUljGAP6u$#d>Jg%C@3e6op=(XH!md>&Rketco{aubtf%kr+b9c-!nXb~Lr z4Y!ZKQ*q6Q9ee(ja!nRLOpYLeiT>f~^_Y+s*vToj7 zf!_Fp$?73jKWQmi-9G(b&OxmaxoL0A);Jdz@c)8K*>zgfb8ygu;H@*GO$;{srtGh@ zTX-SwVOG{)HMN5gQOL*{H`A2Y&Z2qhoGTUk`!33;R_&9t%wke|Xxia~XQt5aT*v?y!eL+YX515kvpu+#!!; zmcfSO)j&f)X-DMa;$R;zvJ)Acv46~u20~o2{w}EPgtdn677ob7X>R6{qPM> zo$IzPza^*Yn}BBJ#c1@H@L5akUk_piO#`|E#>M2+y{Ue9 zaR5SmAj*%Y23`I&{(q;^)nDc`1o?!7gp_nZzEl0_Q*J+v<39|Uv}D^~BJslXAT^}G zv8G}AgKQ)xJPG~zxUg{Hjw)ZsA35(ri%dtNCiLRgWchu@Lsb z?o$t2`aB6xuwAQd-Xv4qa( z>hE+ld2D)3x2NUZ_A*Acia33IO6uKPm%6AI_LDTKI^HL4fU$+RiSdSmI(7qBCX638 zEW5lslY7hCk0;NS3V55sg-5^z9e1JRfc&R|T3Y0^pW2QIJ&d-T$t})lg#IiE5~jYP zA%}n=OQ2=`LokE`X&ERu)U93orV!0FUEEAGCQWihp-`U-BM7@OE7B;^DB5t?`(PkR zMs)rKOuc^nXT)_{rg@2STwzV&(QdvtIaK8aFS4+hYkE#+*M-5l7tmLJr#Z?l+Rp9A zi9^i^`O;TDkAD(uq4k0nnK5He$t`a`((LP`A)V2EY%X}zLIh+#F|g)C@+rI1bFM60 zw{z~#`kB=h)5ZI!Jq_9&8%hbZ_U_D!C3a?i-78j4Il-PP1ii$#HD4D4w6j35= zLK!L*N*RkpLWci*^uF)+eeb`HeH?qYW36XB&wXF_b)DCFo)p{L_<;B08N-Qls&DMU6g}+Z^knWusR14*0m*?|>+9j2km7)+EHxjg5_nRzo^~){t#%HOG+8oT*{B zZ@2Lv5;=|T9LUUC)4yJuN~O-OTtjQXr|>D*p?P&H;89*Oq$>UX^5bxk1gHba7P0M+ zO72M29P-C2aAbJvE0 z5Uak|dCHyZKq|aAl${28R4bFM?1R9ENJLPbbhb12&rRR8%0+J^9g7?|-rW2=h$j&H zqhvpQ8#uxqV8FybyGrbcUj}~g zPJX@@;{0UZPQ*sU*6j5g;~z(}2aZe*$LpC74n5-A7qwQSehmXD>JwU zNj%0}eAF#0r@SJo8$1!N6Q;`;lMv_U2 z_R-!j%;{<@j2NB-QC5sYr|#*0D^*n z`N7`V4TSV(>GkqC3sbKFcy(TA(Gm-+q78M8Qq{^lqF=Ye$fz}KR_*g70@LK3BWUr$ z$x-E&M*a@WnrIO(GwHdFL^7|Ma2O(mx%H2Z?pUR+o5rB_A#kkfoH+Q7fRn-W8Th)R zZ8BRM7|KJGY76bzT-if1F++PkBHz$F`OU-V*v{0cpFdR_zQ0b<#_}>LW}@hur@50Z zWag&1|M1+R#DIcyhu;l7YV8F3(bgmSgG-;dONP2XxYlXy`c?RRB^heXCSm+X5+R)y zr?y5v?>qeQVFxy0LqiVgQy}bF1C1{CaL+IT6U|<==tr+H$c!6rT7emuK z?4VJ=y)7x30PsOD`SWb$(I7>r^eiSGylOA5hehdrKxLd*@p|4PTE81_XB3aIs_XC z1acg-Xn7sDssx+I=4MCG<6)hEXar`(Lnz#ECvZ(+PAFsCxILKG@|{Pc`|kNCVdG$H zlwgib|IoU0@A}?xKaib(&`8kHaKpqJm;n>Wcp!~N!^&m*6CmDfl!DyPHU2iO!5SmWq9Dy)JM4p#Z@7rj;wQ@ZN!w* ziHV^Voa%B*Ktn!=O!(W+AEFAky0xxJ3ZK$ux@0u@?HzTN4G6ubw|7g>FwTMGU}jXR z&?6u7@#)KJL1lA$M{06fT5%&IQVDdF-8)tNe)OiKtl6s?p_w0U_#s87z&u5Ra^*#G z_WOPiu9}$YlH<{C1;h;10{gwq`uu1b4uiaeykq`W{{a|pj6Ix@dF=mrqp*CiOAp=Ipm=v?fmU<>!6t1)7P(FmcP?(ozkBAFQ@|=fSE)-v{duDMho4{Ox zM%=X?os1x$n+RN0pgDksOD#}=e%e1^E0_+44<3An*5duC{*i|@COqk%Ad8x+?RLUk z!_B!io`()$l=sCW5z^{NZ}8SwTsY-0mL?QPP2_f}k&#g%7+%n0oZ0qP@QdDRb4^B% zxs^=0Hpa2`1Q&quwJ!!JhJXzX;RVc#X$`<&upBtAx^V(@0U8Zfh&V4ZOA>?b+EW6= z!LKE1zWy5I(8PDxyjj@kASbeyx~d!Xwx;_-8VR$y}cKotPo3opDy0xmKpP*pWkqASX z1Y`KI>5-$NqXBhKQuz!dEYXff>VRN?R(+JL`av3Gizeim-iTGLhr^mky`j(Q>L}!7 z5oXk$``u0swlaKVzHkIL3+!E@Cgb3cqALe8Yl(V;W=)SnX3|E@;CkV54-hFgjkrdg zPM091tF`piGUj50zna*4`CZ9Kd9->(aw7vB`#qWYaO~(@80=idUmqcLEVoos_#&7 zfgpv<8|0{*scHvx7mkBfpPL>k53YtC4qCsyK>hPXm`%%`K;fl5^Mwbg_p&@o95D(2 zy!@lJ+uU`@pC)ENttWu(J>T|7CP&&SK$WCUaY07_wymR7;2&^h!UX}*0Gg~D&(6G$ zDi|9bjY1g%ENRZp5?iR6nzJBIpnZTA5RhQBj9jjQ#AApA-N2Hlds=Q}xnrzmJvJr^ z?dDbYrl$Y@yZ{OmQBg;n@isQN_t}w==sW;L#HiYT4FvDV)GnbOz+{m!gqg`$dud^!p@mOMF#d{` zTDYv>%Hh!e={cXk92R#tXl>bRVbS~Li@rGz4Mob}5TY;Gimh!x06&2nkl(kWgOi34 zt%DHYcxG7SRG31Dh|vmDU(ulkZ*XV`rd@6(Nm0!0fQ*Pfc*)Z)uLhyl0d+|yoLb!{ zr@!aq$kH00Fc2q z!rTw!CLqOav6kh9zzOzT`#NrleJeO=g~=+&b-=h)l#@fAE2pINW;~+H{C-m!kPT?& zt6})oHc%YwkGU7u8ix+f%ADz9Ug6fdKZ)$W~V7?K!T30R&C)RB+& z>JVHfSSWB0nM_mP|26OPzqtVF>XA_tcjg$NI1qrfwE+c#IRC_rI&4N^9v(t~i&HWn z*y37K&C8cKP(tL<8(fF4m5}Tn@bYWvZ$Y*6BWSCZdoJCb-GMA&P3dPQe*c!CW38{q z@Ypc9SrN2cF4l-!+RfsUl7tzTRjy60&FcfEWD4?)6!bvw@n4S5KomB#`HUL4awo75 zu%p2U^Q_X&Igj{`v=%HJu=62Kd{Yqw$t8%W07n471G-V?_t5?LuX7*3Xmm8|OVx_M zSA^$I}Ph98aL73ZBWV1<$u#9vaXOfHBkIZqmLBcp@5(LR0U6)4)u8a3BB& zsVOlq8*XqaVmF!uP* z5s(ESGsqlU@CXAqsWyH6B*GAm=%Imtp{8DtM$rdRbPC)z8i3P%2YH4VI(>xcSw-#} zliz}XWvZSeF?=ql$Fv62Kd6^G&K=lXFDRfIL-pIO+?>AY-P^ZdZtsNCaq`!C+qESLQ;NKU;&pt;xp_?*{ht zS1ic-6|TJaQ6)i_<&8#eh`t40E!uyYkZIfMI0JnYc(nTH)zgMLHrx(o%HNvcpG{ao zpi#iFo+i$zRvv}lWY*a?vHT4N4Z%IvFq?5wA2>*GJcW)rl;{ci zKmZ-ewpDY#e}v2e2OT<}!e(oZUS)i?W;m;^>X^*NjlT=ax-)w?JX~GtFghA7I8?SE zC6#*jbT>4R4>LNh>CS0Cgs6?N(w~vcLJqHg(;s|up!crtfJf)!g`8pmiMuvi6oAS69qhKD%%VT5RO20 zMF0Xnd%97n8e)rL6l)Mc93O6%o1K*+4N_yMx*PB$gwA334yt{mt(dThCQSz@BZOua zQnL5&H|yvu0zeYe^vwaG7bhrWd@xIiILjDT!Ykh2z|NimgaYRj21p}AnE@papBf6v zJ34hZ3UN~r5}=Pk?1jz^Er_wI-`xNi<=3ribtbjCw?6&k$*9V-)$PCmADq;Hk})a} zAXhkCOzCm>!D5FBLKXV~n;?iKXc4F~Jv2$v^U;YBdY(g% zI$yv3i4G_F5ZKdj?rQxjz#d%m1g{1U9Hlh)$v*fL02cVuU&jj`qTz-*8G3cRaHj0> zW0#9IHaF)#U&ryM9A_<1wpwk}KzQYx8_8NMyL0CUE)kpYx_^~bF3PtOq$X?Wm~h8M zLwA430*#wJyLSshVA5<>){S<&bbsUoThW_m&u(Ey&rYoz=R5UAA|EndXq^EVU@o)= z1XK>^k-!3y($LmkK##mB>JIWGqA{>?rJGeWpA@EOHN+95H%z2BWXFP_Pv|a%r{3Xg zCkC(wlsnFH)&y{>G<-kY{L6~>1j?r9%%I@l3o$W>bRg^FKpa}L1>_b?g?;}%5S4PI z4^QE5w9|kfAUYsQd$cH(ccb+NRq7lPgyO2H{c+U z6Tf3BiJGtsT7K-iA-hPYL0I16f-X*NwY0(PGo-3GUsZ@f^OI@lg9H9Gh!koB^2|a3 zyrN=YiR_9Vhq+3x1S53CF+KL5rY8M(p=)*u7tf!+nLU)a0v@5E+WtS6z5HW9m@VQK zcI2=7G*l7F6Qz&0)jT}_)$QMXKKo##ne+SSu936E~P&AcX zN!OwKTkc06vU0nglwh);052WaU#&hAqOWaDXoU{J0LHPAueML=ShHwzqTQNU(hl4RJU7sE5i6oO)z`yh2pWB`I?-6mb!EoJ z1Q(p2ybLvlZo1If=Y6=797*8}+~j4D`9`7<-_(R)(~oKj)Hakmz@(b-U^Z!LVnLil z;{g9`EnqKYXf2l7Qx#C^Sr+cFKD#IWE~dqN_}UQ(JFBOCq9uo!bsH=*53@zJ% zFrm`EFs)`;6FU9r9K;wMkNA*>$VJbh7Uw#-^>kDEcu6%%D==+lk=9^!$DsZ8z4Q%; zG=MyXg@izr(SXzsZ5o`$l%34d0PE1G^Zdx{drl9v9<&KunTGAyD+s)hQKV`dJIx8@ z7jSeIxC#OI7uPV$K$8nL;eJpSAY)I`jzGv0gS|VvOq{m4ksc1WX4C?~hHv|&goIMu z2SQ@~^(P8?FzQ}nI3*$nI0P`_&`W18ejgU{=d4w({yDuX3(-<^Ff5`uFUQC0lan@| zDoRZik!aH&Y*ZttM3@i=o*_pFz!Ee_BV+ZRl(+UH(I>23|4JhAf2p)?bgnwyO1D8P zJwRE{!h(|`NzmS2KMoG8aJbm3b_Ow$hcvZzUyRGF_6Cn`&^@O|wOE$`Xs4?>RL8OG?V%MpqFVwWJbeH0BZvyA zf~w2U`ij>%?JeE{mj<-J@pd2{@mFPo&)ALo4S6XLo?T+~Olzt83BnK9f+z2CLH>h7=GzxYMZnn_< z$0vj#l^4-Cid<{IU#odU6KT=}Q4Tu=yB(v{Zdu8FyoH0@pn41nef}hdkOszd|Fu+I zw^nX=)QEz6ivtB!?v3R%S-!$Mb2 zIUZ6{__`0J)BjMRiBk7$2UQqgG@ktY3z;-zDG26Jce&wvqYDR2Qs?A1f#4yA-h>~B z%Aju}Iz;LJgc8zYy{=BI6yg{TLXcwY%a49Ke~krcjItfC!QSeS)W>5gcse%@!g?C< z0l{$v+Eua2ThkZ@6=#oW0{8+ktAyY%&ir&OS_nhE4@EGN6^Mtu#;C1U(xh4BQTN3W zXKq^4Q7ln|*+#qcCosNAKvUx2lE zdr3_?2SY4)rj=o@IEWQvVY9Q(eJg1J8h36#ZQ^aI7eB=XZZ%ESlWTVRj-2rE@p`7p zV6R#EPi7WIg7?5=7gbeK;3a=8N3?~}^2KPO+ZA(YgEb9Iuu$Z877#=}LFnoY#W^t? z*@`#e%9YxI3AFxfuCHku22%kpEnCSm!0kGcv+Nt&9i>U#IrLMCj0ToA{{Ayyu))I% z3fg*?Xe4*OViCia0c&!zo}tGP<=|>=e*SYtw6zcY#w93{;^JXRRPbnN4M65>T4wVQ z7L*c=dlO}bi(vrz zJh8A;($FZ!cp9A4R=K`_BO&8IazjQ=?>rtA@>o##!KP|Uu(h`CL-p$75}%fanVtn3 z9xChT^fWf+Bb!7K=OhxIW0Dl9MXDFn72##ALyr*f-22;R!nbq5i>yQv?A!7L!2OQ!*tuh^3eFw2GzXbj!eRNMn(&2SM(Q z4TnU$8+Q!~PlWP+TvP#u!`B_6=T~DV89hEc;vV#Qur6T7p+gEI*@J-`JBu9NMY=NH zcPURMb)hsuasRidLK6eLZV>7kz8;?qeSSe0%A6emMMr;c%d9M;sT^@=JfG zvLAHRfq^$zj>to>Jg`Y59Ei|RQ-cW|u&9fD-dFMH(W&WuD2?iWY$cJlp2=sa8HL<} z^-LzhUAY}PgG50{vX}j^WF8636|a9a>4^VCtVtLC5D~3`rX9)e%n5W1aE5oa992V1 z1|;$a5lv~F-QNB1?#3Y79j}${-e@>LyaDbXvPifOpqqg~8l?(`)qJ2nyQ8NIoVIPE z>t5$#!dsE@5#cyNQjN(JZl!6m+CgBQn8tX1xaIj@FtYTy6*_nbf@wok$c+Bd`Vhwe zqdl}!aJ%XN=U^oJ5ZEE_l|uURbto;*H%-6RQ~tl$i=C=TEJd0?IdL=o!*lFIO)yCe z*hX~xAHrf+zRV>fY;k9hTfTj(gn5M)X*p) zRe!aAknKD!WU;-Irna`;o`JY|%;=G!M}kRY>bYAo^qxPb>g z)>$Y#KY$z#9v~Rz(DwQ@ltM_w>J|LKamAaXBi}zTK#+s%uV%Mg%v0K2Zcj3f>^za>-U zI{2RdK|%St4Pkf&OrJ!bt&WbOC5glQAHa>HQm@lYBf!j>d-~(rdJco8Hpr0+ZDQ%4N~+w&2R3_oo~mC z-3Av`5h|0&NX;DKV~s=|d=Zo>)6;(6)otWc?s%DX=Z?i;fp801kd#`FC*P7C2Biq= zwJ0wyGc>ehiX-QjAlNV})o&`UhF?K zVh)8h#Qne+d4+`X9yoSh_`ELLG2zR)Wx>oEaT`Ryb@o#yTn$7ZTpKPsMeMzW+59PU zfXZ_{i}PYtcIZXHLkXP}tRV1Hjf}`8Zwc@*I(l%Xsfyj9@%`Jktpk>&uTE=rp2Sgy zuA_xpSc}EP7C0G|5A77oxr_#yV+iX~)!K9n#)d1g*0L)eI*o2rq0$?#!CmnuK z-Jn}XXQHI9efktj952+B_+!%7B~Dcc*iEX`G_M&1CEx=&7sK**9nP{kh&ebQ1{4;4 zM_G3NS}rd9dZl}dD3~%C7J~qQP?UTxgg@9xKp$Yq0Up7&b>{<$4JHE8DTzxt$ahe! zxb{PqhTggyPR`4_H%8~D1lV5A=PZr9yOXrfe2tMXv$xY(e%iiY`fFO5Ew%F*#tDXf zdW-vwWBV~|nGkF?6wm=Pg&=Nm{2@#;(S?rwXoc^zXBA)JS`hQ@&^AQ$k5!7%`v z53Ayp-~2>nNCNl39zfdxnU**&u9B3V1yd-rji5gTvU~&&l#`RRcmFa8l0X4E6PV-Z z03C**p@a}gla|In61a^{Iqn`n6)67B(2fCO!JK;$Cx#rJS$0y5GT{pd0y>e(fhi{! zZGX>&#hEco8!nz1x2$qwW6gK$Xhxe8GNc}?eAxIB+G?QphDU*6kw}WoNQ%IF1cM5W z_XUy0mlPlJj`P0Z^ZE}kiWq%hK0tE zzShAES;0v(p3$y*;~4nz<42KK|5{_eBJx>C`x~Iv=mBF0VUe=*L`e;Jkc7Su#&8y- zLGmshQcWC&zYr(~4DC=K8>o?%7Od`kuO}mx1ki!UzqL<$nN44(TC5@E6lFG=&M2C>wq`RifvNkO3g0By(y@9voYeBM`3=j!T`l9QKy zdg+^@QZa+g2iVN7Zm!5&dQ%cp>Oen)$2PyAx;6P<*EKZUFeLu+X#Bp)}0tRj@tXn7aI$UFb_Q6rOyH0 z5B#?U#O(}HD;L%~#!T!Jz^XlKnqfhJWmt&ByAuofY)qysx@XyBEzwmB*d4^Z(p#MU zG#;`ze+qyBKI)A($I^R*g%g+2OIW@D8A2w2C;1RmFp_`lYyQh#NfFRxh7F*pnCu)FcQy}kyuMLdy!`$YU6pLo{MDu8}@Qm z{Cxu;Ja_{D!GFUGsR8&I+PuWTRpJ7Ojmf+ofDcG4C;>3D;J@Dh=osDrOY+}WfGQqu zkO)e~f35(XOeKhGTUuJ4KVR{m?GQ$6hcMabE@b#H_ajsO1_okyIK>4^1MjT3e!XEN zsk~RQ2|tNuFF35wt`a98NP-~iAgKbt4&s~b`fKRX^Ozem6OZA(I9hAS5aW!q2zU#{ zH`r-l4?RTB6g72s;26M(l@!L_)5LR3MA83wWCZywEYUvV2Et4Zv@M(gIDnwx6B%dd zJxyF|BB9G_PN~2>!{P-5zg_Y&qARLxaYfS7=UO05#785&mZ1v>3!6w@#+Tq&qrrKJ zp>=6R?gxw*GWE`#&Iz-ODE-&j=3=*&qm(Cw@xh*w!f!9Oww7bWSLWGThQfexS5yc86o$ciI301P1M_8=k{ z{WGBz!9PA7^mKsd>A?83e$4=vHijo@X~(w6(6>!9;(z*`ZZB*rjENaeSYu<96-gyl zm!CR%TI86QmEDUDZ?w-AwsEP2@zYJbNa@wjoK-%3QeM6kp*U$UbKrXLx=KHX^=u3|<)G_8dv zlALC~OoAbH+cHD_nm(2oed(Q%0>lL=yWqyr4oswM6_%sDTBVUG8*MRp;G*o$v69&M zc&noLMlO{w{&Vi)j5Ya3b3S*>PfLVHouSQrc(`D$`IO4ZU_(SN0n^zqCL!YeJOrC> zY{}p1{GUIf1w@e98kn*XnmGN5oFY9IpcsycJJ>eJIFGwApRTX0zI*G|v!0$sG&acE z_tnZbGLRfOuwfSe+>zov3(pEy=FEEgYo^jTAb#W6$9j)TPWC)-AYz({2pf~_>3R_w zv+P3Ovo9`*x~%u_?**`Q%#48uVd-yR{j^Cn!f=GDOr?%s@-1L>U|C#8iPaevBKAOI zRIiuq0_U2g2pif*p)Q?GKgK?py2OYRH$LpD2jCop5}Y`?Cc7|S!tJGyXzWHf**s{f zSw>;>JNEagyY}U|jQp1FX}Hg|3uK=QG0LVUb1O(Bwz=*4dNxNHh!blt35hLsAO?e} z`W({ah}*SG_F2p7%l5|7JJ)@Qw{l$Q4H^l*B6O?@YY)wUNFCy=ZB+s;C!!N_`qE)9 z>uXaq9=436($;$k6?pK9G@dh7$L_ z)dQc4Rt*~;N+juf$A9b#pj*&6qb+zdWQWsOXtKt+xRi#pU2&gf=$sW+FY*W00sApC z>nPTTd0@lWpJ@Cux9HeoLmNv@7(_&!#9>+SS54CX_1jwEW?MZ z^(9V}h_;r!EZVY>x|-EHyf@A+Me4KJjUUVu$*DKjLnG@b($bq)>!!N87EMPQ2PVjr zKcB}63JVq-%C0ZZlN&y3YFHjR^}|m~CR|tDWcu;#4b!RXCp%*MWW?&v*FBMzrgJW* zu;r)yIpwpOJZ*kY{&-`4=>0odYcHk9{If9M8vQK@8Lu_p4 zsnPx;=JI2p#M@=QkdSdQ-_~8}5CNgw79v9Yrn;CC2 zGfSO0p_8V#Eo0i;7ESHKaz50wGj(0bGZQ7rc{NTV&#QV;7fK3a=eu4G7$W*k_yyKE zo5=T_@nPnntxJolb(^=mZL^?ogjK5=E*ENpq0yHmoN+xf|WJmS>M zsTLgrOI9h@rarlZc!%2-^M`B`Zpn#mx6`wvW$21er@fbLYKr02lE}(&KW?yDEYR)o zx$M1C24F03vkZ!^be!l3TT0~E&&F|vUk-@dX+++1bkH$O_lpv*=1;%S8$m`&M`wc` zt~NMrYWk4Hpl881X=Z=_m3x7|C$3%Ju&|Xy2UdKS8v0@-sXkV(&$m&dbvA5J|2%G( zlo<4G{Tp z`=3cu|Qm1LRLf}MuXL2EP9!t1@i zH^s&kHz`Pe|I^q#I(C08*6^Z=N=ffHnZkA3jj8Rt=q)}WVV2^LL7pvrC-_-qB4etx zrfS~W`St#&5;QE2Uph`4b>l9Le=^RUv+C5~xzZV=O>wz%_gH9>!hk+2<;x;D^wwP! z%B|ID)o(w{P3GFnT7P62vt}!i&a>KhNw(qbm)@2)gF00#-qBxscAw@*6LWF?+40bN zGR^Cy0+}+FnE1?g%cF%tn4sePQE%@q#}@B;s_Y)z_a% zZofv)y|vj}71Xf~c}EAqrmSyX+LOOJ?;hAzx@kwyDBapHWZx7DZFZxj(td zAZgrhWl%_9#*ZyLS5T0TR(~+ix*-_5v2-EnN&hgx_1&GXwUU9z_H})(@cgWs7zp(8 z`ifX07@uSy`iXS7j5NrlyRuE_;O&_9<0Cg5xWQ z@DT9DJWBFjp7D0_8>wZ{oU>WWw@F>T$^BxPb(>JGFW3bR%K-#Cdm5Ad4J|>HM9%59 z_ZvD1C=0jF5qmi7u?4qkR_5p1rnlQGyuvx}nJ7Hy8+X$QZ9Wm!x7#jpk?Lk4$qi4) z_!D=*;X^(6ZTZq!&Cg4ZDb6WZx+Xs|qqoVxmhX>+k? zh`FRoenDc)X+`?zgzA2fKRT|Do5kx~cvwr{#EYLSqGFGSYMKfPb{5QxwK457-u;L< zo-Wzw;vB8|gehhz9VpI}Oo}P31$XG39l7}M(CuVCPFlgs8O9^cqBzRLVNH<*VwYUqf_F}(hnxYXIOYl z36Pgpz6ny?k{VMQbo8}_%z=v=Wq6%AC6*FEgS!{`d%5lfoeoS*`~Kx%vt~-V5WX>y z8ya-n=}xFwd%OO$rp})o-kT3_H9DC^-(ehNCo;Pb73o_~A{g^LR~J+<*r&4h7Gyz0k3ZccuiW*OwRpL+d$yvPoZ?3*zHK_8MVf8( z^@i8PEqFy=vJ>Uh{S;S!Ew0~NmtTyk^A;2?;~{@oe%kaxlWvCO`3J5d7e)($SI17g zeI$Hn=G(3v%js`_jFjiB%gzy%cy(m-P%mBo^f@_#0~Qvr=MaR1se&Ia8;do5-8dZ- zn(-sAUYIA|c-`84De()H+cvWmare(BzBsvuiEG?%{zA-+1@8xzITq~}?MFmL-72N7 z@z8!GN_uSa8ysT{tJk@A$Cb3GLZ$XMv!875??F@4I?x^2ElD zxgPJ8UqXG9&5QQyr0+gxW3)Xo)*`3zQ?Y)of{kobx!3vu0rjYx@=IygRl!N_sQaOw zBOUo5WJ%I1e|7Fb^4g)LIqpYq8K}~!2^rEjWxZA#RYb$Dcz5B22D9b@OIf+jWOUT} z0arN4qjN*lR`G|J_@Od~5)~fgmX?>UdSZkPQo0YLq0i;#8e*0qw7 z%L13#^TPL-G<%uu()TpVlkh*%kgM=MG$I)w1dj8-UoLcyu_l_ zT*NG%3m+K>?7(j(-Z<;pwOt`0j~&)~+p#c)*EBU1l$XQP@I5sFNDy#L^*0jSQD8@5 zw8yD$Y)jd+=$h-(bHFD-4?jOFlvbfo$0X8PKyn2D z_Wa^f);;^Qt4mW|y#sO|anAOU2w!`o_`{z*Wi$~4oowIhrUs6ou kN;~Tlodn{f!j$&TucT74njfJLMj~xD*r8uU+kg810e9C+=Kufz literal 0 HcmV?d00001 diff --git a/Legacy/Aria/ArNetworking/doxygen.conf b/Legacy/Aria/ArNetworking/doxygen.conf new file mode 100644 index 0000000..8aa7f57 --- /dev/null +++ b/Legacy/Aria/ArNetworking/doxygen.conf @@ -0,0 +1,1304 @@ +# Doxyfile 1.5.3 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file that +# follow. The default is UTF-8 which is also the encoding used for all text before +# the first occurrence of this tag. Doxygen uses libiconv (or the iconv built into +# libc) for the transcoding. See http://www.gnu.org/software/libiconv for the list of +# possible encodings. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = ArNetworking + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = 2.8.0 + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = docs/ + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Finnish, French, German, Greek, Hungarian, +# Italian, Japanese, Japanese-en (Japanese with English messages), Korean, +# Korean-en, Lithuanian, Norwegian, Polish, Portuguese, Romanian, Russian, +# Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = NO + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like regular Qt-style comments +# (thus requiring an explicit @brief command for a brief description.) + +JAVADOC_AUTOBRIEF = YES + +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will +# interpret the first line (until the first dot) of a Qt-style +# comment as the brief description. If set to NO, the comments +# will behave just like regular Qt-style comments (thus requiring +# an explicit \brief command for a brief description.) + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the DETAILS_AT_TOP tag is set to YES then Doxygen +# will output the detailed description near the top, like JavaDoc. +# If set to NO, the detailed description appears after the member +# documentation. + +DETAILS_AT_TOP = YES + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 8 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = "javanote=

Java Wrapper Library: " \ + "pynote=

Python Wrapper Library: " \ + "swignote=

Java and Python Wrappers: " \ + "swigomit=

Java and Python Wrappers: Not available in Java or Python wrapper libraries. " \ + "notwindows=@note Not available on Windows " \ + "windowsonly=@note Available on Windows only " \ + "linuxonly=@note Available on Linux only " + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for Java. +# For instance, namespaces will be presented as packages, qualified scopes +# will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to +# include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. + +CPP_CLI_SUPPORT = NO + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = YES + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be extracted +# and appear in the documentation as a namespace called 'anonymous_namespace{file}', +# where file will be replaced with the base name of the file that contains the anonymous +# namespace. By default anonymous namespace are hidden. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = YES + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = YES + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = NO + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = NO + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = NO + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# in the documentation. The default is NO. + +SHOW_DIRECTORIES = NO + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from the +# version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = YES + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be abled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text " + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = src/ \ + include/ \ + examples/ \ + docs/options/all_options.dox + +# This tag can be used to specify the character encoding of the source files that +# doxygen parses. Internally doxygen uses the UTF-8 encoding, which is also the default +# input encoding. Doxygen uses libiconv (or the iconv built into libc) for the transcoding. +# See http://www.gnu.org/software/libiconv for the list of possible encodings. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx +# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py + +FILE_PATTERNS = *.cpp \ + *.h + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = NO + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or +# directories that are symbolic links (a Unix filesystem feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = proprietary* + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the output. +# The symbol name can be a fully qualified name, a word, or if the wildcard * is used, +# a substring. Examples: ANamespace, AClass, AClass::ANamespace, ANamespace::*Test + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = examples/ docs/options/ + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = *.cpp *_options + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = docs/figures + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER +# is applied to all files. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. If you have enabled CALL_GRAPH or CALLER_GRAPH +# then you must also enable this option. If you don't then doxygen will produce +# a warning and turn it on anyway + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES (the default) +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = YES + +# If the REFERENCES_RELATION tag is set to YES (the default) +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = YES + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. Otherwise they will link to the documentstion. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = NO + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = ./ + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. For this to work a browser that supports +# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox +# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). + +HTML_DYNAMIC_SECTIONS = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 4 + +# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be +# generated containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, +# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are +# probably better off using the HTML help feature. + +GENERATE_TREEVIEW = YES + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = letter + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = NO + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = YES + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = YES + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = YES + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = YES + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = AREXPORT= + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse +# the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = ../docs/Aria.tag=../../docs + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = docs/ArNetworking.tag + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option is superseded by the HAVE_DOT option below. This is only a +# fallback. It is recommended to install and use dot, since it yields more +# powerful graphs. + +CLASS_DIAGRAMS = YES + +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see http://www.mcternan.me.uk/mscgen/) to +# produce the chart and insert it in the documentation. The MSCGEN_PATH tag allows you to +# specify the directory where the mscgen tool resides. If left empty the tool is assumed to +# be found in the default search path. + +MSCGEN_PATH = + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = NO + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = NO + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = NO + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = NO + +# If the CALL_GRAPH, SOURCE_BROWSER and HAVE_DOT tags are set to YES then doxygen will +# generate a call dependency graph for every global function or class method. +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable call graphs for selected +# functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the CALLER_GRAPH, SOURCE_BROWSER and HAVE_DOT tags are set to YES then doxygen will +# generate a caller dependency graph for every global function or class method. +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable caller graphs for selected +# functions only using the \callergraph command. + +CALLER_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = NO + +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = NO + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MAX_DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen if the number +# of direct children of the root node in a graph is already larger than +# MAX_DOT_GRAPH_NOTES then the graph will not be shown at all. Also note +# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. + +DOT_GRAPH_MAX_NODES = 50 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, which results in a white background. +# Warning: Depending on the platform used, enabling this option may lead to +# badly anti-aliased labels on the edges of a graph (i.e. they become hard to +# read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- + +# The SEARCHENGINE tag specifies whether or not a search engine should be +# used. If set to NO the values of all tags below this one will be ignored. + +SEARCHENGINE = NO diff --git a/Legacy/Aria/ArNetworking/doxygen.conf.in b/Legacy/Aria/ArNetworking/doxygen.conf.in new file mode 100644 index 0000000..de5a767 --- /dev/null +++ b/Legacy/Aria/ArNetworking/doxygen.conf.in @@ -0,0 +1,1304 @@ +# Doxyfile 1.5.3 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file that +# follow. The default is UTF-8 which is also the encoding used for all text before +# the first occurrence of this tag. Doxygen uses libiconv (or the iconv built into +# libc) for the transcoding. See http://www.gnu.org/software/libiconv for the list of +# possible encodings. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = ArNetworking + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = @VERSION@ + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = docs/ + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Finnish, French, German, Greek, Hungarian, +# Italian, Japanese, Japanese-en (Japanese with English messages), Korean, +# Korean-en, Lithuanian, Norwegian, Polish, Portuguese, Romanian, Russian, +# Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = NO + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like regular Qt-style comments +# (thus requiring an explicit @brief command for a brief description.) + +JAVADOC_AUTOBRIEF = YES + +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will +# interpret the first line (until the first dot) of a Qt-style +# comment as the brief description. If set to NO, the comments +# will behave just like regular Qt-style comments (thus requiring +# an explicit \brief command for a brief description.) + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the DETAILS_AT_TOP tag is set to YES then Doxygen +# will output the detailed description near the top, like JavaDoc. +# If set to NO, the detailed description appears after the member +# documentation. + +DETAILS_AT_TOP = YES + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 8 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = "javanote=

Java Wrapper Library: " \ + "pynote=

Python Wrapper Library: " \ + "swignote=

Java and Python Wrappers: " \ + "swigomit=

Java and Python Wrappers: Not available in Java or Python wrapper libraries. " \ + "notwindows=@note Not available on Windows " \ + "windowsonly=@note Available on Windows only " \ + "linuxonly=@note Available on Linux only " + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for Java. +# For instance, namespaces will be presented as packages, qualified scopes +# will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to +# include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. + +CPP_CLI_SUPPORT = NO + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = YES + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be extracted +# and appear in the documentation as a namespace called 'anonymous_namespace{file}', +# where file will be replaced with the base name of the file that contains the anonymous +# namespace. By default anonymous namespace are hidden. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = YES + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = YES + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = NO + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = NO + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = NO + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# in the documentation. The default is NO. + +SHOW_DIRECTORIES = NO + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from the +# version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = YES + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be abled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text " + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = src/ \ + include/ \ + examples/ \ + docs/options/all_options.dox + +# This tag can be used to specify the character encoding of the source files that +# doxygen parses. Internally doxygen uses the UTF-8 encoding, which is also the default +# input encoding. Doxygen uses libiconv (or the iconv built into libc) for the transcoding. +# See http://www.gnu.org/software/libiconv for the list of possible encodings. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx +# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py + +FILE_PATTERNS = *.cpp \ + *.h + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = NO + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or +# directories that are symbolic links (a Unix filesystem feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = proprietary* + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the output. +# The symbol name can be a fully qualified name, a word, or if the wildcard * is used, +# a substring. Examples: ANamespace, AClass, AClass::ANamespace, ANamespace::*Test + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = examples/ docs/options/ + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = *.cpp *_options + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = docs/figures + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER +# is applied to all files. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. If you have enabled CALL_GRAPH or CALLER_GRAPH +# then you must also enable this option. If you don't then doxygen will produce +# a warning and turn it on anyway + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES (the default) +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = YES + +# If the REFERENCES_RELATION tag is set to YES (the default) +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = YES + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. Otherwise they will link to the documentstion. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = NO + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = ./ + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. For this to work a browser that supports +# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox +# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). + +HTML_DYNAMIC_SECTIONS = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 4 + +# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be +# generated containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, +# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are +# probably better off using the HTML help feature. + +GENERATE_TREEVIEW = YES + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = letter + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = NO + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = YES + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = YES + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = YES + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = YES + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = AREXPORT= + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse +# the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = ../docs/Aria.tag=../../docs + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = docs/ArNetworking.tag + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option is superseded by the HAVE_DOT option below. This is only a +# fallback. It is recommended to install and use dot, since it yields more +# powerful graphs. + +CLASS_DIAGRAMS = YES + +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see http://www.mcternan.me.uk/mscgen/) to +# produce the chart and insert it in the documentation. The MSCGEN_PATH tag allows you to +# specify the directory where the mscgen tool resides. If left empty the tool is assumed to +# be found in the default search path. + +MSCGEN_PATH = + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = NO + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = NO + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = NO + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = NO + +# If the CALL_GRAPH, SOURCE_BROWSER and HAVE_DOT tags are set to YES then doxygen will +# generate a call dependency graph for every global function or class method. +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable call graphs for selected +# functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the CALLER_GRAPH, SOURCE_BROWSER and HAVE_DOT tags are set to YES then doxygen will +# generate a caller dependency graph for every global function or class method. +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable caller graphs for selected +# functions only using the \callergraph command. + +CALLER_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = NO + +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = NO + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MAX_DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen if the number +# of direct children of the root node in a graph is already larger than +# MAX_DOT_GRAPH_NOTES then the graph will not be shown at all. Also note +# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. + +DOT_GRAPH_MAX_NODES = 50 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, which results in a white background. +# Warning: Depending on the platform used, enabling this option may lead to +# badly anti-aliased labels on the edges of a graph (i.e. they become hard to +# read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- + +# The SEARCHENGINE tag specifies whether or not a search engine should be +# used. If set to NO the values of all tags below this one will be ignored. + +SEARCHENGINE = NO diff --git a/Legacy/Aria/ArNetworking/examples/ArNetworking_Examples-vc2003.sln b/Legacy/Aria/ArNetworking/examples/ArNetworking_Examples-vc2003.sln new file mode 100644 index 0000000..e31b6c2 --- /dev/null +++ b/Legacy/Aria/ArNetworking/examples/ArNetworking_Examples-vc2003.sln @@ -0,0 +1,87 @@ +Microsoft Visual Studio Solution File, Format Version 8.00 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "clientDemoStatic", "clientDemoStatic-vc2003.vcproj", "{0A8A179D-832B-44B2-829A-AB6E61BFF46E}" + ProjectSection(ProjectDependencies) = postProject + {527BBF7C-631F-486B-8E4F-EA594299A71A} = {527BBF7C-631F-486B-8E4F-EA594299A71A} + {1D08AFC4-1036-425C-B381-6FE522207D47} = {1D08AFC4-1036-425C-B381-6FE522207D47} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ArNetworkingDLL", "..\src\ArNetworkingDLL-vc2003.vcproj", "{95FF1CC1-5006-4DEE-99D9-0B6C418C9689}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ArNetworkingStatic", "..\src\ArNetworkingStatic-vc2003.vcproj", "{1D08AFC4-1036-425C-B381-6FE522207D47}" + ProjectSection(ProjectDependencies) = postProject + {527BBF7C-631F-486B-8E4F-EA594299A71A} = {527BBF7C-631F-486B-8E4F-EA594299A71A} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "clientDemo", "clientDemo-vc2003.vcproj", "{806E0C42-BE8A-4857-A97B-068FD56C27A1}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + {95FF1CC1-5006-4DEE-99D9-0B6C418C9689} = {95FF1CC1-5006-4DEE-99D9-0B6C418C9689} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "serverDemo", "serverDemo-vc2003.vcproj", "{7AEA7E4D-0984-4A16-8A3F-AF36B1A27836}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + {95FF1CC1-5006-4DEE-99D9-0B6C418C9689} = {95FF1CC1-5006-4DEE-99D9-0B6C418C9689} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "serverDemoStatic", "serverDemoStatic-vc2003.vcproj", "{31A8793E-E70A-4C52-B470-971BAF9DE5E0}" + ProjectSection(ProjectDependencies) = postProject + {527BBF7C-631F-486B-8E4F-EA594299A71A} = {527BBF7C-631F-486B-8E4F-EA594299A71A} + {1D08AFC4-1036-425C-B381-6FE522207D47} = {1D08AFC4-1036-425C-B381-6FE522207D47} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AriaDLL", "..\..\src\AriaDLL-vc2003.vcproj", "{606257AE-E882-4C66-84C0-72331642D09F}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AriaStatic", "..\..\src\AriaStatic-vc2003.vcproj", "{527BBF7C-631F-486B-8E4F-EA594299A71A}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfiguration) = preSolution + Debug = Debug + Release = Release + EndGlobalSection + GlobalSection(ProjectConfiguration) = postSolution + {0A8A179D-832B-44B2-829A-AB6E61BFF46E}.Debug.ActiveCfg = Debug|Win32 + {0A8A179D-832B-44B2-829A-AB6E61BFF46E}.Debug.Build.0 = Debug|Win32 + {0A8A179D-832B-44B2-829A-AB6E61BFF46E}.Release.ActiveCfg = Release|Win32 + {0A8A179D-832B-44B2-829A-AB6E61BFF46E}.Release.Build.0 = Release|Win32 + {95FF1CC1-5006-4DEE-99D9-0B6C418C9689}.Debug.ActiveCfg = Debug|Win32 + {95FF1CC1-5006-4DEE-99D9-0B6C418C9689}.Debug.Build.0 = Debug|Win32 + {95FF1CC1-5006-4DEE-99D9-0B6C418C9689}.Release.ActiveCfg = Release|Win32 + {95FF1CC1-5006-4DEE-99D9-0B6C418C9689}.Release.Build.0 = Release|Win32 + {1D08AFC4-1036-425C-B381-6FE522207D47}.Debug.ActiveCfg = Debug|Win32 + {1D08AFC4-1036-425C-B381-6FE522207D47}.Debug.Build.0 = Debug|Win32 + {1D08AFC4-1036-425C-B381-6FE522207D47}.Release.ActiveCfg = Release|Win32 + {1D08AFC4-1036-425C-B381-6FE522207D47}.Release.Build.0 = Release|Win32 + {806E0C42-BE8A-4857-A97B-068FD56C27A1}.Debug.ActiveCfg = Debug|Win32 + {806E0C42-BE8A-4857-A97B-068FD56C27A1}.Debug.Build.0 = Debug|Win32 + {806E0C42-BE8A-4857-A97B-068FD56C27A1}.Release.ActiveCfg = Release|Win32 + {806E0C42-BE8A-4857-A97B-068FD56C27A1}.Release.Build.0 = Release|Win32 + {7AEA7E4D-0984-4A16-8A3F-AF36B1A27836}.Debug.ActiveCfg = Debug|Win32 + {7AEA7E4D-0984-4A16-8A3F-AF36B1A27836}.Debug.Build.0 = Debug|Win32 + {7AEA7E4D-0984-4A16-8A3F-AF36B1A27836}.Release.ActiveCfg = Release|Win32 + {7AEA7E4D-0984-4A16-8A3F-AF36B1A27836}.Release.Build.0 = Release|Win32 + {31A8793E-E70A-4C52-B470-971BAF9DE5E0}.Debug.ActiveCfg = Debug|Win32 + {31A8793E-E70A-4C52-B470-971BAF9DE5E0}.Debug.Build.0 = Debug|Win32 + {31A8793E-E70A-4C52-B470-971BAF9DE5E0}.Release.ActiveCfg = Release|Win32 + {31A8793E-E70A-4C52-B470-971BAF9DE5E0}.Release.Build.0 = Release|Win32 + {606257AE-E882-4C66-84C0-72331642D09F}.Debug.ActiveCfg = Debug|Win32 + {606257AE-E882-4C66-84C0-72331642D09F}.Debug.Build.0 = Debug|Win32 + {606257AE-E882-4C66-84C0-72331642D09F}.Release.ActiveCfg = Release|Win32 + {606257AE-E882-4C66-84C0-72331642D09F}.Release.Build.0 = Release|Win32 + {527BBF7C-631F-486B-8E4F-EA594299A71A}.Debug.ActiveCfg = Debug|Win32 + {527BBF7C-631F-486B-8E4F-EA594299A71A}.Debug.Build.0 = Debug|Win32 + {527BBF7C-631F-486B-8E4F-EA594299A71A}.Release.ActiveCfg = Release|Win32 + {527BBF7C-631F-486B-8E4F-EA594299A71A}.Release.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + EndGlobalSection + GlobalSection(ExtensibilityAddIns) = postSolution + EndGlobalSection +EndGlobal diff --git a/Legacy/Aria/ArNetworking/examples/ArNetworking_Examples-vc2008.sln b/Legacy/Aria/ArNetworking/examples/ArNetworking_Examples-vc2008.sln new file mode 100644 index 0000000..a83f152 --- /dev/null +++ b/Legacy/Aria/ArNetworking/examples/ArNetworking_Examples-vc2008.sln @@ -0,0 +1,79 @@ +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual C++ Express 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "clientDemoStatic", "clientDemoStatic-vc2008.vcproj", "{0A8A179D-832B-44B2-829A-AB6E61BFF46E}" + ProjectSection(ProjectDependencies) = postProject + {527BBF7C-631F-486B-8E4F-EA594299A71A} = {527BBF7C-631F-486B-8E4F-EA594299A71A} + {5AD87287-2610-453A-A986-A4CDCCC24C89} = {5AD87287-2610-453A-A986-A4CDCCC24C89} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ArNetworkingDLL", "..\src\ArNetworkingDLL-vc2008.vcproj", "{783BA2AB-07CE-43AD-8FC2-FFD9F19DF575}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ArNetworkingStatic", "..\src\ArNetworkingStatic-vc2008.vcproj", "{5AD87287-2610-453A-A986-A4CDCCC24C89}" + ProjectSection(ProjectDependencies) = postProject + {527BBF7C-631F-486B-8E4F-EA594299A71A} = {527BBF7C-631F-486B-8E4F-EA594299A71A} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "clientDemo", "clientDemo-vc2008.vcproj", "{806E0C42-BE8A-4857-A97B-068FD56C27A1}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + {783BA2AB-07CE-43AD-8FC2-FFD9F19DF575} = {783BA2AB-07CE-43AD-8FC2-FFD9F19DF575} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "serverDemoStatic", "serverDemoStatic-vc2008.vcproj", "{EEF9FE4C-34C4-4C76-94C4-D11930C88DE1}" + ProjectSection(ProjectDependencies) = postProject + {527BBF7C-631F-486B-8E4F-EA594299A71A} = {527BBF7C-631F-486B-8E4F-EA594299A71A} + {5AD87287-2610-453A-A986-A4CDCCC24C89} = {5AD87287-2610-453A-A986-A4CDCCC24C89} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AriaDLL", "..\..\src\AriaDLL-vc2008.vcproj", "{606257AE-E882-4C66-84C0-72331642D09F}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AriaStatic", "..\..\src\AriaStatic-vc2008.vcproj", "{527BBF7C-631F-486B-8E4F-EA594299A71A}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "serverDemo", "serverDemo-vc2008.vcproj", "{B9C37E51-E357-4019-B4B5-71C42E1FCD11}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {0A8A179D-832B-44B2-829A-AB6E61BFF46E}.Debug|Win32.ActiveCfg = Debug|Win32 + {0A8A179D-832B-44B2-829A-AB6E61BFF46E}.Debug|Win32.Build.0 = Debug|Win32 + {0A8A179D-832B-44B2-829A-AB6E61BFF46E}.Release|Win32.ActiveCfg = Release|Win32 + {0A8A179D-832B-44B2-829A-AB6E61BFF46E}.Release|Win32.Build.0 = Release|Win32 + {783BA2AB-07CE-43AD-8FC2-FFD9F19DF575}.Debug|Win32.ActiveCfg = Debug|Win32 + {783BA2AB-07CE-43AD-8FC2-FFD9F19DF575}.Debug|Win32.Build.0 = Debug|Win32 + {783BA2AB-07CE-43AD-8FC2-FFD9F19DF575}.Release|Win32.ActiveCfg = Release|Win32 + {783BA2AB-07CE-43AD-8FC2-FFD9F19DF575}.Release|Win32.Build.0 = Release|Win32 + {5AD87287-2610-453A-A986-A4CDCCC24C89}.Debug|Win32.ActiveCfg = Debug|Win32 + {5AD87287-2610-453A-A986-A4CDCCC24C89}.Debug|Win32.Build.0 = Debug|Win32 + {5AD87287-2610-453A-A986-A4CDCCC24C89}.Release|Win32.ActiveCfg = Release|Win32 + {5AD87287-2610-453A-A986-A4CDCCC24C89}.Release|Win32.Build.0 = Release|Win32 + {806E0C42-BE8A-4857-A97B-068FD56C27A1}.Debug|Win32.ActiveCfg = Debug|Win32 + {806E0C42-BE8A-4857-A97B-068FD56C27A1}.Debug|Win32.Build.0 = Debug|Win32 + {806E0C42-BE8A-4857-A97B-068FD56C27A1}.Release|Win32.ActiveCfg = Release|Win32 + {806E0C42-BE8A-4857-A97B-068FD56C27A1}.Release|Win32.Build.0 = Release|Win32 + {EEF9FE4C-34C4-4C76-94C4-D11930C88DE1}.Debug|Win32.ActiveCfg = Debug|Win32 + {EEF9FE4C-34C4-4C76-94C4-D11930C88DE1}.Debug|Win32.Build.0 = Debug|Win32 + {EEF9FE4C-34C4-4C76-94C4-D11930C88DE1}.Release|Win32.ActiveCfg = Release|Win32 + {EEF9FE4C-34C4-4C76-94C4-D11930C88DE1}.Release|Win32.Build.0 = Release|Win32 + {606257AE-E882-4C66-84C0-72331642D09F}.Debug|Win32.ActiveCfg = Debug|Win32 + {606257AE-E882-4C66-84C0-72331642D09F}.Debug|Win32.Build.0 = Debug|Win32 + {606257AE-E882-4C66-84C0-72331642D09F}.Release|Win32.ActiveCfg = Release|Win32 + {606257AE-E882-4C66-84C0-72331642D09F}.Release|Win32.Build.0 = Release|Win32 + {527BBF7C-631F-486B-8E4F-EA594299A71A}.Debug|Win32.ActiveCfg = Debug|Win32 + {527BBF7C-631F-486B-8E4F-EA594299A71A}.Debug|Win32.Build.0 = Debug|Win32 + {527BBF7C-631F-486B-8E4F-EA594299A71A}.Release|Win32.ActiveCfg = Release|Win32 + {527BBF7C-631F-486B-8E4F-EA594299A71A}.Release|Win32.Build.0 = Release|Win32 + {B9C37E51-E357-4019-B4B5-71C42E1FCD11}.Debug|Win32.ActiveCfg = Debug|Win32 + {B9C37E51-E357-4019-B4B5-71C42E1FCD11}.Debug|Win32.Build.0 = Debug|Win32 + {B9C37E51-E357-4019-B4B5-71C42E1FCD11}.Release|Win32.ActiveCfg = Release|Win32 + {B9C37E51-E357-4019-B4B5-71C42E1FCD11}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Legacy/Aria/ArNetworking/examples/Makefile b/Legacy/Aria/ArNetworking/examples/Makefile new file mode 100644 index 0000000..d977f56 --- /dev/null +++ b/Legacy/Aria/ArNetworking/examples/Makefile @@ -0,0 +1,8 @@ + +all: + $(MAKE) -C .. examples + +%: %.cpp + $(MAKE) -C .. examples/$@ + +.PHONY: all diff --git a/Legacy/Aria/ArNetworking/examples/README.txt b/Legacy/Aria/ArNetworking/examples/README.txt new file mode 100644 index 0000000..0e7e0bf --- /dev/null +++ b/Legacy/Aria/ArNetworking/examples/README.txt @@ -0,0 +1,26 @@ +These mostly come in pairs, with the description in front then the +client or server tag + +clientCommandLister - A client that just connects to the server then lists the + data that the server has available. Also useful as a testing/diagnostic tool. + +configClient - A client that will get the ArConfig information from the server + +configClientToServer - A client that will send ArConfig information from + a config file to the server + +configServer - A server that takes the ArConfig information and + makes it available to the client, use in conjunction with configClient + +configServerRobot - Serves up a robot parameter file to edit (example) + +serverDemo - An example that will show the setting up of a + server with robot sensor visualization, robot control, and more... + connect with MobileEyes. + +drawingsExample - Shows how to display custom graphics (drawings) in + a client + +drawingsExampleWithRobot - Shows how to display custom graphics (drawings) + in a client, along with the robot and its sensors. + diff --git a/Legacy/Aria/ArNetworking/examples/clientCommandLister.cpp b/Legacy/Aria/ArNetworking/examples/clientCommandLister.cpp new file mode 100644 index 0000000..b7a2cd8 --- /dev/null +++ b/Legacy/Aria/ArNetworking/examples/clientCommandLister.cpp @@ -0,0 +1,36 @@ +#include "Aria.h" +#include "ArNetworking.h" + +int main(int argc, char **argv) +{ + Aria::init(); + ArLog::init(ArLog::StdOut, ArLog::Normal); + ArClientBase client; + + ArArgumentParser parser(&argc, argv); + + ArClientSimpleConnector clientConnector(&parser); + parser.loadDefaultArguments(); + + if (!clientConnector.parseArgs() || !parser.checkHelpAndWarnUnparsed()) + { + clientConnector.logOptions(); + exit(0); + } + + if (!clientConnector.connectClient(&client)) + { + if (client.wasRejected()) + printf("Server '%s' rejected connection, exiting\n", client.getHost()); + else + printf("Could not connect to server '%s', exiting\n", client.getHost()); + exit(1); + } + client.setRobotName(client.getHost()); // include server hostname in log messages + client.runAsync(); + ArUtil::sleep(500); + client.logDataList(); + Aria::shutdown(); + return 0; +} + diff --git a/Legacy/Aria/ArNetworking/examples/clientDemo-vc2003.vcproj b/Legacy/Aria/ArNetworking/examples/clientDemo-vc2003.vcproj new file mode 100644 index 0000000..856fa8b --- /dev/null +++ b/Legacy/Aria/ArNetworking/examples/clientDemo-vc2003.vcproj @@ -0,0 +1,181 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/ArNetworking/examples/clientDemo-vc2008.vcproj b/Legacy/Aria/ArNetworking/examples/clientDemo-vc2008.vcproj new file mode 100644 index 0000000..7c4c2b3 --- /dev/null +++ b/Legacy/Aria/ArNetworking/examples/clientDemo-vc2008.vcproj @@ -0,0 +1,251 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/ArNetworking/examples/clientDemo-vc2010.vcxproj b/Legacy/Aria/ArNetworking/examples/clientDemo-vc2010.vcxproj new file mode 100644 index 0000000..a2b2546 --- /dev/null +++ b/Legacy/Aria/ArNetworking/examples/clientDemo-vc2010.vcxproj @@ -0,0 +1,159 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + clientDemo + {806E0C42-BE8A-4857-A97B-068FD56C27A1} + + + + Application + false + MultiByte + v100 + + + Application + false + MultiByte + v100 + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + ../../bin/ + ../../obj/$(ProjectName)-$(Configuration)-VC10/ + false + ../../bin/ + ../../obj/$(ProjectName)-$(Configuration)-VC10/ + false + clientDemoDebugVC10 + $(ProjectName)VC10 + + + + $(IntDir)$(ProjectName)BuildLog.htm + + + .\../../bin/clientDemo.tlb + + + + + Disabled + ..\include;..\..\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + Default + MultiThreadedDebugDLL + false + + + .\../../obj/ + .\../../obj/ + $(IntDir)vc100.pdb + true + Level3 + true + ProgramDatabase + Default + true + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + AriaDebugVC10.lib;ArNetworkingDebugVC10.lib + $(OutDir)$(TargetFileName) + 1.0 + true + ..\..\lib;%(AdditionalLibraryDirectories) + true + Console + false + + + MachineX86 + + + + + $(IntDir)$(ProjectName)BuildLog.htm + + + .\../../bin/clientDemo.tlb + + + + + MaxSpeed + AnySuitable + true + ..\include;..\..\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + MultiThreadedDLL + false + false + .\../../obj/clientDemo.pch + .\../../obj/ + .\../../obj/ + .\../../obj/ + Level3 + true + Default + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + AriaVC10.lib;ArNetworkingVC10.lib + $(OutDir)$(TargetFileName) + 1.0 + true + ..\..\lib;%(AdditionalLibraryDirectories) + Console + false + + + MachineX86 + + + + + Disabled + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + EnableFastChecks + true + MaxSpeed + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + + + + \ No newline at end of file diff --git a/Legacy/Aria/ArNetworking/examples/clientDemo.cpp b/Legacy/Aria/ArNetworking/examples/clientDemo.cpp new file mode 100644 index 0000000..03a000c --- /dev/null +++ b/Legacy/Aria/ArNetworking/examples/clientDemo.cpp @@ -0,0 +1,634 @@ +/* This is the ArNetworking example client. + * It connects to an ArNetworking server, and provides continuous + * information about the robot state (position, speed, server mode, etc.), + * and, if the server supports the commands, lets you drive the robot with + * the keyboard. + * + * To see the example client in action, first run a server on the robot's + * onboard computer, for example, serverDemo, testServer, guiServer (from ARNL), + * or ARAM. Make sure the robot computer is on a network, and run this + * clientDemo with the hostname of the robot computer as an argument: + * + * ./clientDemo -host myrobot + * + */ + +#include "Aria.h" +#include "ArNetworking.h" + + +/* This class provides callback functions which are called by the ArKeyHandler + * object when the user presses keys. These callback functions adjust member + * variables. The sendInput() method sends a command with those values + * to the server using the "ratioDrive" request. + */ + +class InputHandler +{ +public: + /** + * @param client Our client networking object + * @param keyHandler Key handler to register command callbacks with + */ + InputHandler(ArClientBase *client, ArKeyHandler *keyHandler); + virtual ~InputHandler(void); + + /// Up arrow key handler: drive the robot forward + void up(void); + + /// Down arrow key handler: drive the robot backward + void down(void); + + /// Left arrow key handler: turn the robot left + void left(void); + + /// Right arrow key handler: turn the robot right + void right(void); + + /// Move the robot laterally right (q key) + void lateralLeft(void); + + /// Move the robot laterally right (e key) + void lateralRight(void); + + /// Send drive request to the server with stored values + void sendInput(void); + + /// Send a request to enable "safe drive" mode on the server + void safeDrive(); + + /// Send a request to disable "safe drive" mode on the server + void unsafeDrive(); + + void listData(); + + void logTrackingTerse(); + void logTrackingVerbose(); + void resetTracking(); +protected: + ArClientBase *myClient; + ArKeyHandler *myKeyHandler; + + /// Set this to true in the constructor to print out debugging information + bool myPrinting; + + /// Current translation value (a percentage of the maximum speed) + double myTransRatio; + + /// Current rotation ration value (a percentage of the maximum rotational velocity) + double myRotRatio; + + /// Current rotation ration value (a percentage of the maximum rotational velocity) + double myLatRatio; + + /** Functor objects, given to the key handler, which then call our handler + * methods above */ + ///@{ + ArFunctorC myUpCB; + ArFunctorC myDownCB; + ArFunctorC myLeftCB; + ArFunctorC myRightCB; + ArFunctorC myLateralLeftCB; + ArFunctorC myLateralRightCB; + ArFunctorC mySafeDriveCB; + ArFunctorC myUnsafeDriveCB; + ArFunctorC myListDataCB; + ArFunctorC myLogTrackingTerseCB; + ArFunctorC myLogTrackingVerboseCB; + ArFunctorC myResetTrackingCB; + ///@} +}; + +InputHandler::InputHandler(ArClientBase *client, ArKeyHandler *keyHandler) : + myClient(client), myKeyHandler(keyHandler), + myPrinting(false), myTransRatio(0.0), myRotRatio(0.0), myLatRatio(0.0), + + /* Initialize functor objects with pointers to our handler methods: */ + myUpCB(this, &InputHandler::up), + myDownCB(this, &InputHandler::down), + myLeftCB(this, &InputHandler::left), + myRightCB(this, &InputHandler::right), + myLateralLeftCB(this, &InputHandler::lateralLeft), + myLateralRightCB(this, &InputHandler::lateralRight), + mySafeDriveCB(this, &InputHandler::safeDrive), + myUnsafeDriveCB(this, &InputHandler::unsafeDrive), + myListDataCB(this, &InputHandler::listData), + myLogTrackingTerseCB(this, &InputHandler::logTrackingTerse), + myLogTrackingVerboseCB(this, &InputHandler::logTrackingVerbose), + myResetTrackingCB(this, &InputHandler::resetTracking) +{ + + /* Add our functor objects to the key handler, associated with the appropriate + * keys: */ + myKeyHandler->addKeyHandler(ArKeyHandler::UP, &myUpCB); + myKeyHandler->addKeyHandler(ArKeyHandler::DOWN, &myDownCB); + myKeyHandler->addKeyHandler(ArKeyHandler::LEFT, &myLeftCB); + myKeyHandler->addKeyHandler(ArKeyHandler::RIGHT, &myRightCB); + myKeyHandler->addKeyHandler('q', &myLateralLeftCB); + myKeyHandler->addKeyHandler('e', &myLateralRightCB); + myKeyHandler->addKeyHandler('s', &mySafeDriveCB); + myKeyHandler->addKeyHandler('u', &myUnsafeDriveCB); + myKeyHandler->addKeyHandler('l', &myListDataCB); + myKeyHandler->addKeyHandler('t', &myLogTrackingTerseCB); + myKeyHandler->addKeyHandler('v', &myLogTrackingVerboseCB); + myKeyHandler->addKeyHandler('r', &myResetTrackingCB); +} + +InputHandler::~InputHandler(void) +{ + +} + +void InputHandler::up(void) +{ + if (myPrinting) + printf("Forwards\n"); + myTransRatio = 100; +} + +void InputHandler::down(void) +{ + if (myPrinting) + printf("Backwards\n"); + myTransRatio = -100; +} + +void InputHandler::left(void) +{ + if (myPrinting) + printf("Left\n"); + myRotRatio = 100; +} + +void InputHandler::right(void) +{ + if (myPrinting) + printf("Right\n"); + myRotRatio = -100; +} + +void InputHandler::lateralLeft(void) +{ + if (myPrinting) + printf("Lateral left\n"); + myLatRatio = 100; +} + +void InputHandler::lateralRight(void) +{ + if (myPrinting) + printf("Lateral right\n"); + myLatRatio = -100; +} + +void InputHandler::safeDrive() +{ + /* Construct a request packet. The data is a single byte, with value + * 1 to enable safe drive, 0 to disable. */ + ArNetPacket p; + p.byteToBuf(1); + + /* Send the packet as a single request: */ + if(myPrinting) + printf("Sending setSafeDrive 1.\n"); + myClient->requestOnce("setSafeDrive",&p); + if(myPrinting) + printf("\nSent enable safe drive.\n"); +} + +void InputHandler::unsafeDrive() +{ + /* Construct a request packet. The data is a single byte, with value + * 1 to enable safe drive, 0 to disable. */ + ArNetPacket p; + p.byteToBuf(0); + + /* Send the packet as a single request: */ + if(myPrinting) + printf("Sending setSafeDrive 0.\n"); + myClient->requestOnce("setSafeDrive",&p); + if(myPrinting) + printf("\nSent disable safe drive command. Your robot WILL run over things if you're not careful.\n"); +} + +void InputHandler::listData() +{ + myClient->logDataList(); +} + +void InputHandler::logTrackingTerse() +{ + myClient->logTracking(true); +} + +void InputHandler::logTrackingVerbose() +{ + myClient->logTracking(false); +} + +void InputHandler::resetTracking() +{ + myClient->resetTracking(); +} + + +void InputHandler::sendInput(void) +{ + /* This method is called by the main function to send a ratioDrive + * request with our current velocity values. If the server does + * not support the ratioDrive request, then we abort now: */ + if(!myClient->dataExists("ratioDrive")) return; + + /* Construct a ratioDrive request packet. It consists + * of three doubles: translation ratio, rotation ratio, and an overall scaling + * factor. */ + ArNetPacket packet; + packet.doubleToBuf(myTransRatio); + packet.doubleToBuf(myRotRatio); + packet.doubleToBuf(50); // use half of the robot's maximum. + packet.doubleToBuf(myLatRatio); + if (myPrinting) + printf("Sending\n"); + myClient->requestOnce("ratioDrive", &packet); + myTransRatio = 0; + myRotRatio = 0; + myLatRatio = 0; +} + + +/** This class requests continual data updates from the server and prints them + * out. + */ +class OutputHandler +{ +public: + OutputHandler(ArClientBase *client); + virtual ~OutputHandler(void); + + /// This callback is called when an update on general robot state arrives + void handleOutput(ArNetPacket *packet); + /// This callback is called when an update on general robot state arrives + void handleOutputNumbers(ArNetPacket *packet); + /// This callback is called when an update on general robot state arrives + void handleOutputStrings(ArNetPacket *packet); + + /// This callback is called when an update on the battery configuration changes + void handleBatteryInfo(ArNetPacket *packet); + /// This is called when the physical robot information comes back + void handlePhysicalInfo(ArNetPacket *packet); + /// This callback is called when an update on the temperature information changes + void handleTemperatureInfo(ArNetPacket *packet); + /// Called when the map on the server changes. + void handleMapUpdated(ArNetPacket *packet); +protected: + + /// The results from the data update are stored in these variables + //@{ + double myX; + double myY; + double myTh; + double myVel; + double myRotVel; + double myLatVel; + bool myVoltageIsStateOfCharge; + char myTemperature; + double myVoltage; + char myStatus[256]; + char myMode[256]; + //@} + ArClientBase *myClient; + + /** These functor objects are given to the client to receive updates when they + * arrive from the server. + */ + //@{ + ArFunctor1C myHandleOutputCB; + ArFunctor1C myHandleOutputNumbersCB; + ArFunctor1C myHandleOutputStringsCB; + ArFunctor1C myHandleBatteryInfoCB; + ArFunctor1C myHandlePhysicalInfoCB; + ArFunctor1C myHandleTemperatureInfoCB; + ArFunctor1C myHandleMapUpdatedCB; + //@} + + /// A header for the columns in the data printout is sometimes printed + bool myNeedToPrintHeader; + /// Don't print any information until we get the battery info + bool myGotBatteryInfo; +}; + +OutputHandler::OutputHandler(ArClientBase *client) : + myClient(client), + myHandleOutputCB(this, &OutputHandler::handleOutput), + myHandleOutputNumbersCB(this, &OutputHandler::handleOutputNumbers), + myHandleOutputStringsCB(this, &OutputHandler::handleOutputStrings), + myHandleBatteryInfoCB(this, &OutputHandler::handleBatteryInfo), + myHandlePhysicalInfoCB(this, &OutputHandler::handlePhysicalInfo), + myHandleTemperatureInfoCB(this, &OutputHandler::handleTemperatureInfo), + myHandleMapUpdatedCB(this, &OutputHandler::handleMapUpdated), + myNeedToPrintHeader(false), + myGotBatteryInfo(false) +{ + /* Add a handler for battery info, and make a single request for it */ + myClient->addHandler("physicalInfo", &myHandlePhysicalInfoCB); + myClient->requestOnce("physicalInfo"); + + + /* Add a handler for battery info, and make a single request for it */ + myClient->addHandler("batteryInfo", &myHandleBatteryInfoCB); + myClient->requestOnce("batteryInfo"); + + /* If it exists add a handler for temperature info, and make a + * single request for it */ + if (myClient->dataExists("temperatureInfo")) + { + myClient->addHandler("temperatureInfo", &myHandleTemperatureInfoCB); + myClient->requestOnce("temperatureInfo"); + } + + // if we have the new way of broadcasting that only pushes strings + // when they change then use that + if (myClient->dataExists("updateNumbers") && + myClient->dataExists("updateStrings")) + { + printf("Using new updates\n"); + // get the numbers every 100 ms + myClient->addHandler("updateNumbers", &myHandleOutputNumbersCB); + myClient->request("updateNumbers", 100); + // and the strings whenever they change (and are broadcast) + myClient->addHandler("updateStrings", &myHandleOutputStringsCB); + myClient->request("updateStrings", -1); + } + else + { + printf("Using old updates\n"); + // For the old way, just Add a handler for general info, and + // request it to be called every 100 ms + myClient->addHandler("update", &myHandleOutputCB); + myClient->request("update", 100); + } + + if(myClient->dataExists("mapUpdated")) + { + myClient->addHandler("mapUpdated", &myHandleMapUpdatedCB); + myClient->request("mapUpdated", -1); + } +} + +OutputHandler::~OutputHandler(void) +{ + /* Halt the request for data updates */ + myClient->requestStop("update"); +} + +void OutputHandler::handleOutput(ArNetPacket *packet) +{ + /* Extract the data from the update packet. Its format is status and + * mode (null-terminated strings), then 6 doubles for battery voltage, + * x position, y position and orientation (theta) (from odometry), current + * translational velocity, and current rotational velocity. Translation is + * always milimeters, rotation in degrees. + */ + memset(myStatus, 0, sizeof(myStatus)); + memset(myMode, 0, sizeof(myMode)); + packet->bufToStr(myStatus, sizeof(myStatus)); + packet->bufToStr(myMode, sizeof(myMode)); + myVoltage = ( (double) packet->bufToByte2() )/10.0; + myX = (double) packet->bufToByte4(); + myY = (double) packet->bufToByte4(); + myTh = (double) packet->bufToByte2(); + myVel = (double) packet->bufToByte2(); + myRotVel = (double) packet->bufToByte2(); + myLatVel = (double) packet->bufToByte2(); + myTemperature = (double) packet->bufToByte(); + + if(myNeedToPrintHeader) + { + printf("\n%6s|%6s|%6s|%6s|%6s|%6s|%4s|%6s|%15s|%20s|\n", + "x","y","theta", "vel", "rotVel", "latVel", "temp", myVoltageIsStateOfCharge ? "charge" : "volts", "mode","status"); + fflush(stdout); + myNeedToPrintHeader = false; + } + if (myGotBatteryInfo) + printf("%6.0f|%6.0f|%6.1f|%6.0f|%6.0f|%6.0f|%4.0d|%6.1f|%15s|%20s|\r", + myX, myY, myTh, myVel, myRotVel, myLatVel, myTemperature, myVoltage, myMode, myStatus); + + fflush(stdout); +} + +void OutputHandler::handleOutputNumbers(ArNetPacket *packet) +{ + /* Extract the data from the updateNumbers packet. Its format is 6 + * doubles for battery voltage, x position, y position and + * orientation (theta) (from odometry), current translational + * velocity, and current rotational velocity. Translation is always + * milimeters, rotation in degrees. + */ + myVoltage = ( (double) packet->bufToByte2() )/10.0; + myX = (double) packet->bufToByte4(); + myY = (double) packet->bufToByte4(); + myTh = (double) packet->bufToByte2(); + myVel = (double) packet->bufToByte2(); + myRotVel = (double) packet->bufToByte2(); + myLatVel = (double) packet->bufToByte2(); + myTemperature = (double) packet->bufToByte(); + + if(myNeedToPrintHeader) + { + printf("\n%6s|%6s|%6s|%6s|%6s|%6s|%4s|%6s|%15s|%20s|\n", + "x","y","theta", "vel", "rotVel", "latVel", "temp", myVoltageIsStateOfCharge ? "charge" : "volts", "mode","status"); + fflush(stdout); + myNeedToPrintHeader = false; + } + if (myGotBatteryInfo) + printf("%6.0f|%6.0f|%6.1f|%6.0f|%6.0f|%6.0f|%4.0d|%6.1f|%15s|%20s|\r", + myX, myY, myTh, myVel, myRotVel, myLatVel, myTemperature, myVoltage, myMode, myStatus); + + fflush(stdout); +} + +void OutputHandler::handleOutputStrings(ArNetPacket *packet) +{ + /* Extract the data from the updateStrings packet. Its format is + * status and mode (null-terminated strings). + */ + memset(myStatus, 0, sizeof(myStatus)); + memset(myMode, 0, sizeof(myMode)); + packet->bufToStr(myStatus, sizeof(myStatus)); + packet->bufToStr(myMode, sizeof(myMode)); +} + +void OutputHandler::handleBatteryInfo(ArNetPacket *packet) +{ + /* Get battery configuration parameters: when the robot will begin beeping and + * warning about low battery, and when it will automatically disconnect and + * shutdown. */ + double lowBattery = packet->bufToDouble(); + double shutdown = packet->bufToDouble(); + printf("Low battery voltage: %6g Shutdown battery voltage: %6g\n", lowBattery, shutdown); + fflush(stdout); + myNeedToPrintHeader = true; + myGotBatteryInfo = true; + + if (packet->getDataReadLength() == packet->getDataLength()) + { + printf("Packet is too small so its an old server, though you could just get to the bufToUByte anyways, since it'd be 0 anyhow\n"); + myVoltageIsStateOfCharge = false; + } + else + myVoltageIsStateOfCharge = (packet->bufToUByte() == 1); + +} + + +void OutputHandler::handlePhysicalInfo(ArNetPacket *packet) +{ + /* Get phyiscal configuration parameters: */ + char robotType[512]; + char robotSubtype[512]; + int width; + int lengthFront; + int lengthRear; + + packet->bufToStr(robotType, sizeof(robotType)); + packet->bufToStr(robotSubtype, sizeof(robotSubtype)); + width = packet->bufToByte2(); + lengthFront = packet->bufToByte2(); + lengthRear = packet->bufToByte2(); + + printf("Type: %s Subtype: %s Width %d: LengthFront: %d LengthRear: %d\n", + robotType, robotSubtype, width, lengthFront, lengthRear); + fflush(stdout); +} + +void OutputHandler::handleTemperatureInfo(ArNetPacket *packet) +{ + char warning = packet->bufToByte(); + char shutdown = packet->bufToByte(); + printf("High temperature warning: %4d High temperature shutdown: %4d\n", warning, shutdown); + fflush(stdout); + myNeedToPrintHeader = true; +} + +void OutputHandler::handleMapUpdated(ArNetPacket *packet) +{ + printf("\nMap changed.\n"); + fflush(stdout); + myNeedToPrintHeader = true; +} + + +/* Key handler for the escape key: shutdown all of Aria. */ +void escape(void) +{ + printf("esc pressed, shutting down aria\n"); + Aria::shutdown(); +} + +int main(int argc, char **argv) +{ + /* Aria initialization: */ + Aria::init(); + + //ArLog::init(ArLog::StdErr, ArLog::Verbose); + + + /* Create our client object. This is the object which connects with a remote + * server over the network, and which manages all of our communication with it + * once connected by sending data "requests". Requests may be sent once, or + * may be repeated at any frequency. Requests and replies to requsets contain + * payload "packets", into which various data types may be packed (when making a + * request), and from which they may also be extracted (when handling a reply). + * See the InputHandler and OutputHandler classes above for + * examples of making requests and reading/writing the data in packets. + */ + ArClientBase client; + + /* Aria components use this to get options off the command line: */ + ArArgumentParser parser(&argc, argv); + + /* This will be used to connect our client to the server, including + * various bits of handshaking (e.g. sending a password, retrieving a list + * of data requests and commands...) + * It will get the hostname from the -host command line argument: */ + ArClientSimpleConnector clientConnector(&parser); + + parser.loadDefaultArguments(); + + /* Check for -help, and unhandled arguments: */ + if (!Aria::parseArgs() || !parser.checkHelpAndWarnUnparsed()) + { + Aria::logOptions(); + exit(0); + } + + + /* Connect our client object to the remote server: */ + if (!clientConnector.connectClient(&client)) + { + if (client.wasRejected()) + printf("Server '%s' rejected connection, exiting\n", client.getHost()); + else + printf("Could not connect to server '%s', exiting\n", client.getHost()); + exit(1); + } + + printf("Connected to server.\n"); + + client.setRobotName(client.getHost()); // include server name in log messages + + /* Create a key handler and also tell Aria about it */ + ArKeyHandler keyHandler; + Aria::setKeyHandler(&keyHandler); + + /* Global escape-key handler to shut everythnig down */ + ArGlobalFunctor escapeCB(&escape); + keyHandler.addKeyHandler(ArKeyHandler::ESCAPE, &escapeCB); + + /* Now that we're connected, we can run the client in a background thread, + * sending requests and receiving replies. When a reply to a request arrives, + * or the server makes a request of the client, a handler functor is invoked. + * The handlers for this program are registered with the client by the + * InputHandler and OutputHandler classes (in their constructors, above) */ + client.runAsync(); + + /* Create the InputHandler object and request safe-drive mode */ + InputHandler inputHandler(&client, &keyHandler); + inputHandler.safeDrive(); + + /* Use ArClientBase::dataExists() to see if the "ratioDrive" request is available on the + * currently connected server. */ + if(!client.dataExists("ratioDrive") ) + printf("Warning: server does not have ratioDrive command, can not use drive commands!\n"); + else + printf("Keys are:\nUP: Forward\nDOWN: Backward\nLEFT: Turn Left\nRIGHT: Turn Right\n"); + printf("s: Enable safe drive mode (if supported).\nu: Disable safe drive mode (if supported).\nl: list all data requests on server\n\nDrive commands use 'ratioDrive'.\nt: logs the network tracking tersely\nv: logs the network tracking verbosely\nr: resets the network tracking\n\n"); + + + /* Create the OutputHandler object. It will begin printing out data from the + * server. */ + OutputHandler outputHandler(&client); + + + /* Begin capturing keys into the key handler. Callbacks will be called + * asyncrosously from this main thread when pressed. */ + + /* While the client is still running (getRunningWithLock locks the "running" + * flag until it returns), check keys on the key handler (which will call + * our callbacks), then tell the input handler to send drive commands. + * Sleep a fraction of a second as well to avoid using + * too much CPU time, and give other threads time to work. + */ + while (client.getRunningWithLock()) + { + keyHandler.checkKeys(); + inputHandler.sendInput(); + ArUtil::sleep(100); + } + + /* The client stopped running, due to disconnection from the server, general + * Aria shutdown, or some other reason. */ + client.disconnect(); + Aria::shutdown(); + return 0; +} diff --git a/Legacy/Aria/ArNetworking/examples/clientDemoStatic-vc2003.vcproj b/Legacy/Aria/ArNetworking/examples/clientDemoStatic-vc2003.vcproj new file mode 100644 index 0000000..5ecefa7 --- /dev/null +++ b/Legacy/Aria/ArNetworking/examples/clientDemoStatic-vc2003.vcproj @@ -0,0 +1,136 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/ArNetworking/examples/clientDemoStatic-vc2008.vcproj b/Legacy/Aria/ArNetworking/examples/clientDemoStatic-vc2008.vcproj new file mode 100644 index 0000000..fa75c01 --- /dev/null +++ b/Legacy/Aria/ArNetworking/examples/clientDemoStatic-vc2008.vcproj @@ -0,0 +1,214 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/ArNetworking/examples/clientDemoStatic-vc2010.vcxproj b/Legacy/Aria/ArNetworking/examples/clientDemoStatic-vc2010.vcxproj new file mode 100644 index 0000000..2912652 --- /dev/null +++ b/Legacy/Aria/ArNetworking/examples/clientDemoStatic-vc2010.vcxproj @@ -0,0 +1,146 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + clientDemoStatic + {0A8A179D-832B-44B2-829A-AB6E61BFF46E} + clientDemoStatic + ManagedCProj + + + + Application + MultiByte + false + + + Application + MultiByte + false + v100 + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + ..\..\bin\ + ../../obj/$(ProjectName)-$(Configuration)-VC10/ + true + ..\..\bin\ + ../../obj/$(ProjectName)-$(Configuration)-VC10/ + false + clientDemoStaticDebugVC10 + $(ProjectName)VC10 + + + + $(IntDir)$(ProjectName)BuildLog.htm + + + Disabled + ..\..\include;..\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;ARIA_STATIC;%(PreprocessorDefinitions) + false + Default + MultiThreadedDebug + false + + + Level3 + ProgramDatabase + true + + + false + + + ArNetworkingStaticDebugVC10.lib;AriaStaticDebugVC10.lib;ws2_32.lib;winmm.lib;advapi32.lib + $(OutDir)$(TargetFileName) + true + ..\..\lib;%(AdditionalLibraryDirectories) + %(IgnoreSpecificDefaultLibraries) + true + true + false + + + NotSet + + + + + $(IntDir)$(ProjectName)BuildLog.htm + + + AnySuitable + true + ..\..\include;..\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;ARIA_STATIC;%(PreprocessorDefinitions) + false + MultiThreaded + false + true + + + Level3 + ProgramDatabase + true + + + false + + + ArNetworkingStaticVC10.lib;AriaStaticVC10.lib;winmm.lib;ws2_32.lib;advapi32.lib;%(AdditionalDependencies) + $(OutDir)$(TargetFileName) + true + ..\..\lib;%(AdditionalLibraryDirectories) + %(IgnoreSpecificDefaultLibraries) + false + false + + + + + NotSet + + + + + true + true + + + true + true + + + true + true + + + + + + + + + \ No newline at end of file diff --git a/Legacy/Aria/ArNetworking/examples/configClient.cpp b/Legacy/Aria/ArNetworking/examples/configClient.cpp new file mode 100644 index 0000000..453fb2f --- /dev/null +++ b/Legacy/Aria/ArNetworking/examples/configClient.cpp @@ -0,0 +1,66 @@ +#include "Aria.h" +#include "ArNetworking.h" + +ArClientBase *client; +ArClientHandlerConfig *configHandler; +bool done = false; + +void gotConfig(void) +{ + ArConfig *newConfig; + done = true; + configHandler->getConfig()->writeFile("configClient.txt"); + newConfig = new ArConfig(*(configHandler->getConfig())); + newConfig->writeFile("configClientNew.txt"); +} + +int main(int argc, char **argv) +{ + Aria::init(); + ArGlobalFunctor gotConfigCB(&gotConfig); + std::string hostname; + + client = new ArClientBase; + configHandler = new ArClientHandlerConfig(client); + + configHandler->addGotConfigCB(&gotConfigCB); + + ArArgumentParser parser(&argc, argv); + + ArClientSimpleConnector clientConnector(&parser); + + parser.loadDefaultArguments(); + + /* Check for -help, and unhandled arguments: */ + if (!Aria::parseArgs() || !parser.checkHelpAndWarnUnparsed()) + { + Aria::logOptions(); + exit(0); + } + /* Connect our client object to the remote server: */ + if (!clientConnector.connectClient(client)) + { + exit(1); + } + + client->setRobotName(client->getHost()); // include server hostname in log messages + + configHandler->requestConfigFromServer(); + client->runAsync(); + + while (!done) + ArUtil::sleep(100); + + if (configHandler->canRequestDefaults()) + { + configHandler->requestDefaultConfigFromServer(); + while (!configHandler->haveGottenDefaults()) + ArUtil::sleep(100); + printf("%d\n", configHandler->haveGottenDefaults()); + configHandler->getDefaultConfig()->writeFile("configClientDefaults.txt"); + printf("wrote defaults\n"); + } + + + Aria::exit(0); +} diff --git a/Legacy/Aria/ArNetworking/examples/configClientToServer.cpp b/Legacy/Aria/ArNetworking/examples/configClientToServer.cpp new file mode 100644 index 0000000..3d19828 --- /dev/null +++ b/Legacy/Aria/ArNetworking/examples/configClientToServer.cpp @@ -0,0 +1,82 @@ +#include "Aria.h" +#include "ArNetworking.h" + +/* + Pass this a file to send to the server (should be made by configClient then modified). + + Takes a file to send, and can take the host to send to too + + */ + +ArClientBase *client; +ArClientHandlerConfig *configHandler; + +char *file; + +void saveConfigSucceeded(void) +{ + printf("HERE: Save config succeeded\n"); +} + +void saveConfigFailed(const char *str) +{ + printf("HERE: Save config failed: %s\n", str); +} + +void gotConfig(void) +{ + char errorBuffer[1024]; + ArConfig *newConfig; + if (!configHandler->getConfig()->parseFile(file, false, false, errorBuffer, + sizeof(errorBuffer))) + printf("Error loading file: %s\n", errorBuffer); + + configHandler->saveConfigToServer(); + client->loopOnce(); + ArUtil::sleep(1000); + client->loopOnce(); + ArUtil::sleep(1000); + client->disconnect(); + Aria::shutdown(); + exit(0); +} + +int main(int argc, char **argv) +{ + Aria::init(); + //ArLog::init(ArLog::StdOut, ArLog::Verbose); + ArGlobalFunctor gotConfigCB(&gotConfig); + ArGlobalFunctor saveConfigSucceededCB(&saveConfigSucceeded); + ArGlobalFunctor1 saveConfigFailedCB(&saveConfigFailed); + std::string hostname; + + client = new ArClientBase; + configHandler = new ArClientHandlerConfig(client, true); + + configHandler->addGotConfigCB(&gotConfigCB); + configHandler->addSaveConfigSucceededCB(&saveConfigSucceededCB); + configHandler->addSaveConfigFailedCB(&saveConfigFailedCB); + + if (argc == 1) + { + printf("Usage: %s \n", argv[0]); + exit(1); + } + file = argv[1]; + if (argc == 2) + hostname = "localhost"; + else + hostname = argv[2]; + + + if (!client->blockingConnect(hostname.c_str(), 7272)) + { + printf("Could not connect to server, exiting\n"); + exit(1); + } + //client->requestOnce("setConfig"); + configHandler->requestConfigFromServer(); + //client->requestOnce("setConfig"); + client->run(); + return 0; +} diff --git a/Legacy/Aria/ArNetworking/examples/configServer.cpp b/Legacy/Aria/ArNetworking/examples/configServer.cpp new file mode 100644 index 0000000..ac858ca --- /dev/null +++ b/Legacy/Aria/ArNetworking/examples/configServer.cpp @@ -0,0 +1,61 @@ +#include "Aria.h" +#include "ArNetworking.h" + +int main(int argc, char **argv) +{ + Aria::init(); + ArServerBase server; + + ArConfig *config; + config = Aria::getConfig(); + std::string section; + char joy[512]; + sprintf(joy, "Joy"); + section = "section1"; + config->addParam(ArConfigArg("int", new int, "fun int", 0), section.c_str(), ArPriority::NORMAL); + config->addParam(ArConfigArg("double", new double, "fun double", 0, 1), section.c_str(), ArPriority::NORMAL); + config->addParam(ArConfigArg("bool", new bool, "fun bool"), section.c_str(), ArPriority::IMPORTANT); + config->addParam(ArConfigArg("string", joy, "fun string", sizeof(joy)), section.c_str(), ArPriority::TRIVIAL); + section = "section8"; + config->addParam(ArConfigArg("int", new int, "fun int", 0), section.c_str(), ArPriority::NORMAL); + config->addParam(ArConfigArg("double", new double, "fun double", 0, 1), section.c_str(), ArPriority::NORMAL); + config->addParam(ArConfigArg("doubleFOUR", (double).4, "fun double", 0.0, 1.0), section.c_str(), ArPriority::NORMAL); + config->addParam(ArConfigArg("double three", new double, "fun double", 0, 1), section.c_str(), ArPriority::NORMAL); + config->addParam(ArConfigArg("double two", new double, "fun double", 0, 1), section.c_str(), ArPriority::NORMAL); + config->addParam(ArConfigArg("double one", new double, "fun double", 0, 1), section.c_str(), ArPriority::NORMAL); + config->addParam(ArConfigArg("double", new double, "fun double", 0, 1), section.c_str(), ArPriority::NORMAL); + config->addParam(ArConfigArg("bool", new bool, "fun bool"), section.c_str(), ArPriority::IMPORTANT); + config->addParam(ArConfigArg("string", joy, "fun string", sizeof(joy)), section.c_str(), ArPriority::TRIVIAL); + section = "some section"; + config->setSectionComment("some section", "this is a random section with 4 ints"); + config->addParam(ArConfigArg("int1", new int, "fun int"), section.c_str(), ArPriority::TRIVIAL); + config->addParam(ArConfigArg("int2", new int, "fun int", -1, 1200), section.c_str(), ArPriority::NORMAL); + config->addParam(ArConfigArg("int3", new int, "fun int"), section.c_str(), ArPriority::IMPORTANT); + config->addParam(ArConfigArg("int4", new int, "fun int"), section.c_str(), ArPriority::NORMAL); + config->addParam(ArConfigArg("int4", new int, "fun int"), section.c_str(), ArPriority::NORMAL); + config->addParam(ArConfigArg("int1", new int, "fun int"), section.c_str(), ArPriority::TRIVIAL); + section = "another section"; + config->setSectionComment("another section", "this is another section with 1 of each type"); + config->addParam(ArConfigArg("inta", new int, "fun int"), section.c_str(), ArPriority::NORMAL); + config->addParam(ArConfigArg("doublea", new double, "fun double"), section.c_str(), ArPriority::NORMAL); + config->addParam(ArConfigArg("boola", new bool, "fun bool"), section.c_str(), ArPriority::NORMAL); + config->addParam(ArConfigArg("stringa", new char[512], "fun string", 512), section.c_str(), ArPriority::NORMAL); + + if (!server.open(7272)) + { + printf("Could not open server port\n"); + exit(1); + } + config->setBaseDirectory("./"); + config->writeFile("default.txt"); + config->parseFile("modified.txt"); + config->writeFile("modifiedModified.txt"); + ArServerHandlerConfig configHandler(&server, Aria::getConfig(), + "default.txt"); + + server.run(); + + Aria::shutdown(); + + return 0; +} diff --git a/Legacy/Aria/ArNetworking/examples/configServerRobot.cpp b/Legacy/Aria/ArNetworking/examples/configServerRobot.cpp new file mode 100644 index 0000000..60d0036 --- /dev/null +++ b/Legacy/Aria/ArNetworking/examples/configServerRobot.cpp @@ -0,0 +1,30 @@ +#include "Aria.h" +#include "ArNetworking.h" + +int main(int argc, char **argv) +{ + Aria::init(); + ArServerBase server; + + //ArLog::init(ArLog::StdOut, ArLog::Verbose); + ArConfig *config; + config = Aria::getConfig(); + + ArRobotP3DX dx; + //dx.writeFile("dx.txt"); + *Aria::getConfig() = dx; + //Aria::getConfig()->writeFile("dxcopy.txt"); + + if (!server.open(7272)) + { + printf("Could not open server port\n"); + exit(1); + } + + ArServerHandlerConfig configHandler(&server, Aria::getConfig()); + server.run(); + + Aria::shutdown(); + + return 0; +} diff --git a/Legacy/Aria/ArNetworking/examples/drawingsExample.cpp b/Legacy/Aria/ArNetworking/examples/drawingsExample.cpp new file mode 100644 index 0000000..9486158 --- /dev/null +++ b/Legacy/Aria/ArNetworking/examples/drawingsExample.cpp @@ -0,0 +1,287 @@ +#include "Aria.h" +#include "ArNetworking.h" +#include + + +/** @example drawingsExample.cpp Example showing how to draw custom graphics in + * clients such as MobileEyes + * + * This is an example server that shows how to draw arbitrary figures in a + * client (e.g. MobileEyes) via ArServerInfoDrawings. It draws some lines, "arrows", and moving dots + * with various sizes and colors. You can use these drawings for debugging + * or visualization, for example, to represent sensor readings. In fact, + * specific support for ArRobot, ArSick, ArSonarDevice, ArIRs and ArBumpers + * are built in to ArServerInfoDrawings: see drawingsExampleWithRobot.cpp + * or serverDemo.cpp. + * + * @sa drawingsExampleWithRobot.cpp + */ + + +/* These are some callbacks that respond to client requests for the drawings' + * geometry data. */ +void exampleHomeDrawingNetCallback(ArServerClient* client, ArNetPacket* requestPkt); +void exampleDotsDrawingNetCallback(ArServerClient* client, ArNetPacket* requestPkt); +void exampleXDrawingNetCallback(ArServerClient* client, ArNetPacket* requestPkt); +void exampleArrowsDrawingNetCallback(ArServerClient* client, ArNetPacket* requestPkt); + + +/* This class shows how to encapsulate the various aspects of a drawing into one + * object that other parts of the program can easily access in a more general + * (and thread-safe) way. It lets you change position, radius, resolution + * (number of dots), and dot drawing properties. + * The default radius is 1 meter and the default number of points is 360. + * + * In this example program, the radius is updated periodically by a loop in the + * main thread (see main() function), while ArNetworking requests are handled + * in the separate ArNetworking server thread, calling drawingServerCB() callback (this is + * registered with the server when we register the drawing with the + * ArServerInfoDrawings object). So note the use of an ArMutex object to + * control this asyrchronous access to the reply packet. + */ +class Circle +{ +private: + ArNetPacket myReply; + ArMutex myMutex; // mutex around myReply + ArPose myPos; + double myRadius; + unsigned int myNumPoints; + void drawingServerCB(ArServerClient *client, ArNetPacket *pkt); + ArFunctor2C callback; + void regenerate(); +public: + Circle(ArServerInfoDrawings *drawingsServer, const std::string& name, ArDrawingData *drawData); + ~Circle(); + + void setPos(const ArPose& p) + { + myPos = p; + regenerate(); + } + + void setRadius(double r) + { + myRadius = r; + regenerate(); + } + + void setNumPoints(unsigned int r) + { + myNumPoints = r; + regenerate(); + } + +}; + +Circle::Circle(ArServerInfoDrawings *drawingsServer, const std::string& name, ArDrawingData* drawData) : + myRadius(1000.0), + myNumPoints(360), + callback(this, &Circle::drawingServerCB) +{ + drawingsServer->addDrawing(drawData, name.c_str(), &callback); +} + +Circle::~Circle() +{ + // TODO remove drawing from the server, but not implemented yet +} + +void Circle::drawingServerCB(ArServerClient *client, ArNetPacket *pkt) +{ + myMutex.lock(); + client->sendPacketUdp(&myReply); + myMutex.unlock(); +} + +// Method called by accessor methods when properties changed. This reconstructs +// the myReply packet sent in response to requests from clients +void Circle::regenerate() +{ + myMutex.lock(); + myReply.empty(); + myReply.byte4ToBuf(myNumPoints); + double a = 360.0/myNumPoints; + for(unsigned int i = 0; i < myNumPoints; ++i) + { + myReply.byte4ToBuf(ArMath::roundInt(myPos.getX()+ArMath::cos(i*a)*myRadius)); // X + myReply.byte4ToBuf(ArMath::roundInt(myPos.getY()+ArMath::sin(i*a)*myRadius)); // Y + } + myMutex.unlock(); +} + + +int main(int argc, char **argv) +{ + Aria::init(); + ArServerBase server; + + ArArgumentParser parser(&argc, argv); + ArServerSimpleOpener simpleOpener(&parser); + + // parse the command line... fail and print the help if the parsing fails + // or if help was requested + parser.loadDefaultArguments(); + if (!simpleOpener.parseArgs() || !parser.checkHelpAndWarnUnparsed()) + { + simpleOpener.logOptions(); + exit(1); + } + + + // first open the server up + if (!simpleOpener.open(&server)) + { + if (simpleOpener.wasUserFileBad()) + printf("Error: Bad user/password/permissions file.\n"); + else + printf("Error: Could not open server port. Use -help to see options.\n"); + exit(1); + } + + + // This is the service that provides drawing data to the client. + ArServerInfoDrawings drawings(&server); + + // Add our custom drawings + drawings.addDrawing( + // shape: color: size: layer: + new ArDrawingData("polyLine", ArColor(255, 0, 0), 2, 49), + "exampleDrawing_Home", + new ArGlobalFunctor2(&exampleHomeDrawingNetCallback) + ); + drawings.addDrawing( + new ArDrawingData("polyDots", ArColor(0, 255, 0), 250, 48), + "exampleDrawing_Dots", + new ArGlobalFunctor2(&exampleDotsDrawingNetCallback) + ); + drawings.addDrawing( + new ArDrawingData("polySegments", ArColor(0, 0, 0), 4, 52), + "exampleDrawing_XMarksTheSpot", + new ArGlobalFunctor2(&exampleXDrawingNetCallback) + ); + drawings.addDrawing( + new ArDrawingData("polyArrows", ArColor(255, 0, 255), 500, 100), + "exampleDrawing_Arrows", + new ArGlobalFunctor2(&exampleArrowsDrawingNetCallback) + ); + + Circle circle(&drawings, "exampleDrawing_circle", + new ArDrawingData("polySegments", ArColor(255, 150, 0), 3, 120)); + circle.setPos(ArPose(0, -5000)); + circle.setRadius(1000); + circle.setNumPoints(360); + + // log whatever we wanted to before the runAsync + simpleOpener.checkAndLog(); + + // run the server thread in the background + server.runAsync(); + + printf("Server is now running...\n"); + + + // Add a key handler mostly that windows can exit by pressing + // escape, note that the key handler prevents you from running this program + // in the background on Linux. + ArKeyHandler *keyHandler; + if ((keyHandler = Aria::getKeyHandler()) == NULL) + { + keyHandler = new ArKeyHandler; + Aria::setKeyHandler(keyHandler); + printf("To exit, press escape.\n"); + } + + + double circleRadius = 1000; + while(true) + { + ArUtil::sleep(100); + circleRadius += 50; + if(circleRadius > 5000) + circleRadius = 0; + circle.setRadius(circleRadius); + } + + Aria::shutdown(); + exit(0); +} + + + + +// Network callbacks for drawings' current geometry data: + +void exampleHomeDrawingNetCallback(ArServerClient* client, ArNetPacket* requestPkt) { + ArNetPacket reply; + + // 7 Vertices + reply.byte4ToBuf(7); + + // Centered on 0,0. + // X: Y: + reply.byte4ToBuf(-500); reply.byte4ToBuf(500); // Vertex 1 + reply.byte4ToBuf(-500); reply.byte4ToBuf(-500); // Vertex 2 + reply.byte4ToBuf(500); reply.byte4ToBuf(-500); // Vertex 3 + reply.byte4ToBuf(500); reply.byte4ToBuf(500); // Vertex 4 + reply.byte4ToBuf(0); reply.byte4ToBuf(1000); // Vertex 5 + reply.byte4ToBuf(-500); reply.byte4ToBuf(500); // Vertex 6 + reply.byte4ToBuf(500); reply.byte4ToBuf(500); // Vertex 7 + + client->sendPacketUdp(&reply); +} + +void exampleDotsDrawingNetCallback(ArServerClient* client, ArNetPacket* requestPkt) { + ArNetPacket reply; + + unsigned int tik = ArUtil::getTime() % 200; + double t = tik / 5.0; + + // Three dots + reply.byte4ToBuf(3); + + // Dot 1: + reply.byte4ToBuf(3000); // X coordinate (mm) + reply.byte4ToBuf((int) (sin(t) * 1000));// Y + + // Dot 2: + reply.byte4ToBuf(3500); // X + reply.byte4ToBuf((int) (sin(t+500) * 1000));// Y + + // Dot 3: + reply.byte4ToBuf(4000); // X + reply.byte4ToBuf((int) (sin(t+1000) * 1000));// Y + + client->sendPacketUdp(&reply); +} + +void exampleXDrawingNetCallback(ArServerClient* client, ArNetPacket* requestPkt) { + ArNetPacket reply; + + // X marks the spot. 2 line segments, so 4 vertices: + reply.byte4ToBuf(4); + + // Segment 1: + reply.byte4ToBuf(-4250); // X1 + reply.byte4ToBuf(250); // Y1 + reply.byte4ToBuf(-3750); // X2 + reply.byte4ToBuf(-250); // Y2 + + // Segment 2: + reply.byte4ToBuf(-4250); // X1 + reply.byte4ToBuf(-250); // Y1 + reply.byte4ToBuf(-3750); // X2 + reply.byte4ToBuf(250); // Y2 + + client->sendPacketUdp(&reply); +} + +void exampleArrowsDrawingNetCallback(ArServerClient* client, ArNetPacket* requestPkt) { + // 1 Arrow that points at the robot + ArNetPacket reply; + reply.byte4ToBuf(1); + reply.byte4ToBuf(0); // Pos. X + reply.byte4ToBuf(700); // Pos. Y + client->sendPacketUdp(&reply); +} + diff --git a/Legacy/Aria/ArNetworking/examples/drawingsExampleWithRobot.cpp b/Legacy/Aria/ArNetworking/examples/drawingsExampleWithRobot.cpp new file mode 100644 index 0000000..49525de --- /dev/null +++ b/Legacy/Aria/ArNetworking/examples/drawingsExampleWithRobot.cpp @@ -0,0 +1,256 @@ +#include "Aria.h" +#include "ArNetworking.h" +#include + +/** @example drawingsExampleWithRobot.cpp Example showing how to draw custom + * graphics in clients such as MobileEyes, and enable drawing of sensor + * readings as well. + * + * This is an example server that shows how to draw arbitrary figures in a + * client (e.g. MobileEyes). It also uses the convenient built-in + * support for visualization built in to ArRobot, ArSick, ArSonarDevice, + * etc. + * + * @sa drawingsExample.cpp which does not include robot and sensor drawings + */ + +/* These are callbacks that respond to client requests for the drawings' + * geometry data. */ +void exampleHomeDrawingNetCallback(ArServerClient* client, ArNetPacket* requestPkt); +void exampleDotsDrawingNetCallback(ArServerClient* client, ArNetPacket* requestPkt); +void exampleXDrawingNetCallback(ArServerClient* client, ArNetPacket* requestPkt); +void exampleArrowsDrawingNetCallback(ArServerClient* client, ArNetPacket* requestPkt); + +int main(int argc, char **argv) +{ + Aria::init(); + ArRobot robot; + ArServerBase server; + + ArArgumentParser parser(&argc, argv); + ArSimpleConnector simpleConnector(&parser); + ArServerSimpleOpener simpleOpener(&parser); + + + // parse the command line... fail and print the help if the parsing fails + // or if help was requested + parser.loadDefaultArguments(); + if (!simpleConnector.parseArgs() || !simpleOpener.parseArgs() || + !parser.checkHelpAndWarnUnparsed()) + { + simpleConnector.logOptions(); + simpleOpener.logOptions(); + exit(1); + } + + // Set up where we'll look for files such as config file, user/password file, + // etc. + char fileDir[1024]; + ArUtil::addDirectories(fileDir, sizeof(fileDir), Aria::getDirectory(), + "ArNetworking/examples"); + + // first open the server up + if (!simpleOpener.open(&server, fileDir, 240)) + { + if (simpleOpener.wasUserFileBad()) + printf("Error: Bad user/password/permissions file.\n"); + else + printf("Error: Could not open server port. Use -help to see options.\n"); + exit(1); + } + + + // Devices + ArAnalogGyro gyro(&robot); + + ArSonarDevice sonarDev; + robot.addRangeDevice(&sonarDev); + + ArIRs irs; + robot.addRangeDevice(&irs); + + ArBumpers bumpers; + robot.addRangeDevice(&bumpers); + + ArSick sick(361, 180); + robot.addRangeDevice(&sick); + + + ArServerInfoRobot serverInfoRobot(&server, &robot); + ArServerInfoSensor serverInfoSensor(&server, &robot); + + // This is the service that provides drawing data to the client. + ArServerInfoDrawings drawings(&server); + + // Convenience function that sets up drawings for all the robot's current + // range devices (using default shape and color info) + drawings.addRobotsRangeDevices(&robot); + + // Add our custom drawings + drawings.addDrawing( + // shape: color: size: layer: + new ArDrawingData("polyLine", ArColor(255, 0, 0), 2, 49), + "exampleDrawing_Home", + new ArGlobalFunctor2(&exampleHomeDrawingNetCallback) + ); + drawings.addDrawing( + new ArDrawingData("polyDots", ArColor(0, 255, 0), 250, 48), + "exampleDrawing_Dots", + new ArGlobalFunctor2(&exampleDotsDrawingNetCallback) + ); + drawings.addDrawing( + new ArDrawingData("polySegments", ArColor(0, 0, 0), 4, 52), + "exampleDrawing_XMarksTheSpot", + new ArGlobalFunctor2(&exampleXDrawingNetCallback) + ); + drawings.addDrawing( + new ArDrawingData("polyArrows", ArColor(255, 0, 255), 500, 100), + "exampleDrawing_Arrows", + new ArGlobalFunctor2(&exampleArrowsDrawingNetCallback) + ); + + // modes for moving the robot + ArServerModeStop modeStop(&server, &robot); + ArServerModeDrive modeDrive(&server, &robot); + ArServerModeRatioDrive modeRatioDrive(&server, &robot); + ArServerModeWander modeWander(&server, &robot); + modeStop.addAsDefaultMode(); + modeStop.activate(); + + + + // Connect to the robot. + if (!simpleConnector.connectRobot(&robot)) + { + printf("Error: Could not connect to robot... exiting\n"); + Aria::shutdown(); + return 1; + } + + // set up the laser before handing it to the laser mode + simpleConnector.setupLaser(&sick); + + robot.enableMotors(); + + // start the robot cycle running in a background thread + robot.runAsync(true); + + // start the laser processing cycle in a background thread + sick.runAsync(); + + // connect the laser if it was requested + if (!simpleConnector.connectLaser(&sick)) + { + printf("Error: Could not connect to laser... exiting\n"); + Aria::shutdown(); + return 1; + } + + // log whatever we wanted to before the runAsync + simpleOpener.checkAndLog(); + + // run the server thread in the background + server.runAsync(); + + printf("Server is now running...\n"); + + + // Add a key handler mostly that windows can exit by pressing + // escape, note that the key handler prevents you from running this program + // in the background on Linux. + ArKeyHandler *keyHandler; + if ((keyHandler = Aria::getKeyHandler()) == NULL) + { + keyHandler = new ArKeyHandler; + Aria::setKeyHandler(keyHandler); + robot.lock(); + robot.attachKeyHandler(keyHandler); + robot.unlock(); + printf("To exit, press escape.\n"); + } + + robot.waitForRunExit(); + + + Aria::shutdown(); + exit(0); +} + + + + +// Network callbacks for drawings' current geometry data: + +void exampleHomeDrawingNetCallback(ArServerClient* client, ArNetPacket* requestPkt) { + ArNetPacket reply; + + // 7 Vertices + reply.byte4ToBuf(7); + + // Centered on 0,0. + // X: Y: + reply.byte4ToBuf(-500); reply.byte4ToBuf(500); // Vertex 1 + reply.byte4ToBuf(-500); reply.byte4ToBuf(-500); // Vertex 2 + reply.byte4ToBuf(500); reply.byte4ToBuf(-500); // Vertex 3 + reply.byte4ToBuf(500); reply.byte4ToBuf(500); // Vertex 4 + reply.byte4ToBuf(0); reply.byte4ToBuf(1000); // Vertex 5 + reply.byte4ToBuf(-500); reply.byte4ToBuf(500); // Vertex 6 + reply.byte4ToBuf(500); reply.byte4ToBuf(500); // Vertex 7 + + client->sendPacketUdp(&reply); +} + +void exampleDotsDrawingNetCallback(ArServerClient* client, ArNetPacket* requestPkt) { + ArNetPacket reply; + + unsigned int tik = ArUtil::getTime() % 200; + double t = tik / 5.0; + + // Three dots + reply.byte4ToBuf(3); + + // Dot 1: + reply.byte4ToBuf(3000); // X coordinate (mm) + reply.byte4ToBuf((int) (sin(t) * 1000));// Y + + // Dot 2: + reply.byte4ToBuf(3500); // X + reply.byte4ToBuf((int) (sin(t+500) * 1000));// Y + + // Dot 3: + reply.byte4ToBuf(4000); // X + reply.byte4ToBuf((int) (sin(t+1000) * 1000));// Y + + client->sendPacketUdp(&reply); +} + +void exampleXDrawingNetCallback(ArServerClient* client, ArNetPacket* requestPkt) { + ArNetPacket reply; + + // X marks the spot. 2 line segments, so 4 vertices: + reply.byte4ToBuf(4); + + // Segment 1: + reply.byte4ToBuf(-4250); // X1 + reply.byte4ToBuf(250); // Y1 + reply.byte4ToBuf(-3750); // X2 + reply.byte4ToBuf(-250); // Y2 + + // Segment 2: + reply.byte4ToBuf(-4250); // X1 + reply.byte4ToBuf(-250); // Y1 + reply.byte4ToBuf(-3750); // X2 + reply.byte4ToBuf(250); // Y2 + + client->sendPacketUdp(&reply); +} + +void exampleArrowsDrawingNetCallback(ArServerClient* client, ArNetPacket* requestPkt) { + // 1 Arrow that points at the robot + ArNetPacket reply; + reply.byte4ToBuf(1); + reply.byte4ToBuf(0); // Pos. X + reply.byte4ToBuf(700); // Pos. Y + client->sendPacketUdp(&reply); +} + diff --git a/Legacy/Aria/ArNetworking/examples/getVideoExample.cpp b/Legacy/Aria/ArNetworking/examples/getVideoExample.cpp new file mode 100644 index 0000000..e7e65f9 --- /dev/null +++ b/Legacy/Aria/ArNetworking/examples/getVideoExample.cpp @@ -0,0 +1,164 @@ +#include "Aria.h" +#include "ArNetworking.h" + +/** @example getVideoExample.cpp + * + * This example client requests video images from the server + * and saves them repeatedly to a file named "video.jpg", or + * to a series of files ("video1.jpg", "video2.jpg", etc.) if + * you give the -counter option. Give the image request rate + * in images per second with the -rate option (or use -1 to let + * the server decide when to send image; may not work with all servers). + * + * Connect to SAVserver, ACTS, or another video server to get + * images. + * + * To make a movie from the images, you can use ffmpeg on Linux. + * First run with frame rate and counter options to save multiple images: + * ./getVideoExample -host robothost -port 7272 -rate 20 -counter + * Then use ffmpeg: + * ffmpeg -i video%d.jpeg -r 20 movie.mpeg + * See ffmpeg -h for full list of options. + */ + + +bool useCounter = false; +unsigned long counter = 1; + +double rate = 0; +int rateAsTime = 0; + +void jpegHandler(ArNetPacket *packet) +{ + unsigned int width; + unsigned int height; + static unsigned char jpeg[50000]; + int jpegSize; + FILE *file; + + width = packet->bufToUByte2(); + height = packet->bufToUByte2(); + jpegSize = packet->getDataLength() - packet->getDataReadLength(); + if(jpegSize > 50000) + { + ArLog::log(ArLog::Normal, "Cannot save image, it's too big. (image is %d bytes, my buffer is 50000 bytes)", jpegSize); + return; + } + packet->bufToData((char *)jpeg, jpegSize); + char filename[128]; + char tmpFilename[128]; + sprintf(tmpFilename, "tmp.jpg"); + if ((file = ArUtil::fopen(tmpFilename, "wb")) != NULL) + { + fwrite(jpeg, jpegSize, 1, file); + fclose(file); + if(useCounter) + snprintf(filename, 64, "video%lu.jpg", counter++); + else + strcpy(filename, "video.jpg"); +#ifdef WIN32 + // On windows, rename() fails if the new file already exists + unlink(filename); +#endif + if (rename(tmpFilename, filename) == 0) + ArLog::log(ArLog::Normal, "Wrote a %dx%d image, %d bytes, named %s.", width, height, jpegSize, filename); + else + ArLog::log(ArLog::Normal, "Wrote a %dx%d image, %d bytes, named %s (could not rename to real name).", width, height, jpegSize, tmpFilename); + } + else + ArLog::log(ArLog::Normal, "Could not write temp file %s", tmpFilename); + + if (rate == 0 || rateAsTime == 0) + { + ArLog::log(ArLog::Normal, "Only one frame was requested, so exiting"); + Aria::exit(0); + } +} + +int main(int argc, char **argv) +{ + +#ifndef WIN32 + ArDaemonizer daemonizer(&argc, argv, false); + bool isDaemonized = false; + if (!daemonizer.daemonize()) + { + ArLog::log(ArLog::Terse, "Could not daemonize process"); + exit(1); + } + if (daemonizer.isDaemonized()) + isDaemonized = true; +#endif + + Aria::init(); + ArLog::init(ArLog::File, ArLog::Normal, "getVideoLog.txt", true, true, true); + + ArArgumentParser argParser(&argc, argv); + argParser.loadDefaultArguments(); + + ArClientSimpleConnector clientConnector(&argParser); + + if(argParser.checkParameterArgumentDouble("-rate", &rate) && rate != 0.0) + { + if(rate == -1) + rateAsTime = -1; + else + rateAsTime = ArMath::roundInt(1000.0 / rate); + } + + useCounter = argParser.checkArgument("-counter"); + + if(!Aria::parseArgs() || !argParser.checkHelpAndWarnUnparsed()) + { + Aria::logOptions(); + ArLog::log(ArLog::Terse, "\n\n%s options:\n-rate (If this isn't given, then the program will take one frame then exit, note that it is a double (so you can do .5 to do one frame per 2 seconds) and that if you set it to be too fast you'll saturate the robot's bandwidth and make it useless)\n-counter (default no)\n", argv[0]); + + ArLog::log(ArLog::Terse, "\n\nNotes:\nThis program saves the images as video.jpg if you aren't using a counter, or video.jpg if you are using the counter.\nIt puts its logs into getVideoLog.txt, and overwrites it whenever it runs\n"); + + return 1; + } + + + + ArClientBase client; + if (!clientConnector.connectClient(&client)) + { + ArLog::log(ArLog::Normal, "Could not connect to server, exiting\n"); + exit(1); + } + + ArGlobalFunctor1 jpegHandlerCB(&jpegHandler); + + if(client.dataExists("getPictureCam1")) + { + ArLog::log(ArLog::Normal, "Requesting images using \"getPictureCam1\" request."); + client.addHandler("getPictureCam1", &jpegHandlerCB); + if (rate != 0 && rateAsTime != 0) + client.request("getPictureCam1", rateAsTime); + else + client.requestOnce("getPictureCam1"); + } + else if(client.dataExists("sendVideo")) + { + ArLog::log(ArLog::Normal, "Server does not have \"getPictureCam1\" request, requesting images using old \"sendVideo\" request."); + client.addHandler("sendVideo", &jpegHandlerCB); + if (rate != 0 && rateAsTime != 0) + client.request("sendVideo", rateAsTime); + else + client.requestOnce("sendVideo"); + } + else + { + ArLog::log(ArLog::Terse, "Error: Server does not have \"getPictureCam1\" or \"sendVideo\" request, cannot request images."); + Aria::exit(2); + } + + + client.run(); + + Aria::shutdown(); + return 0; +} + + + diff --git a/Legacy/Aria/ArNetworking/examples/popupExample.cpp b/Legacy/Aria/ArNetworking/examples/popupExample.cpp new file mode 100644 index 0000000..fa8cc14 --- /dev/null +++ b/Legacy/Aria/ArNetworking/examples/popupExample.cpp @@ -0,0 +1,189 @@ + +#include "Aria.h" +#include "ArNetworking.h" + +/** @example popupExample.cpp Shows how to create popup windows in a client like MobileEyes + * + * This example server program connects to a robot, and sends a message to clients (e.g. MobileEyes) to display + * in a dialog box when a sensor reading is detected in front of the robot + * within 1 meter. It also checks to see if that obstacle is not at the same + * angle as the previous detected obstacle -- it's probably the same one, + * unmoved -- to avoid sending repeated popups. The popup offers three choices, + * acknowlege and do nothing, turn the robot around 180 degrees, or exit the server. + */ + + +class SensorDetectPopup +{ +public: + SensorDetectPopup(ArRobot *robot, ArServerHandlerPopup *popupServer); +protected: + ArRobot *myRobot; + ArServerHandlerPopup *myPopupServer; + bool myPopupDisplayed; + double myPrevObstacleAngle; + bool myPrevObstacleAngleValid; + ArFunctor2C *myPopupClosedCB; + + void popupClosed(ArTypes::Byte4 popupID, int button); + void sensorTask(void) ; +}; + + +int main(int argc, char **argv) +{ + Aria::init(); + ArRobot robot; + ArSonarDevice sonar; + ArSick sick; + robot.addRangeDevice(&sonar); + ArServerBase server; + + // Argument parser: + ArArgumentParser parser(&argc, argv); + parser.loadDefaultArguments(); + + // Connector and server opener: + ArRobotConnector robotConnector(&parser, &robot); + if(!robotConnector.connectRobot()) + { + ArLog::log(ArLog::Terse, "popupExample: Could not connect to the robot."); + if(parser.checkHelpAndWarnUnparsed()) + { + Aria::logOptions(); + } + Aria::exit(1); + } + + ArLaserConnector laserConnector(&parser, &robot, &robotConnector); + + ArServerSimpleOpener simpleOpener(&parser); + + // Get command-line and other parameters + if(!Aria::parseArgs() || !parser.checkHelpAndWarnUnparsed()) + { + Aria::logOptions(); + Aria::exit(1); + } + + robot.runAsync(true); + + // connect to the laser + if(!laserConnector.connectLasers()) + { + ArLog::log(ArLog::Normal, "popupExample: Warning: Could not connect to lasers."); + } + + + // Open the server + if(!simpleOpener.open(&server)) + { + ArLog::log(ArLog::Terse, "popupExample: Error, could not open server."); + return 1; + } + server.runAsync(); + ArLog::log(ArLog::Normal, "popupExample: Server running. Press control-C to exit."); + ArLog::log(ArLog::Normal, "popupExample: Each time an obstacle is detected near the robot, a new popup message will be created. Connect with MobileEyes to see them."); + + // Sends robot position etc. + ArServerInfoRobot robotInfoServer(&server, &robot); + + // This service sends drawings e.g. showing range device positions + ArServerInfoDrawings drawingsServer(&server); + drawingsServer.addRobotsRangeDevices(&robot); + + // This service can send messages to clients to display as popup dialogs: + ArServerHandlerPopup popupServer(&server); + + // This object contains the robot sensor interpretation task and creates + // popups: + SensorDetectPopup(&robot, &popupServer); + + robot.enableMotors(); + robot.waitForRunExit(); + + Aria::exit(0); +} + +SensorDetectPopup::SensorDetectPopup(ArRobot *robot, ArServerHandlerPopup *popupServer) : + myRobot(robot), + myPopupServer(popupServer), + myPopupDisplayed(false), + myPrevObstacleAngleValid(false) +{ + myRobot->lock(); + myRobot->addSensorInterpTask("sensorDetectPopup", 50, new ArFunctorC(this, &SensorDetectPopup::sensorTask)); + myPopupClosedCB = new ArFunctor2C(this, &SensorDetectPopup::popupClosed); + myRobot->unlock(); +} + +void SensorDetectPopup::sensorTask(void) +{ + // Basic obstacle detection + + if (myPopupDisplayed) return; + double detectAngle, detectRange; + detectRange = myRobot->checkRangeDevicesCurrentPolar(-90, 90, &detectAngle); + if (detectRange > 0 && detectRange <= 500) + { + if(myPrevObstacleAngleValid && fabs(detectAngle - myPrevObstacleAngle) < 0.0001) + return; + ArLog::log(ArLog::Normal, "popupExample: New obstacle detected at range %f, angle %f. Displaying popup dialog on client...", detectRange, detectAngle); + + ArServerHandlerPopupInfo info("popupExample", // ID + "Object Detected", // Title + "A range sensor detected a reading within 0.5 meters of the robot.", // Message + ArServerHandlerPopup::INFORMATION, // Type + 0, // Default button + 0, // Cancel/escape button + 5, // Timeout (sec.) + NULL, // Timeout String + "OK", "Acknowleged.", // Button 0 Label/Acknowlegement + "Turn Around", "Requested rotate...", // Button 1 Label/Acknowlegement + "Shut Down", "Shutting down server..." // Button 2 Label/Acknowlegement + ); + int id = myPopupServer->createPopup(&info, myPopupClosedCB); + ArLog::log(ArLog::Normal, "\t...Created a popup with ID=%d", id); + myPopupDisplayed = true; + myPrevObstacleAngle = detectAngle; + myPrevObstacleAngleValid = true; + } +} + +void SensorDetectPopup::popupClosed(ArTypes::Byte4 popupID, int button) +{ + // A client closed the popup + ArLog::log(ArLog::Normal, "popupExample: a client closed popup dialog window with id=%d. Button=%d...", popupID, button); + myPopupDisplayed = false; + + if(button < 0) + { + ArLog::log(ArLog::Normal, "\t...popup timed out or closed due to an error."); + return; + } + + if (button == 0) + { + ArLog::log(ArLog::Normal, "\t...OK pressed."); + return; + } + + if(button == 1) + { + ArLog::log(ArLog::Normal, "\t...180 degree rotate requested."); + myRobot->lock(); + myRobot->setDeltaHeading(180); + myRobot->unlock(); + return; + } + + if(button == 2) + { + ArLog::log(ArLog::Normal, "\t...exit requested."); + myRobot->stopRunning(); + Aria::shutdown(); + Aria::exit(0); + } +} + + diff --git a/Legacy/Aria/ArNetworking/examples/ptzCameraClientExample.cpp b/Legacy/Aria/ArNetworking/examples/ptzCameraClientExample.cpp new file mode 100644 index 0000000..54937b7 --- /dev/null +++ b/Legacy/Aria/ArNetworking/examples/ptzCameraClientExample.cpp @@ -0,0 +1,334 @@ +#include "Aria.h" +#include "ArNetworking.h" +#include + + +/** @example ptzCameraClientExample.cpp Example client showing how to control a Pan/Tilt/Zoom + * camera remotely. + * + * To use, serverDemo, arnlServer from ARNL, sonarnlServer from SONARNL, or + * your own server program that includes an ArServerHandlerCamera object. + * Then from another host, run ptzCameraClientExample with the -host argument. + * For example, if the hostname of the robot's onboard computer is "robot", run: + * ptzCameraClientExample -host robot + * Or use an IP address, for example, if the address is 10.0.126.32: + * ptzCameraClientExample -host 10.0.126.32 + * + * This program connects to the server, gets a list of cameras if neccesary, and + * for each camera on the robot, it receives and prints out one information + * packet, then a continuous stream of data packets, and then sends requests + * to cycle through each of its pan and tilt limits. + * + * This program does not get any video images from the server. To do so, use + * a video server (e.g. SAV server or ACTS), and see getVideoExample for an + * example client. + */ + + +/** A request packet that is able to send a copy of itself, with data packed in, + * to a server. + */ +class ArNetCameraRequest : public ArNetPacket +{ + ArClientBase *myClient; + std::string myAbsReqName; +public: + ArNetCameraRequest(ArClientBase *client, const char *cameraName = "") : myClient(client), myAbsReqName(std::string("setCameraAbs")+cameraName) + {} + void setCameraName(const char *name) { + myAbsReqName = std::string("setCameraAbs") + name; + } + bool requestPanTiltZoomAbs(double pan, double tilt, double zoom); + bool requestPanTiltAbs(double pan, double tilt); +}; + + +/** Includes callbacks for receiving info and data packets from a + * camera server and storing the values parsed from them. + */ +class ArClientHandlerCamera { +public: + std::string name; + std::string type; + std::string displayName; + std::string displayType; + double minPan, maxPan, minTilt, maxTilt, minZoom, maxZoom; + bool haveZoom; + double pan, tilt, zoom; + + void handleCameraInfoReply(ArNetPacket *packet); + void handleCameraDataReply(ArNetPacket *packet); + + ArClientBase *myClient; + ArNetCameraRequest request; + ArMutex myMutex; + + ArFunctor1C myCameraInfoReplyFunc; + ArFunctor1C myCameraDataReplyFunc; + + ArClientHandlerCamera(ArClientBase *client, const char *cameraName) : + name(cameraName), myClient(client), request(client, cameraName) , + myCameraInfoReplyFunc(this, &ArClientHandlerCamera::handleCameraInfoReply), + myCameraDataReplyFunc(this, &ArClientHandlerCamera::handleCameraDataReply) + { + myClient->addHandler((std::string("getCameraInfo")+name).c_str(), &myCameraInfoReplyFunc); + myClient->addHandler((std::string("getCameraData")+name).c_str(), &myCameraDataReplyFunc); + } + + void requestUpdates(int dataRequestFreq) { + myClient->request((std::string("getCameraInfo")+name).c_str(), -1); + myClient->request((std::string("getCameraData")+name).c_str(), 100); + } + + void lock() { myMutex.lock(); } + void unlock() { myMutex.unlock(); } +}; + + +/** Requests a list of cameras if neccesary, maintains a list of cameras, and implements example pan/tilt movements */ +class PtzCameraExample +{ + ArClientBase *myClient; + + std::set myCameras; + ArMutex mutex; + + ArFunctor1C myCameraListReplyFunc; + + void handleCameraListReply(ArNetPacket *packet); + + +public: + PtzCameraExample(ArClientBase *client) : + myClient(client), + myCameraListReplyFunc(this, &PtzCameraExample::handleCameraListReply) + { + } + + bool init(); + void run(); +}; + + + +int main(int argc, char **argv) +{ + Aria::init(); + ArClientBase client; + + ArArgumentParser parser(&argc, argv); + ArClientSimpleConnector clientConnector(&parser); + parser.loadDefaultArguments(); + if (!Aria::parseArgs() || !parser.checkHelpAndWarnUnparsed()) + { + Aria::logOptions(); + return 1; + } + + if (!clientConnector.connectClient(&client)) + { + if(client.wasRejected()) + ArLog::log(ArLog::Terse, "Error, server '%s' rejected connection. Exiting.", client.getHost()); + else + ArLog::log(ArLog::Terse, "Error, could not connect to server '%s'. Exiting.", client.getHost()); + return 2; + } + + client.setRobotName(client.getHost()); // include server hostname in log messages + + client.runAsync(); + + PtzCameraExample example(&client); + if(!example.init()) + return 1; + + example.run(); + + + Aria::shutdown(); + return 0; +} + + +bool PtzCameraExample::init() +{ + // If the server has the "getCameraList" request, then it's using + // ArServerHandlerCameraCollection, and migth have multiple PTZs/cameras each with + // its own set of requests. So send a "getCameraList" request, and when its + // reply is received, the handler will send "getCameraInfo" requests for each. + // If the server does not have "getCameraList", it only has one PTZ camera, just + // send "getCameraInfo". The handler for that will send various control + // commands. + // If the server does not have "getCameraInfo", then it doesn't provide any + // access to PTZ cameras. + if(myClient->dataExists("getCameraList")) + { + ArLog::log(ArLog::Normal, "Server may have multiple cameras. Requesting list."); + myClient->addHandler("getCameraList", &myCameraListReplyFunc); + myClient->requestOnce("getCameraList"); + } + else if(myClient->dataExists("getCameraInfo")) + { + ArLog::log(ArLog::Normal, "Server does not support multiple cameras. Requesting info for its camera."); + ArClientHandlerCamera *camClient = new ArClientHandlerCamera(myClient, ""); + camClient->requestUpdates(100); + mutex.lock(); + myCameras.insert(camClient); + mutex.unlock(); + } + else + { + ArLog::log(ArLog::Terse, "Error, server does not have any camera control requests. (Was the server run with video features enabled or video forwarding active?)"); + return false; + } + return true; +} + +void PtzCameraExample::handleCameraListReply(ArNetPacket *pkt) +{ + ArTypes::Byte2 numCams = pkt->bufToByte2(); + ArLog::log(ArLog::Normal, "%d cameras in list.", numCams); + char camName[128]; + char camType[128]; + char displayName[128]; + char displayType[128]; + char cmdDesc[128]; + char cmdName[128]; + ArTypes::Byte4 cmdFreq; + int dataReqFreq = 100; + for(ArTypes::Byte2 i = 0; i < numCams; ++i) + { + memset(camName, 0, 128); + memset(camType, 0, 128); + memset(displayName, 0, 128); + memset(displayType, 0, 128); + pkt->bufToStr(camName, 128); // name + + ArClientHandlerCamera *cam = new ArClientHandlerCamera(myClient, camName); + + pkt->bufToStr(camType, 128); // type + cam->type = camType; + pkt->bufToStr(displayName, 128); // description + cam->displayName = displayName; + pkt->bufToStr(displayType, 128); // description + cam->displayType = displayType; + ArTypes::Byte2 numCmds = pkt->bufToByte2(); + ArLog::log(ArLog::Normal, "%d commands for camera \'%s\' (%s) / \'%s\' (%s)", numCmds, camName, camType, displayName, displayType); + for(ArTypes::Byte2 c = 0; c < numCmds; ++c) + { + memset(cmdDesc, 0, 128); + memset(cmdName, 0, 128); + char cmdDesc[128]; + char cmdName[128]; + pkt->bufToStr(cmdDesc, 128); // description + pkt->bufToStr(cmdName, 128); // request name + cmdFreq = pkt->bufToByte4(); // recommended request frequency + ArLog::log(ArLog::Normal, "Camera %s has %s command named %s with recommended request frequency %d.", camName, cmdDesc, cmdName, cmdFreq); + + if(strcmp(cmdDesc, "getCameraData") == 0) + dataReqFreq = cmdFreq; + } + ArTypes::Byte2 numParams = pkt->bufToByte2(); + ArLog::log(ArLog::Normal, "Camera %s has %d parameters.", camName, numParams); + for(ArTypes::Byte2 p = 0; p < numParams; ++p) + { + ArClientArg carg; + ArConfigArg arg; + if(!carg.bufToArgValue(pkt, arg)) + ArLog::log(ArLog::Normal, "Hmm, error getting ArClientArg for camera %s's parameter #%d.", camName, p); + } + + cam->requestUpdates(dataReqFreq); + mutex.lock(); + myCameras.insert(cam); + mutex.unlock(); + } +} + +void ArClientHandlerCamera::handleCameraInfoReply(ArNetPacket *pkt) +{ + lock(); + minPan = pkt->bufToByte2() / 1000.0; + maxPan = pkt->bufToByte2() / 1000.0; + minTilt = pkt->bufToByte2() / 1000.0; + maxTilt = pkt->bufToByte2() / 1000.0; + minZoom = pkt->bufToByte2() / 1000.0; + maxZoom = pkt->bufToByte2() / 1000.0; + haveZoom = pkt->bufToByte(); + ArLog::log(ArLog::Normal, "Got getCameraInfo reply with pan range (%f, %f), tilt range (%f, %f), zoom range (%f, %f), zoom valid %d.", minPan, maxPan, minTilt, maxTilt, minZoom, maxZoom, haveZoom); + unlock(); +} + +void ArClientHandlerCamera::handleCameraDataReply(ArNetPacket *pkt) +{ + lock(); + pan = pkt->bufToByte2() / 1000.0; + tilt = pkt->bufToByte2() / 1000.0; + zoom = pkt->bufToByte2() /1000.0; + ArLog::log(ArLog::Normal, "Got camera data from camera %s with current pan=%f, tilt=%f, zoom=%f.", name.c_str(), pan, tilt, zoom); + unlock(); +} + +bool ArNetCameraRequest::requestPanTiltAbs(double pan, double tilt) +{ + empty(); + byte2ToBuf((ArTypes::Byte2)(pan * 1000.0)); + byte2ToBuf((ArTypes::Byte2)(tilt * 1000.0)); + finalizePacket(); + return myClient->requestOnce(myAbsReqName.c_str(), this); +} + +bool ArNetCameraRequest::requestPanTiltZoomAbs(double pan, double tilt, double zoom) +{ + empty(); + byte2ToBuf((ArTypes::Byte2)(pan * 1000.0)); + byte2ToBuf((ArTypes::Byte2)(tilt * 1000.0)); + byte2ToBuf((ArTypes::Byte2)(zoom * 1000.0)); + finalizePacket(); + return myClient->requestOnce(myAbsReqName.c_str(), this); +} + + +void PtzCameraExample::run() +{ + enum { MinPan, MaxPan, Center1, MinTilt, MaxTilt, Center2} stage; + stage = MinPan; + while(myClient->isConnected()) + { + mutex.lock(); + for(std::set::const_iterator i = myCameras.begin(); i != myCameras.end(); ++i) + { + ArClientHandlerCamera* c = (*i); + c->lock(); + switch(stage) + { + case MinPan: + c->request.requestPanTiltAbs(c->minPan, 0); + stage = MaxPan; + break; + case MaxPan: + c->request.requestPanTiltAbs(c->maxPan, 0); + stage = Center1; + break; + case Center1: + c->request.requestPanTiltAbs(0, 0); + stage = MinTilt; + break; + case MinTilt: + c->request.requestPanTiltAbs(0, c->minTilt); + stage = MaxTilt; + break; + case MaxTilt: + c->request.requestPanTiltAbs(0, c->maxTilt); + stage = Center2; + break; + case Center2: + c->request.requestPanTiltAbs(0, 0); + stage = MinPan; + } + c->unlock(); + } + mutex.unlock(); + ArUtil::sleep(3000); + } +} diff --git a/Legacy/Aria/ArNetworking/examples/serverDemo-vc2003.vcproj b/Legacy/Aria/ArNetworking/examples/serverDemo-vc2003.vcproj new file mode 100644 index 0000000..9cb5df0 --- /dev/null +++ b/Legacy/Aria/ArNetworking/examples/serverDemo-vc2003.vcproj @@ -0,0 +1,180 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/ArNetworking/examples/serverDemo-vc2008.vcproj b/Legacy/Aria/ArNetworking/examples/serverDemo-vc2008.vcproj new file mode 100644 index 0000000..bb5f55b --- /dev/null +++ b/Legacy/Aria/ArNetworking/examples/serverDemo-vc2008.vcproj @@ -0,0 +1,247 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/ArNetworking/examples/serverDemo-vc2010.vcxproj b/Legacy/Aria/ArNetworking/examples/serverDemo-vc2010.vcxproj new file mode 100644 index 0000000..4568514 --- /dev/null +++ b/Legacy/Aria/ArNetworking/examples/serverDemo-vc2010.vcxproj @@ -0,0 +1,152 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + serverDemo + {B9C37E51-E357-4019-B4B5-71C42E1FCD11} + + + + Application + false + MultiByte + + + Application + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + ../../bin/ + ../../obj/$(ProjectName)-$(Configuration)-VC10/ + false + ../../bin/ + ../../obj/$(ProjectName)-$(Configuration)-VC10/ + false + serverDemoDebug + $(ProjectName) + + + + $(IntDir)$(ProjectName)BuildLog.htm + + + .\../../bin/serverDemo.tlb + + + + + Disabled + ..\include;..\..\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + false + Default + MultiThreadedDebugDLL + false + false + true + true + Level3 + true + ProgramDatabase + Default + true + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + AriaDebugVC10.lib;ArNetworkingDebugVC10.lib + $(OutDir)$(TargetFileName) + 1.0 + true + ..\..\lib;%(AdditionalLibraryDirectories) + true + Console + false + + + MachineX86 + + + + + $(IntDir)$(ProjectName)BuildLog.htm + + + .\../../bin/serverDemo.tlb + + + + + MaxSpeed + OnlyExplicitInline + ..\include;..\..\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + false + Default + MultiThreadedDLL + false + false + true + Level3 + true + Default + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + AriaVC10.lib;ArNetworkingVC10.lib + $(OutDir)$(TargetFileName) + 1.0 + true + ..\..\lib;%(AdditionalLibraryDirectories) + Console + false + + + MachineX86 + + + + + Disabled + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + EnableFastChecks + true + MaxSpeed + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + + + + \ No newline at end of file diff --git a/Legacy/Aria/ArNetworking/examples/serverDemo.cpp b/Legacy/Aria/ArNetworking/examples/serverDemo.cpp new file mode 100644 index 0000000..150ca87 --- /dev/null +++ b/Legacy/Aria/ArNetworking/examples/serverDemo.cpp @@ -0,0 +1,257 @@ +#include "Aria.h" +#include "ArNetworking.h" + +/** @example serverDemo.cpp Example ArNetworking server providing teleoperation, + * sonar data, control the camera, etc. + * + * This is a basic ArNetworking server. It connects to a robot or simulator, + * including, if available, IRs, gyro, and bumpers. Give the option + * "-connectLaser" on the command line to enable the laser rangefinder, + * if available. + * + * Run "./serverDemo -help" for a full list of command line options. + * + * Once running, connect to this server with a a client such as + * MobileEyes. + * + * This server provides the following services: + * - User login (optional) + * - Basic robot telemetry information + * - Range sensor data values (not used by MobileEyes) + * - Graphics representing range sensor reading positions + * - Teleoperation modes (including safe/unsafe drive modes) + * - Wander mode + * - Various advanced "custom" commands to control logging, debugging, etc. + * - If an ACTS or SAV server is running, forward the video stream + * - Camera control (pan/tilt/zoom) if cameras are available + * + * Note that this program requires a terminal to run -- i.e. you can't run + * it in the background in Linux. To modify it to allow that, remove the key + * handler code in main(). + */ + +int main(int argc, char **argv) +{ + // mandatory init + Aria::init(); + + //ArLog::init(ArLog::StdOut, ArLog::Verbose); + + // set up our parser + ArArgumentParser parser(&argc, argv); + + // load the default arguments + parser.loadDefaultArguments(); + + // robot + ArRobot robot; + // set up our simple connector + ArRobotConnector robotConnector(&parser, &robot); + + + // add a gyro, it'll see if it should attach to the robot or not + ArAnalogGyro gyro(&robot); + + + // set up the robot for connecting + if (!robotConnector.connectRobot()) + { + printf("Could not connect to robot... exiting\n"); + Aria::exit(1); + } + + ArDataLogger dataLogger(&robot, "dataLog.txt"); + dataLogger.addToConfig(Aria::getConfig()); + + // our base server object + ArServerBase server; + + ArLaserConnector laserConnector(&parser, &robot, &robotConnector); + ArServerSimpleOpener simpleOpener(&parser); + + + ArClientSwitchManager clientSwitchManager(&server, &parser); + + // parse the command line... fail and print the help if the parsing fails + // or if the help was requested + if (!Aria::parseArgs() || !parser.checkHelpAndWarnUnparsed()) + { + Aria::logOptions(); + Aria::exit(1); + } + + // Set up where we'll look for files such as user/password + char fileDir[1024]; + ArUtil::addDirectories(fileDir, sizeof(fileDir), Aria::getDirectory(), + "ArNetworking/examples"); + + // first open the server up + if (!simpleOpener.open(&server, fileDir, 240)) + { + if (simpleOpener.wasUserFileBad()) + printf("Bad user/password/permissions file\n"); + else + printf("Could not open server port\n"); + exit(1); + } + + // Range devices: + + + ArSonarDevice sonarDev; + robot.addRangeDevice(&sonarDev); + + ArIRs irs; + robot.addRangeDevice(&irs); + + ArBumpers bumpers; + robot.addRangeDevice(&bumpers); + + // attach services to the server + ArServerInfoRobot serverInfoRobot(&server, &robot); + ArServerInfoSensor serverInfoSensor(&server, &robot); + ArServerInfoDrawings drawings(&server); + + // modes for controlling robot movement + ArServerModeStop modeStop(&server, &robot); + ArServerModeRatioDrive modeRatioDrive(&server, &robot); + ArServerModeWander modeWander(&server, &robot); + modeStop.addAsDefaultMode(); + modeStop.activate(); + + // set up the simple commands + ArServerHandlerCommands commands(&server); + ArServerSimpleComUC uCCommands(&commands, &robot); // send commands directly to microcontroller + ArServerSimpleComMovementLogging loggingCommands(&commands, &robot); // control debug logging + ArServerSimpleComGyro gyroCommands(&commands, &robot, &gyro); // configure gyro + ArServerSimpleComLogRobotConfig configCommands(&commands, &robot); // control more debug logging + ArServerSimpleServerCommands serverCommands(&commands, &server); // control ArNetworking debug logging + ArServerSimpleLogRobotDebugPackets logRobotDebugPackets(&commands, &robot, "."); // debugging tool + + // ArServerModeDrive is an older drive mode. ArServerModeRatioDrive is newer and generally performs better, + // but you can use this for old clients if neccesary. + //ArServerModeDrive modeDrive(&server, &robot); + //modeDrive.addControlCommands(&commands); // configure the drive modes (e.g. enable/disable safe drive) + + ArServerHandlerConfig serverHandlerConfig(&server, Aria::getConfig()); // make a config handler + ArLog::addToConfig(Aria::getConfig()); // let people configure logging + + modeRatioDrive.addToConfig(Aria::getConfig(), "Teleop settings"); // able to configure teleop settings + modeRatioDrive.addControlCommands(&commands); + + // Forward video if either ACTS or SAV server are running. + // You can find out more about SAV and ACTS on our website + // http://robots.activmedia.com. ACTS is for color tracking and is + // a separate product. SAV just does software A/V transmitting and is + // free to all our customers. Just run ACTS or SAV server before you + // start this program and this class here will forward video from the + // server to the client. + ArHybridForwarderVideo videoForwarder(&server, "localhost", 7070); + + // Control a pan/tilt/zoom camera, if one is installed, and the video + // forwarder was enabled above. + ArPTZ *camera = NULL; + ArServerHandlerCamera *handlerCamera = NULL; + ArCameraCollection *cameraCollection = NULL; + if (videoForwarder.isForwardingVideo()) + { + bool invertedCamera = false; + camera = new ArVCC4(&robot, invertedCamera, + ArVCC4::COMM_UNKNOWN, true, true); + camera->init(); + + cameraCollection = new ArCameraCollection(); + cameraCollection->addCamera("Cam1", "VCC4", "Camera", "VCC4"); + handlerCamera = new ArServerHandlerCamera("Cam1", + &server, + &robot, + camera, + cameraCollection); + } + + // You can use this class to send a set of arbitrary strings + // for MobileEyes to display, this is just a small example + ArServerInfoStrings stringInfo(&server); + Aria::getInfoGroup()->addAddStringCallback(stringInfo.getAddStringFunctor()); + Aria::getInfoGroup()->addStringInt( + "Motor Packet Count", 10, + new ArConstRetFunctorC(&robot, + &ArRobot::getMotorPacCount)); + /* + Aria::getInfoGroup()->addStringInt( + "Laser Packet Count", 10, + new ArRetFunctorC(&sick, + &ArSick::getSickPacCount)); + */ + + // start the robot running, true means that if we lose connection the run thread stops + robot.runAsync(true); + + + // connect the laser(s) if it was requested + if (!laserConnector.connectLasers()) + { + printf("Could not connect to lasers... exiting\n"); + Aria::exit(2); + } + + + drawings.addRobotsRangeDevices(&robot); + + // log whatever we wanted to before the runAsync + simpleOpener.checkAndLog(); + // now let it spin off in its own thread + server.runAsync(); + + printf("Server is now running...\n"); + + // Add a key handler so that you can exit by pressing + // escape. Note that a key handler prevents you from running + // a program in the background on Linux, since it expects an + // active terminal to read keys from; remove this if you want + // to run it in the background. + ArKeyHandler *keyHandler; + if ((keyHandler = Aria::getKeyHandler()) == NULL) + { + keyHandler = new ArKeyHandler; + Aria::setKeyHandler(keyHandler); + robot.lock(); + robot.attachKeyHandler(keyHandler); + robot.unlock(); + printf("To exit, press escape.\n"); + } + + // Read in parameter files. + std::string configFile = "serverDemoConfig.txt"; + Aria::getConfig()->setBaseDirectory("./"); + if (Aria::getConfig()->parseFile(configFile.c_str(), true, true)) + { + ArLog::log(ArLog::Normal, "Loaded config file %s", configFile.c_str()); + } + else + { + if (ArUtil::findFile(configFile.c_str())) + { + ArLog::log(ArLog::Normal, + "Trouble loading configuration file %s, continuing", + configFile.c_str()); + } + else + { + ArLog::log(ArLog::Normal, + "No configuration file %s, will try to create if config used", + configFile.c_str()); + } + } + + clientSwitchManager.runAsync(); + + robot.lock(); + robot.enableMotors(); + robot.unlock(); + + robot.waitForRunExit(); + Aria::exit(0); +} + + diff --git a/Legacy/Aria/ArNetworking/examples/serverDemo.userInfo b/Legacy/Aria/ArNetworking/examples/serverDemo.userInfo new file mode 100644 index 0000000..b36409f --- /dev/null +++ b/Legacy/Aria/ArNetworking/examples/serverDemo.userInfo @@ -0,0 +1,8 @@ +; You'll want to change the . below to the actual password you want +; used for the different accounts, also note you can start up serverDemo +; with this information by giving it the '-userInfo ' +; argument on the command line +UserInfoVersion1 +user user . CustomCommands Movement RobotInfo SensorInfo Stop UnsafeMovement +user guest . CustomCommands Movement RobotInfo SensorInfo Stop UnsafeMovement +user administrator . all diff --git a/Legacy/Aria/ArNetworking/examples/serverDemoStatic-vc2003.vcproj b/Legacy/Aria/ArNetworking/examples/serverDemoStatic-vc2003.vcproj new file mode 100644 index 0000000..ec45845 --- /dev/null +++ b/Legacy/Aria/ArNetworking/examples/serverDemoStatic-vc2003.vcproj @@ -0,0 +1,138 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/ArNetworking/examples/serverDemoStatic-vc2008.vcproj b/Legacy/Aria/ArNetworking/examples/serverDemoStatic-vc2008.vcproj new file mode 100644 index 0000000..2446a63 --- /dev/null +++ b/Legacy/Aria/ArNetworking/examples/serverDemoStatic-vc2008.vcproj @@ -0,0 +1,213 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/ArNetworking/examples/serverDemoStatic-vc2010.vcxproj b/Legacy/Aria/ArNetworking/examples/serverDemoStatic-vc2010.vcxproj new file mode 100644 index 0000000..cc93bf5 --- /dev/null +++ b/Legacy/Aria/ArNetworking/examples/serverDemoStatic-vc2010.vcxproj @@ -0,0 +1,143 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + serverDemoStatic + {EEF9FE4C-34C4-4C76-94C4-D11930C88DE1} + serverDemoStatic + ManagedCProj + + + + Application + MultiByte + false + v100 + + + Application + MultiByte + false + v100 + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + ..\..\bin\ + ../../obj/$(ProjectName)-$(Configuration)-VC10/ + true + ..\..\bin\ + ../../obj/$(ProjectName)-$(Configuration)-VC10/ + false + serverDemoStaticDebug + $(ProjectName) + + + + $(IntDir)$(ProjectName)BuildLog.htm + + + Disabled + ..\..\include;..\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;ARIA_STATIC;%(PreprocessorDefinitions) + false + Default + MultiThreadedDebug + false + + + Level3 + ProgramDatabase + true + + + false + + + AriaStaticDebugVC10.lib;ws2_32.lib;winmm.lib;advapi32.lib;ArNetworkingStaticDebugVC10.lib + $(OutDir)$(TargetFileName) + true + ..\..\lib;%(AdditionalLibraryDirectories) + %(IgnoreSpecificDefaultLibraries) + true + true + false + + + NotSet + + + + + $(IntDir)$(ProjectName)BuildLog.htm + + + AnySuitable + true + ..\..\include;..\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;ARIA_STATIC;%(PreprocessorDefinitions) + false + MultiThreaded + false + true + NotUsing + Level3 + ProgramDatabase + true + + + AriaStaticVC10.lib;ArNetworkingStaticVC10.lib;winmm.lib;ws2_32.lib;%(AdditionalDependencies) + $(OutDir)$(TargetFileName) + true + ..\..\lib;%(AdditionalLibraryDirectories) + %(IgnoreSpecificDefaultLibraries) + false + false + + + + + NotSet + + + + + true + true + + + true + true + + + true + true + + + + + + + + + \ No newline at end of file diff --git a/Legacy/Aria/ArNetworking/examples/simpleServerExample.cpp b/Legacy/Aria/ArNetworking/examples/simpleServerExample.cpp new file mode 100644 index 0000000..0d0f911 --- /dev/null +++ b/Legacy/Aria/ArNetworking/examples/simpleServerExample.cpp @@ -0,0 +1,129 @@ +#include "Aria.h" +#include "ArNetworking.h" + + +/** @example simpleServerExample.cpp This is a simple example of an ArNetworking server. + * This server provides range sensor data to the client, and teleoperation + * controls. It also includes an example of a custom command (using + * ArServerHandlerCommands). + * + * For a more complete server, see serverDemo.cpp. + */ + + +/* This function is called ArServerHandlerCommands when our custom command is + * recieved. */ +void customCommandHandler(ArArgumentBuilder *args) +{ + if(args && args->getArg(0)) + ArLog::log(ArLog::Normal, "Recieved custom command with argument \"%s\".", args->getArg(0)); + else + ArLog::log(ArLog::Normal, "Recieved custom command with no arguments."); +} + + +int main(int argc, char **argv) +{ + Aria::init(); + ArRobot robot; + ArArgumentParser parser(&argc, argv); + ArSimpleConnector simpleConnector(&parser); + + // The base server object, manages all connections to clients. + ArServerBase server; + + // This object simplifies configuration and opening of the ArServerBase + // object. + ArServerSimpleOpener simpleOpener(&parser); + + // parse the command line. fail and print the help if the parsing fails + // or if the help was requested with -help + parser.loadDefaultArguments(); + if (!simpleConnector.parseArgs() || !simpleOpener.parseArgs() || + !parser.checkHelpAndWarnUnparsed()) + { + simpleConnector.logOptions(); + simpleOpener.logOptions(); + exit(1); + } + + // Use the ArSimpleOpener to open the server port + if (!simpleOpener.open(&server)) + { + ArLog::log(ArLog::Terse, "Error: Could not open server on port %d", simpleOpener.getPort()); + exit(1); + } + + + // + // Create services attached to the base server: + // + + // Robot position etc.: + ArServerInfoRobot serverInfoRobot(&server, &robot); + + // Robot control modes (only one mode can be active at once): + ArServerModeStop modeStop(&server, &robot); + // old ArServerModeDrive modeDrive(&server, &robot); + ArServerModeRatioDrive modeRatioDrive(&server, &robot); + ArServerModeWander modeWander(&server, &robot); + modeStop.addAsDefaultMode(); + modeStop.activate(); + + // This provides a simple way to add new commands. + ArServerHandlerCommands commands(&server); + + // Add our custom command. ArServerHandlerCommands also has other methods + // for adding commands taht take different kinds of arguments, or no + // arguments. + ArGlobalFunctor1 customCommandFunctor(&customCommandHandler); + commands.addStringCommand("ExampleCustomCommand", "Example of a custom command. simpleServerExample will print out the text sent with the command.", &customCommandFunctor); + + // These objects provide various debugging and diagnostic custom commands: + ArServerSimpleComUC uCCommands(&commands, &robot); // Get information about the robot + ArServerSimpleComMovementLogging loggingCommands(&commands, &robot); // Control logging + modeRatioDrive.addControlCommands(&commands); // Drive mode diagnostics + + // This provides the client (e.g. MobileEyes) with a simple table of string values + // (called an InfoGroup). An InfoGroup is kept globally by Aria. + // The values in the table sent to clients are retrieved periodically by calling a + // functor. + ArServerInfoStrings stringInfo(&server); + Aria::getInfoGroup()->addAddStringCallback(stringInfo.getAddStringFunctor()); + + // Here are some example entries in the InfoGroup: + Aria::getInfoGroup()->addStringInt( + "Motor Packet Count", 10, + new ArConstRetFunctorC(&robot, + &ArRobot::getMotorPacCount)); + + // + // Connect to the robot: + // + + if (!simpleConnector.connectRobot(&robot)) + { + printf("Error: Could not connect to robot... exiting\n"); + Aria::shutdown(); + return 1; + } + + + robot.enableMotors(); + robot.runAsync(true); + + // The simple opener might have information to display right before starting + // the server thread: + simpleOpener.checkAndLog(); + + // now let the server base run in a new thread, accepting client connections. + server.runAsync(); + + ArLog::log(ArLog::Normal, "Server is now running... Press Ctrl-C to exit."); + + robot.waitForRunExit(); + Aria::shutdown(); + exit(0); +} + + diff --git a/Legacy/Aria/ArNetworking/include/ArCentralForwarder.h b/Legacy/Aria/ArNetworking/include/ArCentralForwarder.h new file mode 100644 index 0000000..d62f62b --- /dev/null +++ b/Legacy/Aria/ArNetworking/include/ArCentralForwarder.h @@ -0,0 +1,168 @@ +#ifndef ARCENTRALFORWARDER_H +#define ARCENTRALFORWARDER_H + +#include "Aria.h" +#include "ArServerBase.h" +#include "ArClientBase.h" + +/** + Class for forwarding... You sould use the commands on this instead + of the ones on the server and client it holds. + + requestStop is missing since that'd only cause problems. + + request doesn't take a packet since that'd cause problems with the + proxying, other than that everything should be like the client. + + Talk to MattL if there's questions. +**/ +class ArCentralForwarder +{ +public: + AREXPORT ArCentralForwarder( + ArServerBase *mainServer, ArSocket *socket, + const char *robotName, int startingPort, + std::map *usedPorts, + ArFunctor2 *notifyServerClientRemovedCB, + const char *enforceProtocolVersion, + ArServerCommands::Type enforceType + ); + AREXPORT ~ArCentralForwarder(); + + /// Gets the robot name + const char *getRobotName(void) { return myRobotName.c_str(); } + + /// Adds a functor for some particular data + AREXPORT bool addHandler(const char *name, + ArFunctor1 *functor); + + /// Removes a functor for some particular data by name + AREXPORT bool remHandler(const char *name, ArFunctor1 *functor); + + /// Request some data every @a mSec milliseconds + AREXPORT bool request(const char *name, long mSec); + + /// Request some data (or send a command) just once + AREXPORT bool requestOnce(const char *name, + ArNetPacket *packet = NULL, + bool quiet = false); + + /// Request some data (or send a command) just once by UDP + AREXPORT bool requestOnceUdp(const char *name, + ArNetPacket *packet = NULL, + bool quiet = false); + + /// Request some data (or send a command) just once with a string as argument + AREXPORT bool requestOnceWithString(const char *name, const char *str); + + /// Sees if this data exists + AREXPORT bool dataExists(const char *name); + + + + /// Gets the server (shouldn't need to be used by anyone) + ArServerBase *getServer(void) { return myServer; } + /// Gets the client (shouldn't need to be used by anyone) + ArClientBase *getClient(void) { return myClient; } + /// Gets the port (shouldn't need to be used by anyone) + int getPort(void) { return myPort; } + AREXPORT bool callOnce( + double heartbeatTimeout, double udpHeartbeatTimeout, + double robotBackupTimeout, double clientBackupTimeout); + AREXPORT bool isConnected(void) { return myState == STATE_CONNECTED; } + AREXPORT void willReplace(void) { myBeingReplaced = true; } +protected: + AREXPORT void netCentralHeartbeat(ArNetPacket *packet); + + void robotServerClientRemoved(ArServerClient *client); + void clientServerClientRemoved(ArServerClient *client); + void receiveData(ArNetPacket *packet); + void internalRequestChanged(long interval, unsigned int command); + bool internalRequestOnce(ArServerClient *client, ArNetPacket *packet, + bool tcp); + + AREXPORT bool startingCallOnce( + double heartbeatTimeout, double udpHeartbeatTimeout, + double robotBackupTimeout, double clientBackupTimeout); + AREXPORT bool connectingCallOnce( + double heartbeatTimeout, double udpHeartbeatTimeout, + double robotBackupTimeout, double clientBackupTimeout); + AREXPORT bool gatheringCallOnce( + double heartbeatTimeout, double udpHeartbeatTimeout, + double robotBackupTimeout, double clientBackupTimeout); + AREXPORT bool connectedCallOnce( + double heartbeatTimeout, double udpHeartbeatTimeout, + double robotBackupTimeout, double clientBackupTimeout); + + std::string myEnforceProtocolVersion; + ArServerCommands::Type myEnforceType; + + ArServerBase *myMainServer; + ArSocket *mySocket; + std::string myRobotName; + std::string myPrefix; + int myStartingPort; + std::map *myUsedPorts; + ArFunctor2 *myForwarderServerClientRemovedCB; + + enum State + { + STATE_STARTING, + STATE_CONNECTING, + STATE_GATHERING, + STATE_CONNECTED + }; + bool myBeingReplaced; + + + ArServerBase *myServer; + ArClientBase *myClient; + State myState; + int myPort; + ArServerBase *server; + ArClientBase *client; + + bool myRobotHasCentralServerHeartbeat; + ArTime myLastSentCentralServerHeartbeat; + + enum ReturnType + { + RETURN_NONE, + RETURN_SINGLE, + RETURN_VIDEO, + RETURN_UNTIL_EMPTY, + RETURN_COMPLEX, + RETURN_VIDEO_OPTIM, + }; + + std::map myReturnTypes; + std::map *> myRequestOnces; + std::map myLastRequest; + std::map myLastBroadcast; + + ReturnType getReturnType(int command); + void checkRequestOnces(unsigned int command); + void setLastRequest(unsigned int command); + void setLastBroadcast(unsigned int command); + + ArTime myLastTcpHeartbeat; + ArTime myLastUdpHeartbeat; + + ArFunctor1C myReceiveDataFunctor; + ArFunctor2C myInternalRequestChangedFunctor; + ArRetFunctor3C myInternalRequestOnceFunctor; + ArFunctor1C myRobotServerClientRemovedCB; + ArFunctor1C myNetCentralHeartbeatCB; + ArFunctor1C myClientServerClientRemovedCB; + +}; + + +#endif // ARSERVERSWITCHFORWARDER diff --git a/Legacy/Aria/ArNetworking/include/ArCentralManager.h b/Legacy/Aria/ArNetworking/include/ArCentralManager.h new file mode 100644 index 0000000..2df9dfd --- /dev/null +++ b/Legacy/Aria/ArNetworking/include/ArCentralManager.h @@ -0,0 +1,88 @@ +#ifndef ARCENTRALMANAGER +#define ARCENTRALMANAGER + +#include "Aria.h" +#include "ArServerBase.h" +#include "ArCentralForwarder.h" + +class ArCentralManager : public ArASyncTask +{ +public: + /// Constructor + AREXPORT ArCentralManager(ArServerBase *robotServer, ArServerBase *clientServer); + /// Destructor + AREXPORT virtual ~ArCentralManager(); + /// Logs all the connection information + void logConnections(void); + /// Enforces that everything is using this protocol version + AREXPORT void enforceProtocolVersion(const char *protocolVersion); + /// Enforces that the robots that connect are this type + AREXPORT void enforceType(ArServerCommands::Type type); + /// Adds a callback for when a new forwarder is added + AREXPORT void addForwarderAddedCallback( + ArFunctor1 *functor, int priority = 0); + /// Removes a callback for when a new forwarder is added + AREXPORT void remForwarderAddedCallback( + ArFunctor1 *functor); + /// Adds a callback for when a new forwarder is destroyed + AREXPORT void addForwarderRemovedCallback( + ArFunctor1 *functor, int priority = 0); + /// Removes a callback for when a new forwarder is destroyed + AREXPORT void remForwarderRemovedCallback( + ArFunctor1 *functor); + /// Networking command to get the list of clients + AREXPORT void netClientList(ArServerClient *client, ArNetPacket *packet); + /// A callback so we can tell the main connection happened when a + /// client is removed + AREXPORT void forwarderServerClientRemovedCallback( + ArCentralForwarder *forwarder, ArServerClient *client); + /// A callback so we can close down other connetions when a main + /// client loses connection + AREXPORT void mainServerClientRemovedCallback(ArServerClient *client); + /// Networking command to switch the direction of a connection + AREXPORT void netServerSwitch(ArServerClient *client, ArNetPacket *packet); + AREXPORT virtual void *runThread(void *arg); +protected: + void close(void); + bool processFile(void); + + bool removePendingDuplicateConnections(const char *robotName); + + ArServerBase *myRobotServer; + ArServerBase *myClientServer; + double myHeartbeatTimeout; + double myUdpHeartbeatTimeout; + double myRobotBackupTimeout; + double myClientBackupTimeout; + + std::string myEnforceProtocolVersion; + ArServerCommands::Type myEnforceType; + + int myMostForwarders; + int myMostClients; + + ArTypes::UByte4 myClosingConnectionID; + std::list myClientSockets; + std::list myClientNames; + std::list myForwarders; + std::map myUsedPorts; + ArMutex myCallbackMutex; + std::multimap *> myForwarderAddedCBList; + std::multimap *> myForwarderRemovedCBList; + ArMutex myDataMutex; + int myOnSocket; + ArFunctor2C myNetSwitchCB; + ArFunctor2C myNetClientListCB; + ArFunctorC myAriaExitCB; + ArRetFunctorC myProcessFileCB; + ArFunctor2C myForwarderServerClientRemovedCB; + ArFunctor1C myMainServerClientRemovedCB; +}; + + +#endif // ARSERVERSWITCHMANAGER diff --git a/Legacy/Aria/ArNetworking/include/ArClientArgUtils.h b/Legacy/Aria/ArNetworking/include/ArClientArgUtils.h new file mode 100644 index 0000000..65607d5 --- /dev/null +++ b/Legacy/Aria/ArNetworking/include/ArClientArgUtils.h @@ -0,0 +1,170 @@ +/*! + * \brief Defines the ArClientArg class. + * \date 05/01/05 + * \author K. Cunningham + * +**/ +#ifndef ARCLIENTARGUTILS_H +#define ARCLIENTARGUTILS_H + +#include "Aria.h" + +class ArNetPacket; +class ArConfigArg; + +/// Small helper class for sending/receiving an ArConfigArg in an ArNetPacket. +/** + * ArClientArg defines methods for packing/unpacking an ArConfigArg into/from + * an ArNetPacket. (The name of the class is a slight misnomer since it may + * be used both on the server and client sides.) + *

+ * The structure of the network packet information is as follows: + *

+ *    string: arg.getName()
+ *    string: arg.getDescription()
+ *    byte: arg.getConfigPriority()
+ *    byte: arg type ('B' == BOOL | 'I' == INT | 'D' == DOUBLE | 'S' == STRING | 'L' == LIST)
+ *    <arg values>
+ *    string: arg.getDisplayHint()      -- only if isDisplayHintParsed is set to true
+ *    string: arg.getExtraExplanation() -- only if version >= 2
+ *    byte: arg.getRestartLevel()       -- only if version >= 2
+ * 
+ *    <arg values> varies by arg type:
+ *
+ *    if BOOL, then:
+ *        byte: arg.getBool()
+ *    if INT, then:
+ *	      byte4: arg.getInt()
+ *		    byte4: arg.getMinInt()
+ *		    byte4: arg.getMaxInt()
+ *    if DOUBLE, then:
+ *	      byte4: arg.getDouble()
+ *		    byte4: arg.getMinDouble()
+ *		    byte4: arg.getMaxDouble()
+ *        byte4: arg.getDoublePrecision()  -- only if version >= 2
+ *    if STRING, then:
+ *        string: arg.getString()
+ *    if LIST, then:
+ *        byte4: arg.getArgCount()
+ *        <list contents>
+ *        
+ *
+ *    
+ * 
+ *

+ * ArClientArg also defines methods to send an "abbreviated" ArConfigArg + * (i.e. just value). The short packet structure is as follows: + *

+ *    <arg value> varies by arg type:
+ *    if BOOL, then:
+ *        byte: arg.getBool()
+ *    if INT, then:
+ *	      byte4: arg.getInt()
+ *    if DOUBLE, then:
+ *	      byte4: arg.getDouble()
+ *    if STRING, then:
+ *        string: arg.getString()
+ *    if LIST, then:
+ *        
+ *        <list contents>
+ * 
+ * Lastly, it defines a method to send an "abbreviated" ArConfigArg in a + * text format. +**/ +class ArClientArg +{ +public: + + /// Constructor + AREXPORT ArClientArg(bool isDisplayHintParsed = false, + ArPriority::Priority lastPriority = ArPriority::LAST_PRIORITY, + int version = 1); + + /// Destructor + AREXPORT virtual ~ArClientArg(); + + /// Returns whether the given parameter can be sent in a network packet. + /** + * Currently, a parameter can only be sent if it is of type INT, DOUBLE, + * STRING, BOOL, LIST, or a SEPARATOR. + **/ + AREXPORT virtual bool isSendableParamType(const ArConfigArg &arg); + + /// Unpacks the given network packet and stores the data in the config arg. + /** + * @param packet the ArNetPacket * from which data is extracted + * @param argOut the ArConfigArg in which to set the data + * @return bool set to true if the data was successfully extracted from + * the packet; false if an error occurred and argOut is invalid + **/ + AREXPORT virtual bool createArg(ArNetPacket *packet, + ArConfigArg &argOut); + + + /// Stores the given config arg into the network packet. + /** + * @param arg the ArConfigArg from which to retrieve the data + * @param packet the ArNetPacket * to which data is added + * @return bool set to true if the data was successfully stored in + * the packet; false if an error occurred and the packet is invalid + **/ + AREXPORT virtual bool createPacket(const ArConfigArg &arg, + ArNetPacket *packet); + + + + /// Unpacks the abbreviated arg value and stores the data in the config arg. + /** + * @param packet the ArNetPacket * from which data is extracted + * @param arg the ArConfigArg in which to set the value + * @return bool set to true if the data was successfully extracted from + * the packet; false if an error occurred and arg is invalid + **/ + AREXPORT virtual bool bufToArgValue(ArNetPacket *packet, + ArConfigArg &arg); + + /// Stores the abbreviated arg value into the network packet. + /** + * @param arg the ArConfigArg from which to retrieve the data + * @param packet the ArNetPacket * to which data is added + * @return bool set to true if the data was successfully stored in + * the packet; false if an error occurred and the packet is invalid + **/ + AREXPORT virtual bool argValueToBuf(const ArConfigArg &arg, + ArNetPacket *packet); + + + + /// Stores the arg value into the network packet as a text string. + /** + * The stored text string is suitable for parsing by an ArArgumentBuilder. + * + * @param arg the ArConfigArg from which to retrieve the data + * @param packet the ArNetPacket * to which data is added + * @return bool set to true if the data was successfully stored in + * the packet; false if an error occurred and the packet is invalid + **/ + AREXPORT virtual bool argTextToBuf(const ArConfigArg &arg, + ArNetPacket *packet); + + + AREXPORT virtual bool addArgTextToPacket(const ArConfigArg &arg, + ArNetPacket *packet); + +protected: + + enum { + BUFFER_LENGTH = 1024 + }; + + bool myIsDisplayHintParsed; + ArPriority::Priority myLastPriority; + int myVersion; + + char myBuffer[BUFFER_LENGTH]; + char myDisplayBuffer[BUFFER_LENGTH]; + char myExtraBuffer[BUFFER_LENGTH]; + +}; // end class ArClientArgUtils + +#endif //ARCLIENTARGUTILS_H diff --git a/Legacy/Aria/ArNetworking/include/ArClientBase.h b/Legacy/Aria/ArNetworking/include/ArClientBase.h new file mode 100644 index 0000000..0981c4f --- /dev/null +++ b/Legacy/Aria/ArNetworking/include/ArClientBase.h @@ -0,0 +1,424 @@ +#ifndef NLCLIENTBASE_H +#define NLCLIENTBASE_H + +#include "Aria.h" +#include "ArClientCommands.h" +#include "ArServerCommands.h" +#include "ArNetPacket.h" +#include "ArNetPacketSenderTcp.h" +#include "ArNetPacketReceiverTcp.h" +#include "ArNetPacketReceiverUdp.h" +#include "ArClientData.h" + +/** + @brief The base client class + + You need to connect a client to a server using blockingConnect() with + the address for the server. Then you should add handlers to + the client to receive information from the server (with addHandler(), + request(), and requestOnce()). Then call run() or runAsync() + (or loopOnce() if you really know what you're doing). + You can also add a callback that will get called every cycle of the + client. + + User and password information may be required by the server. + For details on that see ArServerBase. The most important thing is + the modification to blockingConnect(), it can now take a user and + password argument and upon failure you'll want to check wasRejected() + to determine whether the client couldn't find the server or if the user and + password were rejected. Another relevant function is setServerKey() + to set the key (string of text) we need to connect to the server. + + This class should be thread safe... The only thing you cannot do is + call 'addHandler' or 'remHandler' from within a handler for that + specific piece of data. + **/ + +class ArClientBase : public ArASyncTask +{ +public: + + /// The state of the connection + enum ClientState { + STATE_NO_CONNECTION, ///< The client has not connected + STATE_FAILED_CONNECTION, ///< The client tried to connect and failed + STATE_OPENED_SOCKET, ///< Client opened socket, waiting for intro from srvr + STATE_EXCHANGED_INTROS, ///< Client and server have exchanged introductions + STATE_REJECTED, ///< Client was rejected by server + STATE_WAITING_LIST, ///< Client was connected to server, waiting for list + STATE_CONNECTED, ///< Client is connected to server + STATE_LOST_CONNECTION ///< Client lost connection to server + }; + + enum { + CLIENT_KEY_LENGTH = 16 + }; + + enum NonBlockingConnectReturn + { + NON_BLOCKING_CONTINUE, ///< Client didn't connect or fail to connect yet + NON_BLOCKING_CONNECTED, ///< Client connected + NON_BLOCKING_FAILED ///< Client couldn't connect + }; + + /// Constructor + AREXPORT ArClientBase(); + /// Destructor + AREXPORT virtual ~ArClientBase(); + + /// Sets the optional name of the connected robot for debugging purposes. + AREXPORT virtual void setRobotName(const char *name, + bool debugLogging = false, + int robotId = 0); + + /// Returns the optional name of the connected robot for debugging purposes. + AREXPORT virtual const char *getRobotName() const; + + /// Returns the entire string used to prefix log entries for this client base. + AREXPORT virtual const char *getLogPrefix() const; + + /// Returns if we're doing debug logging or not + AREXPORT bool getDebugLogging(void); + + /// Connect to a server + AREXPORT bool blockingConnect(const char *host, int port, bool log = true, + const char *user = NULL, + const char *password = NULL, + const char *openOnIP = NULL); + + /// Disconnect from a server + /** + * This method blocks while the connection is being shutdown. + **/ + AREXPORT bool disconnect(void); + + /// Disconnect from a server next time through the loop + /** + * This method does not block while the connection is being + * shutdown, and the disconnect only happens the next time the + * client base is in its loop + **/ + AREXPORT void disconnectSoon(void); + + /** @return true if we're connected to a server */ + AREXPORT bool isConnected(void) { return myState == STATE_CONNECTED;} + + /** @return true if a server connection attempt failed because the server rejected the username or password, false if the connection failed for another reason, or the username/password were accepted. */ + AREXPORT bool wasRejected(void) { return myState == STATE_REJECTED; } + + /// Gets the state of the client + AREXPORT ClientState getState(void) { return myState; } + + /// Adds a functor for some particular data + AREXPORT bool addHandler(const char *name, + ArFunctor1 *functor); + + /// Removes a functor for some particular data by name + AREXPORT bool remHandler(const char *name, ArFunctor1 *functor); + + /// Request some data every @a mSec milliseconds + AREXPORT bool request(const char *name, long mSec, + ArNetPacket *packet = NULL); + + /// Don't want this data anymore + AREXPORT bool requestStop(const char *name); + + /// Request some data (or send a command) just once + AREXPORT bool requestOnce(const char *name, + ArNetPacket *packet = NULL, + bool quiet = false); + + /// Request some data (or send a command) just once by UDP + AREXPORT bool requestOnceUdp(const char *name, + ArNetPacket *packet = NULL, + bool quiet = false); + + /// Request some data (or send a command) just once with a string as argument + AREXPORT bool requestOnceWithString(const char *name, const char *str); + + /// Sees if this data exists + AREXPORT bool dataExists(const char *name); + + /// Gets the name of the host we tried to connect to + AREXPORT const char *getHost(void); + + + /// Sets the 'key' needed to connect to the server + AREXPORT void setServerKey(const char *serverKey, bool log = true); + + /// Enforces the that the server is using this protocol version + AREXPORT void enforceProtocolVersion(const char *protocolVersion, + bool log = true); + + /// Enforces that the robots that connect are this type + AREXPORT void enforceType(ArServerCommands::Type type, bool log = true); + + /// Gets the last time a packet was received + AREXPORT ArTime getLastPacketReceived(void); + + /// Sets the backup timeout + AREXPORT void setBackupTimeout(double timeoutInMins); + + /// Runs the client in this thread + AREXPORT virtual void run(void); + + /// Runs the client in its own thread + AREXPORT virtual void runAsync(void); + + /// Stops the thread and sets the stopped flag + AREXPORT virtual void stopRunning(void); + + /// Returns whether the client has been stopped (regardless of whether its in its own thread) + AREXPORT virtual bool isStopped(); + + /// Print out or data with descriptions + AREXPORT void logDataList(void); + + /// Adds a functor to call every cycle + AREXPORT void addCycleCallback(ArFunctor *functor); + + /// Removes a functor called every cycle + AREXPORT void remCycleCallback(ArFunctor *functor); + + /// Send a packet over TCP + AREXPORT bool sendPacketTcp(ArNetPacket *packet); + /// Send a packet over UDP (unless client only wants tcp then sends over tcp) + AREXPORT bool sendPacketUdp(ArNetPacket *packet); + + /// Sets the time to allow for connection (default 3) + AREXPORT void setConnectTimeoutTime(int sec); + + /// Gets the time allowed for connection + AREXPORT int getConnectTimeoutTime(void); + + /// Logs the tracking information (packet and byte counts) + AREXPORT void logTracking(bool terse); + + /// Clears the tracking information (resets counters) + AREXPORT void resetTracking(void); + + /// Adds a call for when the server shuts down + AREXPORT void addServerShutdownCB(ArFunctor *functor, + ArListPos::Pos position = ArListPos::LAST); + + /// Removes a call for when the server shuts down + AREXPORT void remServerShutdownCB(ArFunctor *functor); + + /// Adds a call for when a disconnection has occured because of error + AREXPORT void addDisconnectOnErrorCB(ArFunctor *functor, + ArListPos::Pos position = ArListPos::LAST); + + /// Removes a call for when a disconnection has occured because of error + AREXPORT void remDisconnectOnErrorCB(ArFunctor *functor); + + /// Run the loop once + AREXPORT void loopOnce(void); + + /// Process the packet wherever it came from + AREXPORT void processPacket(ArNetPacket *packet, bool tcp); + + /// Process a packet from udp (just hands off to processPacket) + AREXPORT void processPacketUdp(ArNetPacket *packet, + struct sockaddr_in *sin); + + /// Sets it so we only get TCP data from the server not UDP + AREXPORT void setTcpOnlyFromServer(void); + /// Sets it so we only send TCP data to the server + AREXPORT void setTcpOnlyToServer(void); + + /// Returns whether we only get TCP data from the server not UDP + AREXPORT bool isTcpOnlyFromServer(void); + /// Returns whether we only send TCP data to the server + AREXPORT bool isTcpOnlyToServer(void); + /// Gets a (probably) unique key that can be used to identify the client (after connection) + AREXPORT void getClientKey(unsigned char key[CLIENT_KEY_LENGTH]); + + + /// Starts the process of disconnecting from the server. + /** + * This method should be called in threads that should not block + * (such as the main GUI thread). The call should be followed by + * a delay of one second, followed by a call to + * finishNonBlockingDisconnect(). + **/ + AREXPORT bool startNonBlockingDisconnect(); + + /// Finishes the process of disconnecting from the server. + /** + * This method should be used in conjunction with + * startNonBlockingDisconnect in threads that should not block + * (such as the main GUI thread). + **/ + AREXPORT void finishNonBlockingDisconnect(); + + /// Gets the name of the data a packet is for + AREXPORT const char *getName(ArNetPacket *packet, bool internalCall = false); + /// Gets the name of the data a command is + AREXPORT const char *getName(unsigned int command, bool internalCall = false); + // the function for the thread + AREXPORT virtual void * runThread(void *arg); + /// Internal function to get the socket (no one should need this) + AREXPORT struct in_addr *getTcpAddr(void) { return myTcpSocket.inAddr(); } + /// Internal function that'll do the connection (mainly for switch connections) + AREXPORT bool internalBlockingConnect( + const char *host, int port, bool log, const char *user, + const char *password, ArSocket *tcpSocket, + const char *openOnIP = NULL); + /// Internal function that'll start the non blocking connection (mainly for switch connections) + AREXPORT NonBlockingConnectReturn internalNonBlockingConnectStart( + const char *host, int port, bool log, const char *user, + const char *password, ArSocket *tcpSocket, + const char *openOnIP = NULL); + /// Internal function that'll start the non blocking connection (mainly for switch connections) + AREXPORT NonBlockingConnectReturn internalNonBlockingConnectContinue(void); + /// Internal function to get the tcp socket + AREXPORT ArSocket *getTcpSocket(void) { return &myTcpSocket; } + /// Internal function to get the udp socket + AREXPORT ArSocket *getUdpSocket(void) { return &myUdpSocket; } + /// Internal function get get the data map + AREXPORT const std::map *getDataMap(void) + { return &myIntDataMap; } + /// Returns the command number from the name + AREXPORT unsigned int findCommandFromName(const char *name); + /// Request some data every mSec milliseconds by command not name + AREXPORT bool requestByCommand(unsigned int command, long mSec, + ArNetPacket *packet = NULL); + /// Don't want this data anymore, by command not name + AREXPORT bool requestStopByCommand(unsigned int command); + + /// Request some data (or send a command) just once by command not name + AREXPORT bool requestOnceByCommand(unsigned int command, + ArNetPacket *packet = NULL); + /// Request some data (or send a command) just once by command not name + AREXPORT bool requestOnceByCommandUdp(unsigned int command, + ArNetPacket *packet = NULL); + /// Gets if we received the list of commands + bool getReceivedDataList(void) { return myReceivedDataList; } + /// Gets if we received the list of arguments and + bool getReceivedArgRetList(void) { return myReceivedArgRetList; } + /// Gets if we received the list of commands + bool getReceivedGroupAndFlagsList(void) { return myReceivedGroupAndFlagsList; } + /// Tells us the reason the connection was rejected (see ArServerCommands for details) + int getRejected(void) { return myRejected; } + /// Tells us the reason the connection was rejected (see ArServerCommands for details) + const char *getRejectedString(void) { return myRejectedString; } +protected: + + /// Optional robot name for logging + std::string myRobotName; + /// Optional prefix to be inserted at the start of log messages + std::string myLogPrefix; + /// If we're enforcing the version of the protocol or not + std::string myEnforceProtocolVersion; + /// if we're a particular type + ArServerCommands::Type myEnforceType; + + AREXPORT bool setupPacket(ArNetPacket *packet); + ArTime myLastPacketReceived; + std::list myServerShutdownCBList; + std::list myDisconnectOnErrorCBList; + std::list myCycleCallbacks; + void clear(void); + // does the first part of connection + bool internalConnect(const char *host, int port, bool obsolete, + const char *openOnIP); + void internalStartUdp(void); + void buildList(ArNetPacket *packet); + void internalSwitchState(ClientState state); + bool myReceivedDataList; + bool myReceivedArgRetList; + bool myReceivedGroupAndFlagsList; + ClientState myState; + ArTime myStateStarted; + bool myUdpConfirmedFrom; + bool myUdpConfirmedTo; + // if we only send tcp + bool myTcpOnlyTo; + // if we only receive tcp from the server + bool myTcpOnlyFrom; + + bool myIsRunningAsync; + bool myDisconnectSoon; + bool myIsStartedDisconnect; + bool myIsStopped; + + bool myQuiet; + bool myDebugLogging; + ArLog::LogLevel myVerboseLogLevel; + std::string myHost; + std::string myUser; + std::string myPassword; + // the time we allow for connections + int myTimeoutTime; + // the time we started our connection + ArTime myStartedConnection; + ArTime myStartedUdpConnection; + ArTime myStartedShutdown; + + enum NonBlockingConnectState + { + NON_BLOCKING_STATE_NONE, + NON_BLOCKING_STATE_TCP, + NON_BLOCKING_STATE_UDP + }; + + NonBlockingConnectState myNonBlockingConnectState; + + + ArMutex myDataMutex; + ArMutex myClientMutex; + ArMutex myMapsMutex; + ArMutex myStateMutex; + ArMutex myCallbackMutex; + ArMutex myCycleCallbackMutex; + ArMutex myPacketTrackingMutex; + // our map of names to ints + std::map myNameIntMap; + // our map of ints to functors + std::map myIntDataMap; + + struct sockaddr_in myUdpSin; + bool myUdpSinValid; + // the port the server said it was using + unsigned int myServerReportedUdpPort; + // the port the server actually is using + unsigned int myServerSentUdpPort; + unsigned int myUdpPort; + long myAuthKey; + long myIntroKey; + std::string myServerKey; + double myBackupTimeout; + // this is a key we have for identifying ourselves moderately uniquely + unsigned char myClientKey[16]; + ArNetPacketSenderTcp myTcpSender; + ArNetPacketReceiverTcp myTcpReceiver; + ArNetPacketReceiverUdp myUdpReceiver; + ArSocket myTcpSocket; + ArSocket myUdpSocket; + ArFunctor2C myProcessPacketCB; + ArFunctor2C myProcessPacketUdpCB; + + int myRejected; + char myRejectedString[32000]; + + ArTime myTrackingStarted; + class Tracker + { + public: + Tracker() { reset(); } + virtual ~Tracker() {} + void reset(void) + { myPacketsTcp = 0; myBytesTcp = 0; myPacketsUdp = 0; myBytesUdp = 0; } + long myPacketsTcp; + long myBytesTcp; + long myPacketsUdp; + long myBytesUdp; + }; + AREXPORT void trackPacketSent(ArNetPacket *packet, bool tcp); + AREXPORT void trackPacketReceived(ArNetPacket *packet, bool tcp); + std::map myTrackingSentMap; + std::map myTrackingReceivedMap; + +}; + +#endif // NLCLIENTBASE_H diff --git a/Legacy/Aria/ArNetworking/include/ArClientCommands.h b/Legacy/Aria/ArNetworking/include/ArClientCommands.h new file mode 100644 index 0000000..2a5497c --- /dev/null +++ b/Legacy/Aria/ArNetworking/include/ArClientCommands.h @@ -0,0 +1,24 @@ +#ifndef NLCLIENTCOMMANDS_H +#define NLCLIENTCOMMANDS_H + +/** + The commands from the client to the server +**/ + +class ArClientCommands +{ +public: + enum ClientCommands { + SHUTDOWN = 1, ///< Closes the connection + INTRODUCTION = 2, ///< Introduces the client to the server + UDP_INTRODUCTION = 3, ///< Udp introduction of the client to the server + UDP_CONFIRMATION = 4, ///< Confirmation Udp was received from server + TCP_ONLY = 5, ///< Client tells server to only send TCP + LIST = 128, ///< Lists the types that can be handled + REQUEST = 129, ///< Requests packet of a certain type + REQUESTSTOP = 130 ///< Requests that the server stop sending the given type + /// You can request any other command once if you know its number just by sending that number + }; +}; + +#endif // NLCLIENTCOMMANDS_H diff --git a/Legacy/Aria/ArNetworking/include/ArClientData.h b/Legacy/Aria/ArNetworking/include/ArClientData.h new file mode 100644 index 0000000..c8e206a --- /dev/null +++ b/Legacy/Aria/ArNetworking/include/ArClientData.h @@ -0,0 +1,86 @@ +#ifndef ARCLIENTDATA_H +#define ARCLIENTDATA_H + +#include "Aria.h" +class ArNetPacket; + +/// class to hold information about the different data the client has +/** + This class is mostly just for holding all the information about one + of the client data entires in one convenient spot + + Information about the data flags held here... The recognized ones + right now are just for return values so some forwarding can be done + intelligently, you should only have one return value, they are: + RETURN_NONE (There are no return packets), RETURN_SINGLE (There is + exactly one return packet), RETURN_UNTIL_EMPTY (There return goes + until an empty packet), RETURN_VIDEO (this is the special case for + video where basically its something thats always requested at an + interval and everyone'll want it after we've transfered it), + RETURN_COMPLEX (The return is more complex (so you'll need a helper + class)) +**/ + +class ArClientData +{ +public: + /// Constructor + AREXPORT ArClientData(const char *name, const char *description, + unsigned int command, + ArFunctor1 *functor); + /// Destructor + AREXPORT virtual ~ArClientData(); + /// Gets the name + const char *getName(void) { return myName.c_str(); } + /// Gets the description + const char *getDescription(void) { return myDescription.c_str(); } + unsigned int getCommand(void) { return myCommand; } + /// Gets the argument description + const char *getArgumentDescription(void) + { return myArgumentDescription.c_str(); } + /// Gets the return description + const char *getReturnDescription(void) + { return myReturnDescription.c_str(); } + /// Gets the command group + const char *getCommandGroup(void) { return myCommandGroup.c_str(); } + AREXPORT bool hasDataFlag(const char *dataFlag); + const char *getDataFlagsString(void) + { return myDataFlagsBuilder.getFullString(); } + /// Gets the list of functors + const std::list *> *getFunctorList(void) const + { return &myFunctorList; }; + /// Locks the functor list so we can walk it without it changing + AREXPORT int lockFunctorList(void) { return myMutex.lock(); } + /// Tries to lock the functor list so we can walk it without it changing + AREXPORT int tryLockFunctorList(void) { return myMutex.tryLock(); } + /// Unlocks the functor list so we can walk it without it changing + AREXPORT int unlockFunctorList(void) { return myMutex.unlock(); } + + /// Adds a new functor the end of the list + void addFunctor(ArFunctor1 *functor) + { myFunctorList.push_back(functor); } + /// Removes a functor from the list all together + void remFunctor(ArFunctor1 *functor) + { myFunctorList.remove(functor); } + /// Sets the argument and return descriptions + void setArgRetDescs(const char *argDesc, const char *retDesc) + { myArgumentDescription = argDesc; myReturnDescription = retDesc; } + /// Sets the command group + void setCommandGroup(const char *commandGroup) + { myCommandGroup = commandGroup; } + /// Sets the data flags + AREXPORT void addDataFlags(const char *dataFlags); +protected: + std::string myName; + std::string myDescription; + unsigned int myCommand; + std::string myArgumentDescription; + std::string myReturnDescription; + std::string myCommandGroup; + ArMutex myDataMutex; + ArArgumentBuilder myDataFlagsBuilder; + ArMutex myMutex; + std::list *> myFunctorList; +}; + +#endif // ARCLIENTDATA_H diff --git a/Legacy/Aria/ArNetworking/include/ArClientFileUtils.h b/Legacy/Aria/ArNetworking/include/ArClientFileUtils.h new file mode 100644 index 0000000..de77fef --- /dev/null +++ b/Legacy/Aria/ArNetworking/include/ArClientFileUtils.h @@ -0,0 +1,367 @@ +#ifndef ARCLIENTFILEUTILS_H +#define ARCLIENTFILEUTILS_H + +#include "Aria.h" +#include "ArClientBase.h" + +/// The item type that the ArCLientFileLister gets back +class ArClientFileListerItem +{ +public: + /// Constructor + ArClientFileListerItem(const char *name, time_t atime, time_t mtime, + ArTypes::UByte4 size) + { myName = name; myATime = atime; myMTime = mtime; mySize = size; } + /// Copy Constructor + ArClientFileListerItem(const ArClientFileListerItem &item) + { myName = item.myName; myATime = item.myATime; myMTime = item.myMTime; + mySize = item.mySize; } + /// Assignment operator + AREXPORT ArClientFileListerItem &operator=(const + ArClientFileListerItem &item) + { + if (this != &item) + { + myName = item.myName; myATime = item.myATime; myMTime = item.myMTime; + mySize = item.mySize; + } + return *this; + } + /// Destructor + virtual ~ArClientFileListerItem() {} + /// Gets the name of the list item + const char *getName(void) const { return myName.c_str(); } + /// Gets the time this list item was last accessed in seconds from 1970 + time_t getLastAccessedTime(void) const { return myATime; } + /// Gets the time this list item was last modified in seconds from 1970 + time_t getLastModifiedTime(void) const { return myMTime; } + /// Gets the size of this list item in bytes + ArTypes::UByte4 getSize(void) const { return mySize; } +protected: + std::string myName; + time_t myATime; + time_t myMTime; + ArTypes::UByte4 mySize; +}; + +/// Class for getting file list information from the server +/** + This class will interact with the ArServerFileLister and find out + whats in directories and change directories and such. This class + is all that should be used to get the information from + ArServerFileLister, the API between the two is fairly volatile and + will remain so. If you need more functionality let us know and + we'll add it if its reasonable. + + When you change directories or change to the top dir it doesn't + happen right away, but when it happens the update callbacks will be + called, 0 as the int for the callback means everything is good, + positive error messages are from the server (1 == tried to go + outside allowed area, 2 == no such directory), negative are from + this class (-1 == got directory but it wasn't what we wanted (if + you wait the right one might come in, like if someone selects one + dir then the other)). +**/ +class ArClientFileLister +{ +public: + /// Constructor + AREXPORT ArClientFileLister(ArClientBase *client); + /// Destructor + AREXPORT virtual ~ArClientFileLister(); + /// Sees if the server supports what this class needs + AREXPORT bool isAvailable(void); + /// Goes to the top directory + AREXPORT void changeToTopDir(void); + /// Goes to this directory in the current directory + AREXPORT void changeToDir(const char *dir); + /// Goes up one directory from current directory + AREXPORT void upOneDir(void); + /// Goes to this absolute directory + AREXPORT void changeToAbsDir(const char *dir); + /// Gets the name of the directory we're in + AREXPORT const char *getCurrentDir(void) const; + /// Gets the name of the directory that we're currently waiting for + AREXPORT const char *getWaitingForDir(void) const; + + /// Gets the directories in the current directory + AREXPORT std::list getDirectories(void) const; + /// Gets the files in the current directory + AREXPORT std::list getFiles(void) const; + /// Adds a callback for when we get the desired directory info + AREXPORT void addUpdatedCallback(ArFunctor1 *functor, + ArListPos::Pos position = ArListPos::LAST); + /// Removes a callback for when we get the desired directory info + AREXPORT void remUpdatedCallback(ArFunctor1 *functor); + /// Gets the last time we were updated + AREXPORT ArTime getLastUpdated(void); + /// Gets the last time we requested an update + AREXPORT ArTime getLastRequested(void); + /// Logs the current directory + AREXPORT void log(bool withTimes); +protected: + AREXPORT void netGetDirListing(ArNetPacket *packet); + AREXPORT void netGetDirListingMultiplePackets(ArNetPacket *packet); + AREXPORT void callUpdatedCallbacks(int val); + AREXPORT void logList( + std::list *logThis, + bool withTimes); + void getDirListing(const char *dir); + ArMutex myDataMutex; + ArMutex myCallbackMutex; + ArClientBase *myClient; + char myCurrentDir[2048]; + char myWaitingForDir[2048]; + bool myLastDirMatched; + bool myNewDirListing; + ArTime myLastRequested; + ArTime myLastUpdated; + std::list myDirectories; + std::list myFiles; + std::list *> myUpdatedCallbacks; + ArFunctor1C myGetDirListingCB; + ArFunctor1C myGetDirListingMultiplePacketsCB; +}; + + +/// Class for getting files from the server +/** + This class will interact with the ArServerFileToClient and get a + file on the server. If you want to find out what files are on the + server use ArClientFileLister. + + When get a file it doesn't happen right away, but when the file is + received (or failes) the fileGotten callbacks will be called, 0 as + the int for the callback means everything is good, positive error + messages are from the server (1 == tried to go outside allowed + area, 2 == no such directory, 3 == empty file name, 4 == problem + reading file), negative are from this class (-1 == got directory + but it wasn't what we wanted (if you wait the right one might come + in, like if someone selects one dir then the other), -2 == can't + open file to put result into). +**/ +class ArClientFileToClient +{ +public: + /// Constructor + AREXPORT ArClientFileToClient(ArClientBase *client); + /// Destructor + AREXPORT virtual ~ArClientFileToClient(); + /// Sees if the server supports what this class needs + AREXPORT bool isAvailable(void); + + AREXPORT bool isAvailableSetTimestamp(void); + + /// Get the file from a directory + AREXPORT bool getFileFromDirectory(const char *directory, + const char *fileName, + const char *clientFileName, + bool isSetTimestamp = false); + /// Cancels getting a file + AREXPORT void cancelGet(void); + /// If we're getting a file now + AREXPORT bool isWaitingForFile(void); + /// Gets the directory we're getting from + AREXPORT const char *getDirectory(void); + /// Gets the filename we're getting + AREXPORT const char *getFileName(void); + /// Gets the filename we'll save the gotten file in + AREXPORT const char *getClientFileName(void); + /// Adds a callback for when we get the desired file (or fail) + AREXPORT void addFileReceivedCallback(ArFunctor1 *functor, + ArListPos::Pos position = ArListPos::LAST); + /// Removes a callback for when we get the desired file (or fail) + AREXPORT void remFileReceivedCallback(ArFunctor1 *functor); + + + /// Gets the last time we finished getting a file + AREXPORT ArTime getLastReceived(void); + /// Gets the last time we asked for a file + AREXPORT ArTime getLastRequested(void); + +protected: + + AREXPORT void netGetFile(ArNetPacket *packet); + AREXPORT void netGetFileWithTimestamp(ArNetPacket *packet); + AREXPORT void doGetFile(ArNetPacket *packet, + bool isSetTimestamp); + AREXPORT void callFileReceivedCallbacks(int val); + + +protected: + + ArMutex myDataMutex; + ArMutex myCallbackMutex; + ArClientBase *myClient; + bool myIsWaitingForFile; + std::string myDirectory; + std::string myFileName; + std::string myWholeFileName; + std::string myClientFileName; + FILE *myFile; + + ArTime myLastRequested; + ArTime myLastReceived; + + std::list *> myFileReceivedCallbacks; + + ArFunctor1C myGetFileCB; + ArFunctor1C myGetFileWithTimestampCB; +}; + +/// Class for putting files to the server +/** + This class will interact with the ArServerFileFromClient and put a + file on to the server. If you want to find out what files are on + the server use ArClientFileLister. + + When get a file it doesn't happen right away, but when the file is + received (or failes) the fileGotten callbacks will be called, 0 as + the int for the callback means everything is good, positive error + messages are from the server (0 = good (got file), 1 = getting + file, 2 = tried to go outside allowed area, 3 = bad directory, 4 = + empty file name (or other problem with fileName), 5 = can't write + temp file, 6 = error moving file from temp to perm, 7 = another + client putting file, 8 = timeout (no activity for 15 seconds) and + another client wanted to put the file, 9 = client adding to, + finishing, or canceling a file the server doesn't have), negative + would be from this class but there aren't any of those yet +**/ +class ArClientFileFromClient +{ +public: + /// Constructor + AREXPORT ArClientFileFromClient(ArClientBase *client); + /// Destructor + AREXPORT virtual ~ArClientFileFromClient(); + /// Sees if the server supports what this class needs + AREXPORT bool isAvailable(void); + /// Sees if the server supports what this class needs to send slowly + AREXPORT bool isAvailableSlow(void); + /// Sees if the server supports what this class needs to send fast + AREXPORT bool isAvailableFast(void); + /// Sees if the server supports the ability to set the file timestamp + AREXPORT bool isAvailableSetTimestamp(void); + + /// Enum that describes the speed to send at + enum SendSpeed + { + SPEED_AUTO, ///< Send it fast if available, if not then send it slow + SPEED_FAST, ///< Send it fast + SPEED_SLOW ///< Send it slow + }; + /// Puts the specified client file on the server in the given directory and file + AREXPORT bool putFileToDirectory(const char *directory, + const char *fileName, + const char *clientFileName, + SendSpeed sendSpeed = SPEED_AUTO, + bool isSetTimestamp = false); + /// Cancels putting a file + AREXPORT void cancelPut(void); + + /// If we're waiting for completion now + AREXPORT bool isWaitingForReturn(void); + /// Gets the directory we're putting to + AREXPORT const char *getDirectory(void); + /// Gets the filename we're putting + AREXPORT const char *getFileName(void); + /// Gets the filename we're taking from the client + AREXPORT const char *getClientFileName(void); + /// Adds a callback for when we get the desired file (or fail) + AREXPORT void addFileSentCallback(ArFunctor1 *functor, + ArListPos::Pos position = ArListPos::LAST); + /// Removes a callback for when we get the desired file (or fail) + AREXPORT void remFileSentCallback(ArFunctor1 *functor); + /// Gets the last time we finished putting a file + AREXPORT ArTime getLastCompletedSend(void); + /// Gets the last time we started putting a file + AREXPORT ArTime getLastStartedSend(void); +protected: + AREXPORT void netPutFile(ArNetPacket *packet); + AREXPORT void callFileSentCallbacks(int val); + + ArMutex myDataMutex; + ArMutex myCallbackMutex; + ArClientBase *myClient; + bool myIsWaitingForReturn; + bool myInterleaved; + bool myTimestamp; + std::string myCommandName; + std::string myDirectory; + std::string myFileName; + std::string myWholeFileName; + std::string myClientFileName; + + bool myReadyForNextPacket; + FILE *myFile; + ArTime myLastStartedSend; + ArTime myLastCompletedSend; + std::list *> myFileSentCallbacks; + ArFunctor1C myPutFileCB; +}; + + +/// Class for deleting a file on the server +/** + This class will interact with the ArServerFileFromClient and put a + file on to the server. If you want to find out what files are on + the server use ArClientFileLister. + + When get a file it doesn't happen right away, but when the file is + received (or failes) the fileGotten callbacks will be called, 0 as + the int for the callback means everything is good, positive error + messages are from the server (0 = good (got file), 1 = getting + file, 2 = tried to go outside allowed area, 3 = bad directory, 4 = + empty file name (or other problem with fileName), 5 = can't write + temp file, 6 = error moving file from temp to perm, 7 = another + client putting file, 8 = timeout (no activity for 15 seconds) and + another client wanted to put the file, 9 = client adding to, + finishing, or canceling a file the server doesn't have), negative + would be from this class but there aren't any of those yet +**/ +class ArClientDeleteFileOnServer +{ +public: + /// Constructor + AREXPORT ArClientDeleteFileOnServer(ArClientBase *client); + /// Destructor + AREXPORT virtual ~ArClientDeleteFileOnServer(); + /// Sees if the server supports what this class needs + AREXPORT bool isAvailable(void); + /// Get the file from a directory + AREXPORT bool deleteFileFromDirectory(const char *directory, + const char *fileName); + /// If we're waiting for completion now + AREXPORT bool isWaitingForReturn(void); + /// Gets the directory we're putting to + AREXPORT const char *getDirectory(void); + /// Gets the filename we're putting + AREXPORT const char *getFileName(void); + /// Adds a callback for when we get the desired file (or fail) + AREXPORT void addFileDeletedCallback(ArFunctor1 *functor, + ArListPos::Pos position = ArListPos::LAST); + /// Removes a callback for when we get the desired file (or fail) + AREXPORT void remFileDeletedCallback(ArFunctor1 *functor); + /// Gets the last time we finished putting a file + AREXPORT ArTime getLastCompletedSend(void); + /// Gets the last time we started putting a file + AREXPORT ArTime getLastStartedSend(void); +protected: + AREXPORT void netDeleteFile(ArNetPacket *packet); + AREXPORT void callFileDeletedCallbacks(int val); + ArMutex myDataMutex; + ArMutex myCallbackMutex; + ArClientBase *myClient; + bool myIsWaitingForReturn; + std::string myDirectory; + std::string myFileName; + std::string myWholeFileName; + FILE *myFile; + ArTime myLastStartedSend; + ArTime myLastCompletedSend; + std::list *> myFileDeletedCallbacks; + ArFunctor1C myDeleteFileCB; +}; + +#endif //ARCLIENTFILEUTILS_H diff --git a/Legacy/Aria/ArNetworking/include/ArClientHandlerConfig.h b/Legacy/Aria/ArNetworking/include/ArClientHandlerConfig.h new file mode 100644 index 0000000..7d4d1f3 --- /dev/null +++ b/Legacy/Aria/ArNetworking/include/ArClientHandlerConfig.h @@ -0,0 +1,223 @@ +#ifndef ARCLIENTCONFIGHANDLER_H +#define ARCLIENTCONFIGHANDLER_H + +#include "Aria.h" +#include "ArClientBase.h" + +/// Client handler for receiving and updating ArConfig data via ArNetworking. +/** + * ArClientHandlerConfig processes the network packets that describe a + * robot's ArConfig. It also provides a means to save the modified + * configuration data to the robot server. This class is designed to + * work in conjunction with the ArServerHandlerConfig. See the server + * handler documentation for a complete description of the networking + * interface. + * + * This class should be thread safe, with the exception of + * unThreadSafeGetConfig. (If you want to use this method, surround it + * with calls to lock() and unlock().) + * + * Note that you can't add callbacks or remove callbacks from within a + * callback function. +**/ +class ArClientHandlerConfig +{ +public: + /// Constructor + AREXPORT ArClientHandlerConfig(ArClientBase *client, + bool ignoreBounds = false, + const char *robotName = NULL, + const char *logPrefix = NULL); + /// Destructor + AREXPORT virtual ~ArClientHandlerConfig(void); + + /// Requests the config from the server + AREXPORT void requestConfigFromServer(void); + /// Tells the server to reload the configuration + AREXPORT void reloadConfigOnServer(void); + + /// Threadsafe way to get the config to play with + AREXPORT ArConfig getConfigCopy(void); + + /// Adds a gotConfig callback + AREXPORT void addGotConfigCB(ArFunctor *functor, + ArListPos::Pos position = ArListPos::LAST); + /// Removes a gotConfig callback + AREXPORT void remGotConfigCB(ArFunctor *functor); + /// Adds a save config to server succeeded callback + AREXPORT void addSaveConfigSucceededCB(ArFunctor *functor, + ArListPos::Pos position = ArListPos::LAST); + /// Removes a save config to server succeeded callback + AREXPORT void remSaveConfigSucceededCB(ArFunctor *functor); + /// Adds a save config to server failed callback + AREXPORT void addSaveConfigFailedCB(ArFunctor1 *functor, + ArListPos::Pos position = ArListPos::LAST); + /// Removes a save config to server failed callback + AREXPORT void remSaveConfigFailedCB(ArFunctor1 *functor); + + /// Returns true if config gotten + AREXPORT bool haveGottenConfig(void); + /// Sends the config back to the server + AREXPORT void saveConfigToServer(void); + /// Sends the config back to the server + AREXPORT void saveConfigToServer( + ArConfig *config, + const std::set *ignoreTheseSections = NULL); + + /// Returns if we've requested some defaults + AREXPORT bool haveRequestedDefaults(void); + /// Returns if we've gotten our requested defaults + AREXPORT bool haveGottenDefaults(void); + + /// Sees if we can request defaults (both types) + AREXPORT bool canRequestDefaults(void); + + AREXPORT bool requestDefaultConfigFromServer(void); + AREXPORT ArConfig *getDefaultConfig(); + + /// Requests defaults for all sections from the server; modifies the config + AREXPORT bool requestConfigDefaults(void); + /// Requests defaults for one section from the server; modifies the config + AREXPORT bool requestSectionDefaults(const char *section); + + + /// Adds a got config defaults callback + AREXPORT void addGotConfigDefaultsCB(ArFunctor *functor, + ArListPos::Pos position = ArListPos::LAST); + /// Removes a got config defaults callback + AREXPORT void remGotConfigDefaultsCB(ArFunctor *functor); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Last Editable Priority + // + // This value designates the last priority (highest numerical value) for + // which parameters may be edited. For example, when this value is set to + // EXPERT, then the user may not edit FACTORY parameters. + // + // If editable priority levels are supported and the client wishes to + // receive parameters of ineditable priorities, then the method + // requestLastEditablePriority should be called (and completed) before + // requestConfigFromServer is called. + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + /// Returns whether the server supports the last editable priority request. + AREXPORT bool isLastEditablePriorityAvailable(); + + /// Requests the last editable priority from the server + AREXPORT bool requestLastEditablePriorityFromServer(); + + /// Returns whether the last editable priority has been received from the server + AREXPORT bool haveGottenLastEditablePriority(); + /// Returns the last editable priority of the config + AREXPORT ArPriority::Priority getLastEditablePriority(); + + /// Adds callback invoked when the last editable priority packet is received + AREXPORT void addGotLastEditablePriorityCB + (ArFunctor *functor, + int position = 50); + /// Removes the specified callback from the list of last editable priority callbacks + AREXPORT void remGotLastEditablePriorityCB(ArFunctor *functor); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + /// Unthreadsafe way to get the config to play with (see long docs) + AREXPORT ArConfig *getConfig(void); + /// Locks the config for if you're using the unthreadsafe getConfig + AREXPORT int lock(void); + /// Try to lock for the config for if you're using the unthreadsafe getConfig + AREXPORT int tryLock(void); + /// Unlocks the config for if you're using the unthreadsafe getConfig + AREXPORT int unlock(void); + + /// Turn on this flag to reduce the number of verbose log messages. + AREXPORT void setQuiet(bool isQuiet); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Packet Handlers + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + /// Handles the packet from the GetConfigBySectionsV3 + AREXPORT void handleGetConfigBySectionsV3(ArNetPacket *packet); + + /// Handles the packet from the GetConfigBySectionsV2 + AREXPORT void handleGetConfigBySectionsV2(ArNetPacket *packet); + + /// Handles the packet from the GetConfigBySections + AREXPORT void handleGetConfigBySections(ArNetPacket *packet); + + /// Handles the packet from the GetConfigSectionFlags + AREXPORT void handleGetConfigSectionFlags(ArNetPacket *packet); + + /// Handles the packet from the getConfig + AREXPORT void handleGetConfig(ArNetPacket *packet); + + /// Handles the return packet from the setConfig (saveConfigToServer) + AREXPORT void handleSetConfig(ArNetPacket *packet); + + /// Handles the return packet from the setConfigBySections (saveConfigToServer) + AREXPORT void handleSetConfigBySections(ArNetPacket *packet); + + /// Handles the return packet from the setConfigBySectionsV2 (saveConfigToServer) + AREXPORT void handleSetConfigBySectionsV2(ArNetPacket *packet); + + /// Handles the return packet from getConfigDefaults + AREXPORT void handleGetConfigDefaults(ArNetPacket *packet); + + /// Handles the return packet from getLastEditablePriority + AREXPORT void handleGetLastEditablePriority(ArNetPacket *packet); + +protected: + + AREXPORT void handleGetConfigData(ArNetPacket *packet, + bool isMultiplePackets, + int version); + + +protected: + + std::string myRobotName; + std::string myLogPrefix; + + std::list myGotConfigCBList; + std::list mySaveConfigSucceededCBList; + std::list *> mySaveConfigFailedCBList; + std::list myGotConfigDefaultsCBList; + ArCallbackList myGotLastEditablePriorityCBList; + + ArClientBase *myClient; + + ArConfig myConfig; + ArConfig *myDefaultConfig; + ArPriority::Priority myLastEditablePriority; + + ArMutex myDataMutex; + ArMutex myCallbackMutex; + + bool myHaveRequestedLastEditablePriority; + bool myHaveGottenLastEditablePriority; + bool myHaveRequestedConfig; + bool myHaveGottenConfig; + bool myHaveRequestedDefaults; + bool myHaveGottenDefaults; + bool myHaveRequestedDefaultCopy; + + bool myIsQuiet; + + ArFunctor1C myHandleGetConfigBySectionsV3CB; + ArFunctor1C myHandleGetConfigBySectionsV2CB; + ArFunctor1C myHandleGetConfigBySectionsCB; + ArFunctor1C myHandleGetConfigCB; + ArFunctor1C myHandleSetConfigCB; + ArFunctor1C myHandleSetConfigBySectionsCB; + ArFunctor1C myHandleSetConfigBySectionsV2CB; + ArFunctor1C myHandleGetConfigDefaultsCB; + ArFunctor1C myHandleGetDefaultConfigCB; + ArFunctor1C myHandleGetConfigSectionFlagsCB; + ArFunctor1C myHandleGetLastEditablePriorityCB; +}; + +#endif diff --git a/Legacy/Aria/ArNetworking/include/ArClientSimpleConnector.h b/Legacy/Aria/ArNetworking/include/ArClientSimpleConnector.h new file mode 100644 index 0000000..84adfea --- /dev/null +++ b/Legacy/Aria/ArNetworking/include/ArClientSimpleConnector.h @@ -0,0 +1,71 @@ +#ifndef ARCLIENTSIMPLECONNECTOR_H +#define ARCLIENTSIMPLECONNECTOR_H + +#include "Aria.h" +#include "ArClientBase.h" + +/** + This will let you connect to different hosts, ports, and with + different users and passwords more easily. + + Some program command line options affect behavior: + @verbinclude ArClientSimpleConnector_options + + To set the host the client will connect to use '-host hostName' + in the command line parameters + (no abbreviation for this since -h is for help and it's only 4 + letters). To set the port the client will connect to use '-port + portNumber' or '-p portNumber'. + To set the user to connect with + use '-user userName' or '-u userName'. + To set the password to + connect with use '-password password' or + '-pwd password'. To + use no password use '-nopassword' or '-np'. + Note that for using + passwords you should NOT use that option on the command line since + that can show everyone what the password is (especially in Linux), + it's there only for testing. If you give it a username without a + password it'll ask you for a password, if you don't have a password + just use the -nopassword or let it ask you for a password and hit + enter. To set the server key (string we need to connect to the + server) use '-setServerKey serverKey' or + '-ssk serverKey'. + **/ +class ArClientSimpleConnector +{ +public: + /// Constructor that takes argument parser (prefered) + AREXPORT ArClientSimpleConnector(ArArgumentParser *parser); + /// Constructor that takes args from main (not prefered) + AREXPORT ArClientSimpleConnector(int *argc, char **argv); + /// Constructor that takes argument builder (not prefered) + AREXPORT ArClientSimpleConnector(ArArgumentBuilder *arguments); + /// Destructor + AREXPORT ~ArClientSimpleConnector(void); + /// Connects the client with the options given + AREXPORT bool connectClient(ArClientBase *client, bool log = true); + /// Parses the arguments + AREXPORT bool parseArgs(void); + /// Parses the arguments + AREXPORT bool parseArgs(ArArgumentParser *parser); + /// Logs the options the connector has + AREXPORT void logOptions(void) const; +protected: + void reset(void); + const char *myHost; + const char *myUser; + const char *myPassword; + const char *myServerKey; + int myPort; + bool myNoPassword; + bool myLogDataList; + // our parser + ArArgumentParser *myParser; + bool myOwnParser; + + ArRetFunctorC myParseArgsCB; + ArConstFunctorC myLogOptionsCB; +}; + +#endif // ARCLIENTSIMPLECONNECTOR_H diff --git a/Legacy/Aria/ArNetworking/include/ArClientSwitchManager.h b/Legacy/Aria/ArNetworking/include/ArClientSwitchManager.h new file mode 100644 index 0000000..7019eb5 --- /dev/null +++ b/Legacy/Aria/ArNetworking/include/ArClientSwitchManager.h @@ -0,0 +1,187 @@ +#ifndef ARCLIENTSWITCH_H +#define ARCLIENTSWITCH_H + +#include "Aria.h" +#include "ArServerBase.h" +#include "ArClientBase.h" + +/** + The serverInfoFile takes the form of a config file roughly, there + are 3 things you can put in it now. 'user user', 'password + password' and 'serverKey serverKey'. Note that it loads these + files sequentially so if you pass it 5 files it'll read them in the + order they were passed in. If you give it just the keyword but not + the value (ie 'user') then it'll clear out that value. + + Some program command line options can be used to configure this class: + @verbinclude ArClientSwitchManager_options +**/ +class ArClientSwitchManager : public ArASyncTask +{ +public: + AREXPORT ArClientSwitchManager( + ArServerBase *serverBase, + ArArgumentParser *parser, + const char *serverDescription = "Central Server", + const char *clientSoftwareDescription = "Software"); + AREXPORT virtual ~ArClientSwitchManager(); + /// Returns if we're connected or not + AREXPORT bool isConnected(void); + /// Function to parse the arguments given in the constructor + AREXPORT bool parseArgs(void); + /// Log the options the simple connector has + AREXPORT void logOptions(void) const; + /// Gets the hostname we're using for the central server (NULL means we're not trying to sue the central server) + AREXPORT const char *getCentralServerHostName(void); + /// Gets the identifier we're using + AREXPORT const char *getIdentifier(void); + /// Sets the identifier we're using + AREXPORT void setIdentifier(const char *identifier) + { myIdentifier = identifier; } + + /// Enforces the that the server is using this protocol version + AREXPORT void enforceProtocolVersion(const char *protocolVersion); + /// Enforces that the robots that connect are this type + AREXPORT void enforceType(ArServerCommands::Type type); + + /// Gets the config display hint items dependent on the central + /// server should use (still check getCentralServerHostName to see + /// if it's being used) + const char *getConfigDisplayHint(void) + { return myConfigDisplayHint.c_str(); } + + /// The handler for the response to the switch command + AREXPORT void clientSwitch(ArNetPacket *packet); + /// The handler for the packet to let the server know we're still talking to it + AREXPORT void netCentralHeartbeat(ArServerClient *client, + ArNetPacket *packet); + /// The handler for the packet that comes from the server so we know + /// we're getting these + AREXPORT void netCentralServerHeartbeat(ArServerClient *client, + ArNetPacket *packet); + + /// Parses the file for holding the user, password, and server key + AREXPORT bool parseFile(const char *fileName); + AREXPORT virtual void *runThread(void *arg); + + /// Sets debug logging + AREXPORT void setDebugLogging(bool debugLogging = false) + { myDebugLogging = debugLogging; } + /// Gets if this is using debug logging + AREXPORT bool getDebugLogging(void) { return myDebugLogging; } + + /// Gets the server client the forwarder is using (internal) + /** + @internal + **/ + AREXPORT ArServerClient* getServerClient(void) + { return myServerClient; } + + /// Adds central server or identifier not passed into the config + AREXPORT void addToConfig(const char *configSection, + const char *connectName, const char *connectDesc, + const char *addressName, const char *addressDesc); + + /// Adds a callback when we switch states while starting + AREXPORT void addFailedConnectCB( + ArFunctor1 *functor, int position = 50) + { myFailedConnectCBList.addCallback(functor, position); } + /// Removes a callback when we switch to running + AREXPORT void remFailedConnectCB(ArFunctor1 *functor) + { myFailedConnectCBList.remCallback(functor); } + + /// Adds a callback when we switch states while starting + AREXPORT void addConnectedCB( + ArFunctor1 *functor, int position = 50) + { myConnectedCBList.addCallback(functor, position); } + /// Removes a callback when we switch to running + AREXPORT void remConnectedCB(ArFunctor1 *functor) + { myConnectedCBList.remCallback(functor); } + + +protected: + AREXPORT void socketClosed(void); + ArServerBase *myServer; + ArArgumentParser *myParser; + std::string myServerDesc; + std::string myClientSoftwareDesc; + + ArServerClient *myServerClient; + ArTime myLastTcpHeartbeat; + ArTime myLastUdpHeartbeat; + + ArFileParser myFileParser; + + bool myServerHasHeartbeat; + double myServerHeartbeatTimeout; + double myServerUdpHeartbeatTimeout; + double myServerBackupTimeout; + + bool fileUserCallback(ArArgumentBuilder *arg); + bool filePasswordCallback(ArArgumentBuilder *arg); + bool fileServerKeyCallback(ArArgumentBuilder *arg); + + enum State + { + IDLE, ///< Don't want to connect + TRYING_CONNECTION, ///< If we're trying to connect + CONNECTING, ///< If we're waiting for the response from the server + CONNECTED, ///< If we're connected + LOST_CONNECTION ///< If we lost a connection... wait a bit and try again + }; + State myState; + ArTime myStartedState; + ArTime myLastConnectionAttempt; + //bool myGaveTimeWarning; + + bool processFile(void); + AREXPORT void switchState(State state); + + ArMutex myDataMutex; + + bool myTryConnection; + ArClientBase *myClient; + + std::string myUser; + std::string myPassword; + std::string myServerKey; + + std::string myCentralServer; + int myCentralServerPort; + std::string myIdentifier; + + std::string myEnforceProtocolVersion; + ArServerCommands::Type myEnforceType; + + bool myConfigFirstProcess; + bool myConfigConnectToCentralServer; + char myConfigCentralServer[1024]; + char myConfigIdentifier[1024]; + std::string myConfigDisplayHint; + + ArCallbackList1 myFailedConnectCBList; + ArCallbackList1 myConnectedCBList; + + bool myDebugLogging; + + ArRetFunctorC myParseArgsCB; + ArConstFunctorC myLogOptionsCB; + ArFunctorC mySocketClosedCB; + ArFunctor1C mySwitchCB; + ArFunctor2C myNetCentralHeartbeatCB; + ArFunctor2C myNetCentralServerHeartbeatCB; + ArRetFunctor1C myFileUserCB; + ArRetFunctor1C myFilePasswordCB; + ArRetFunctor1C myFileServerKeyCB; + ArRetFunctorC myProcessFileCB; + +}; + + +#endif // ARCLIENTSWITCH_H + diff --git a/Legacy/Aria/ArNetworking/include/ArHybridForwarderVideo.h b/Legacy/Aria/ArNetworking/include/ArHybridForwarderVideo.h new file mode 100644 index 0000000..63f9312 --- /dev/null +++ b/Legacy/Aria/ArNetworking/include/ArHybridForwarderVideo.h @@ -0,0 +1,88 @@ +#ifndef ARHYBRIDFORWARDERVIDEO_H +#define ARHYBRIDFORWARDERVIDEO_H + +#include "Aria.h" +#include "ArServerBase.h" +#include "ArClientBase.h" + +/// This class takes video another source and serves it back up +class ArHybridForwarderVideo : public ArCameraCollectionItem +{ +public: + /// Constructor that takes a client + AREXPORT ArHybridForwarderVideo(ArServerBase *server, ArClientBase *client); + /// Constructor that just takes a host and port and makes its own client + AREXPORT ArHybridForwarderVideo(ArServerBase *server, + const char *hostname = "localhost", + int port = 7070); + /// Destructor + AREXPORT virtual ~ArHybridForwarderVideo(); + + /// Returns if we're forwarding video or not + AREXPORT bool isForwardingVideo(void) const; + + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // ArCameraCollectionItem methods + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + /// Returns the name of the camera handled by this item. + AREXPORT virtual const char *getCameraName(); + + /// Sets the name of the camera handled by this item. + /** + * This method must be called before addToCameraCollection(). + **/ + AREXPORT virtual void setCameraName(const char *cameraName); + + /// Adds this item to the given camera collection. + AREXPORT virtual void addToCameraCollection(ArCameraCollection &collection); + + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Packet methods + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + /// Sends the last received video size (just gets this once) + AREXPORT void sendVideoSize(ArServerClient *client, ArNetPacket *packet); + /// Sends the last received video + AREXPORT void sendVideo(ArServerClient *client, ArNetPacket *packet); + /// Receives the video size (just gets this once) + AREXPORT void receiveVideoSize(ArNetPacket *packet); + /// Receives the video (and sets a timer to wait a bit and get it again) + AREXPORT void receiveVideo(ArNetPacket *packet); + /// Our callback that requests more video + AREXPORT void clientCycleCallback(void); + /// Sets how often after getting video we ask for it again + void setVideoRequestTime(int ms) { myVideoRequestTime = ms; } + /// Gets how often after getting video we ask for it again + int setVideoRequestTime(void) const { return myVideoRequestTime; } +protected: + AREXPORT void finishConstructor(void); + + std::string myCameraName; + + ArMutex myMutex; + bool myForwardingVideo; + ArNetPacket myReceivedVideoSize; + ArNetPacket myReceivedVideo; + ArNetPacket mySendVideoArgument; + ArTime myLastReceivedVideo; + ArTime myLastReqSent; + bool myReqSent; + int myVideoRequestTime; + ArServerBase *myServer; + ArClientBase *myClient; + ArFunctor2C *mySendVideoSizeCB; + ArFunctor2C *mySendVideoCB; + ArFunctor1C *myReceiveVideoSizeCB; + ArFunctor1C *myReceiveVideoCB; + ArFunctorC *myClientCycleCB; + + bool myIsSendVideoAvailable; +}; + + +#endif diff --git a/Legacy/Aria/ArNetworking/include/ArMapChanger.h b/Legacy/Aria/ArNetworking/include/ArMapChanger.h new file mode 100644 index 0000000..aa052e7 --- /dev/null +++ b/Legacy/Aria/ArNetworking/include/ArMapChanger.h @@ -0,0 +1,557 @@ +#ifndef ARMAPCHANGER_H +#define ARMAPCHANGER_H + +#include "ariaTypedefs.h" +#include "ariaUtil.h" + +#include + +#include +#include +#include + +#include "ArNetPacket.h" +#include "ArCentralForwarder.h" +#include "ArClientBase.h" +#include "ArClientSwitchManager.h" +#include "ArServerBase.h" +#include "ArServerClient.h" +#include "ArMapChanger.h" + +/// Utility class used to apply incremental changes to an Aria map. +/** + * ArMapChanger is a helper class that can send and receive ArMapChangeDetails + * over the network and apply them to an associated Aria map. An instance of + * ArMapChanger must be instantiated on both the client and the server side. + * (Note that there are two different versions of the constructors for this.) + * + * TODO: Possibly subclass this into ArClientMapChanger and ArServerMapChanger? + * + * @see ArMapChangeDetails +**/ +class ArMapChanger +{ +public: + + /// Reply status for a map change request + enum MapChangeReplyType { + CHANGE_FAILED = 0, + CHANGE_SUCCESS = 10 + }; + + /// Name of the network packet that contains the incremental map changes. + static const char *PROCESS_CHANGES_PACKET_NAME; + + /// Name of the network packet that contains incremental map changes originated by the robot. + static const char *PROCESS_ROBOT_CHANGES_PACKET_NAME; + + /// Name of a network packet that is broadcast when the map is being changed. + static const char *CHANGES_IN_PROGRESS_PACKET_NAME; + + /// Name of the network packet that is broadcast when map changes originated by the robot are complete. + static const char *ROBOT_CHANGES_COMPLETE_PACKET_NAME; + + // --------------------------------------------------------------------------- + // Constructors, Destructor + // --------------------------------------------------------------------------- + + /// Constructs a server map changer. + /** + * The map changer will automatically apply the received map change details + * to the given map. + * + * @param server the ArServerBase * that receives the network packets + * @param map the ArMapInterface * to which to apply the map changes + **/ + AREXPORT ArMapChanger(ArServerBase *server, + ArMapInterface *map); + + /// Constructs a server map changer that can also originate changes (to the EM). + /** + * The map changer will automatically apply the received map change details + * to the given map. + * + * @param clientSwitch the ArClientSwitchManager * that communicates to the EM + * @param server the ArServerBase * that receives the network packets + * @param map the ArMapInterface * to which to apply the map changes + **/ + AREXPORT ArMapChanger(ArClientSwitchManager *clientSwitch, + ArServerBase *server, + ArMapInterface *map); + + + /// Constructs a client map changer. + /** + * The map changer will send map change details to the server. The application + * must request this by calling sendMapChanges. + * + * @param client the ArClientBase * which is used to send the map change details + * @param infoNames the list of info names included in the map + **/ + AREXPORT ArMapChanger(ArClientBase *client, + const std::list &infoNames); + + /// Constructs a stand-alone map changer that will apply changes to the given map. + /** + * This method is primarily used for debugging. + * + * @param map the ArMapInterface * to which to apply the map changes + **/ + AREXPORT ArMapChanger(ArMapInterface *map); + + /// Destructor + AREXPORT virtual ~ArMapChanger(); + + // --------------------------------------------------------------------------- + // Main Methods + // --------------------------------------------------------------------------- + + /// Sends the given map changes from the client to the server. + AREXPORT virtual bool sendMapChanges(ArMapChangeDetails *changeDetails); + + /// Sends the given map changes from the robot to the central server. + AREXPORT virtual bool sendRobotMapChanges(ArMapChangeDetails *changeDetails); + + /// Applies the given map changes received from the client to the associated Aria map. + AREXPORT virtual bool applyMapChanges(ArMapChangeDetails *changeDetails); + + /// Transmits the given map change packet list from the client to the server. + AREXPORT virtual bool sendPacketList(const std::list &packetList); + + /// Transmit the given map change packet list from the robot to the central server. + AREXPORT virtual bool sendRobotPacketList(const std::list &packetList); + + // --------------------------------------------------------------------------- + // Callback Methods + // --------------------------------------------------------------------------- + + /// Adds a callback to be invoked after the map has been changed on the server. + /** + * This method is primarily used on the central server. After the map changes + * are successfully applied to its map, they are propagated to all of the + * connected robots. + **/ + AREXPORT virtual bool addChangeCB + (ArFunctor2 *> *functor); + + /// Removes a callback from the map change list. + AREXPORT virtual bool remChangeCB + (ArFunctor2 *> *functor); + + /// Adds a callback to be invoked after the remote reply has been received. + /** + * This method is primarily used on the robot. After the ARCL originated + * changes have been applied by the Enterprise Manager, this callback list + * is invoked for other interested parties. + **/ + AREXPORT virtual bool addRobotChangeReplyCB + (ArFunctor2 *functor); + + /// Removes a callback from the remote reply list. + AREXPORT virtual bool remRobotChangeReplyCB + (ArFunctor2 *functor); + + /// Adds a callback to be invoked before the map file is written. + /** + * This method is primarily used to temporarily make the server's directory + * writeable, if necessary. + **/ + AREXPORT virtual void addPreWriteFileCB(ArFunctor *functor, + ArListPos::Pos position = ArListPos::LAST); + + /// Removes a callback from the pre-write file list. + AREXPORT virtual void remPreWriteFileCB(ArFunctor *functor); + + /// Adds a callback to be invoked after the map file has been written. + /** + * This method is primarily used to restore the server's directory write status, + * if necessary. + **/ + AREXPORT virtual void addPostWriteFileCB(ArFunctor *functor, + ArListPos::Pos position = ArListPos::LAST); + + /// Removes a callback from the post-write file list. + AREXPORT virtual void remPostWriteFileCB(ArFunctor *functor); + +// ----------------------------------------------------------------------------- + +protected: + + /// Indicates the current stage of the map change network packets. + enum MapChangeCommand { + START_CHANGES = 0, ///< First packet that contains changes to be applied to the map + CONTINUE_CHANGES = 1, ///< Request to continue applying changes to the map + FINISH_CHANGES = 2, ///< Last packet that contains changes to be applied to the map + CANCEL_CHANGES = 3, ///< Cancel the request to change the map + LAST_CHANGE_COMMAND = CANCEL_CHANGES ///< Last value in the enumeration + }; + + /// Type of data contained in the map change network packet + enum MapChangeDataType { + NO_CHANGE = 0, ///< No change data + SUMMARY_DATA = 1, ///< Summary data, e.g. min/max pos, number of points + INFO_DATA = 2, ///< Any of the info data, e.g. MapInfo, RouteInfo + SUPPLEMENT_DATA = 3, ///< Miscellaneous supplemental data such as origin lat/long/alt + OBJECTS_DATA = 4, ///< Map objects, i.e. Cairn lines + POINTS_DATA = 5, ///< Map data points + LINES_DATA = 6, ///< Map data lines + LAST_CHANGE_DATA_TYPE = LINES_DATA ///< Last value in the enumeration + }; + + /// Miscellaneous constants + enum { + CHANGE_DATA_TYPE_COUNT = LAST_CHANGE_DATA_TYPE + 1, + CHANGE_COMMAND_COUNT = LAST_CHANGE_COMMAND + 1, + MAX_POINTS_IN_PACKET = 1000, + MAX_LINES_IN_PACKET = 500 + }; + + + // --------------------------------------------------------------------------- + // Packet Handlers + // --------------------------------------------------------------------------- + + /// Server handler for packets that contain map change details. + AREXPORT virtual void handleChangePacket(ArServerClient *client, + ArNetPacket *packet); + + AREXPORT virtual void handleRobotChangeReplyPacket(ArServerClient *client, + ArNetPacket *packet); + + /// Client handler for the results of applying the map changes on the server. + AREXPORT virtual void handleChangeReplyPacket(ArNetPacket *packet); + + /// Client handler for the map-changes-in-progress broadcast packet + AREXPORT virtual void handleChangesInProgressPacket(ArNetPacket *packet); + + /// Client handler for the server's idle-processing-pending broadcast packet + AREXPORT virtual void handleIdleProcessingPacket(ArNetPacket *packet); + + /// Client handler for when the robot disconnects or is shutdown. + AREXPORT virtual void handleClientShutdown(); + +protected: + + // --------------------------------------------------------------------------- + // Helper Methods + // --------------------------------------------------------------------------- + + // bool applyMapChanges(std::list &packetList); + + /// Applies all scan data changes that are contained in the given change details. + /** + * Scan data include summary data, map data points, and map data lines. + * If the map contains scan data for multiple sources, then this method + * applies all of the applicable changes. + * + * An Aria map must have been previously associated with the map changer. + **/ + bool applyScanChanges(ArMapChangeDetails *changeDetails); + + /// Applies scan data changes for the specified scan type. + /** + * @param changeDetails the ArMapChangeDetails * that describes how the map should + * be modified; must be non-NULL + * @param scanType the char * identifier of the scan type to be updated + * @param parser the ArFileParser used to parse the changeDetails + **/ + bool applyScanChanges(ArMapChangeDetails *changeDetails, + const char *scanType, + ArFileParser &parser); + + /// Applies the given map changes to the supplemental data in the map. + /** + * @param changeDetails the ArMapChangeDetails * that describes how the map should + * be modified; must be non-NULL + **/ + bool applySupplementChanges(ArMapChangeDetails *changeDetails); + + /// Applies the given map changes to the object data in the map. + /** + * @param changeDetails the ArMapChangeDetails * that describes how the map should + * be modified; must be non-NULL + **/ + bool applyObjectChanges(ArMapChangeDetails *changeDetails); + + /// Applies the given map changes to the info data in the map. + /** + * @param changeDetails the ArMapChangeDetails * that describes how the map should + * be modified; must be non-NULL + **/ + bool applyInfoChanges(ArMapChangeDetails *changeDetails); + + /// Determines whether the two given map objects are the same object. + /** + * If the objects have a name, then the name must be identical. Otherwise, the type + * and position must be the same. + **/ + bool isMatchingObjects(ArMapObject *obj1, + ArMapObject *obj2); + //ArMapChangeDetails *changeDetails); + + /// Creates a list of network packets for the given map change details. + bool convertChangeDetailsToPacketList(ArMapChangeDetails *changeDetails, + std::list *packetListOut, + bool isRelay = false); + + /// Unpacks the given network packet list and populates the given map change details. + bool convertPacketListToChangeDetails(std::list &packetList, + ArMapChangeDetails *changeDetailsOut); + + /// Creates network packets for the specified map change data and adds them to the given list. + /** + * @param dataType the MapChangeDataType that specifies which map data is to be added + * @param changeType the MapLineChangeType that specifies the type of map change (lines + * added or deleted) + * @param scanType the char * identifier of the scan source to add; valid only when + * dataType is SUMMARY_DATA + * @param extra an optional const char * identifier that clarifies which data to add; + * when dataType is INFO_DATA, this is the info name; otherwise, ignored + * @param fileLineSet the ArMapFileLineSet * component of the map change details that + * is to be converted to network packets + * @param packetListOut the list of ArNetPackets to which new packets are added + **/ + bool addFileLineSetPackets(MapChangeDataType dataType, + ArMapChangeDetails::MapLineChangeType changeType, + const char *scanType, + const char *extra, + ArMapFileLineSet *fileLineSet, + std::list *packetListOut); + + /// Inserts header information into the given network packet. + /** + * @param command the MapChangeCommand that specifies which command identifier to add to this packet + * @param dataType the MapChangeDataType that specifies which map data is to be added + * @param changeType the MapLineChangeType that specifies the type of map change (lines + * added or deleted) + * @param scanType the char * identifier of the scan source to add; valid only when + * dataType is SUMMARY_DATA + * @param packet the ArNetPacket * to be modified; must be non-NULL + **/ + void addHeaderToPacket(MapChangeCommand command, + MapChangeDataType dataType, + ArMapChangeDetails::MapLineChangeType changeType, + const char *scanType, + ArNetPacket *packet); + + /// Creates network packets for the specified file line group and adds them to the given list. + bool addGroupToPacketList(MapChangeDataType dataType, + ArMapChangeDetails::MapLineChangeType changeType, + const char *scanType, + ArMapFileLineGroup &group, + std::list *packetListOut); + + /// Creates network packets for the specified file line and adds them to the given list. + bool addFileLineToPacketList(MapChangeDataType dataType, + ArMapChangeDetails::MapLineChangeType changeType, + const char *scanType, + const ArMapFileLine &fileLine, + std::list *packetListOut); + + /// Creates network packets for the given map data points and adds them to the given list. + bool addPointsPackets(ArMapChangeDetails::MapLineChangeType changeType, + const char *scanType, + std::vector *pointList, + std::list *packetListOut); + + /// Creates network packets for the given map data lines and adds them to the given list. + bool addLinesPackets(ArMapChangeDetails::MapLineChangeType changeType, + const char *scanType, + std::vector *lineSegmentList, + std::list *packetListOut); + + /// Unpacks the header data from the given network packet. + /** + * @param packet the ArNetPacket * from which to extract the header information; + * must be non-NULL + * @param commandOut the MapChangeCommand * extracted from the packet + * @param origMapIdOut the original ArMapId * extracted from the packet + * @param newMapIdOut the optional new ArMapId * extracted from the packet + * @param dataTypeOut the optional MapChangeDataType * extracted from the packet + * @param changeTypeOut the optional MapLineChangeType * extracted from the packet + * @param scanTypeOut the optional std::string * extracted from the packet + * @return bool true if all of the header information was succesfully extracted; + * false, otherwise + **/ + bool unpackHeader(ArNetPacket *packet, + MapChangeCommand *commandOut, + ArMapId *origMapIdOut, + ArMapId *newMapIdOut = NULL, + MapChangeDataType *dataTypeOut = NULL, + ArMapChangeDetails::MapLineChangeType *changeTypeOut = NULL, + std::string *scanTypeOut = NULL); + + /// Unpacks the specified file line set from the given network packet. + /** + * The file line set is added to the given change details. + **/ + bool unpackFileLineSet(ArNetPacket *packet, + MapChangeDataType dataType, + ArMapChangeDetails::MapLineChangeType changeType, + const char *scanType, + int *numGroups, + int *numChildren, + ArMapChangeDetails *changeDetails); + + /// Unpacks the map data points for the specified scan from the given network packet. + /** + * The data points are added to the given change details. + **/ + bool unpackPoints(ArNetPacket *packet, + ArMapChangeDetails::MapLineChangeType changeType, + const char *scanType, + int *numPoints, + ArMapChangeDetails *changeDetails); + + /// Unpacks the map data lines for the specified scan from the given network packet. + /** + * The data lines are added to the given change details. + **/ + bool unpackLines(ArNetPacket *packet, + ArMapChangeDetails::MapLineChangeType changeType, + const char *scanType, + int *numLines, + ArMapChangeDetails *changeDetails); + + /// Resets all of the network packets in the given list so that they can be read again. + void resetPacketList(std::list *packetList); + + /// Waits for a reply from the server. + /** + * If a reply is not received within 30 seconds, this method will timeout and return + * false. + * + * @return bool true if the reply was received; false otherwise + **/ + bool waitForReply(ArTime &started); + + bool waitForCentralServerReply(ArTime &started); + + /// Determines whether idle processing is pending on the server. + bool isIdleProcessingPending(); + + /// Adds the given functor to the given callback list. + AREXPORT void addToCallbackList(ArFunctor *functor, + ArListPos::Pos position, + std::list *cbList); + + /// Removes the given functor from the given callback list. + AREXPORT void remFromCallbackList(ArFunctor *functor, + std::list *cbList); + +private: + /// Disabled copy constructor + ArMapChanger(const ArMapChanger &other); + + /// Disabled assignment operator + ArMapChanger &operator=(const ArMapChanger &other); + +protected: + + /// Accumulates the packet list that describes map changes received from a specified client. + struct ClientChangeInfo + { + public: + /// Constructor for changes received from a client + ClientChangeInfo(ArServerClient *client); + + /// Constructor for changes received from a robot on the CS + ClientChangeInfo(ArCentralForwarder *forwarder); + + /// Destructor + ~ClientChangeInfo(); + + /// Adds the given packet to the list + void addPacket(ArNetPacket *packet); + + /// Server client which sent the map changes... + ArServerClient *myClient; + + /// Or the forwarder that sent the map changes + ArCentralForwarder *myForwarder; + + /// Time at which the first packet in this list was received + ArTime myStartTime; + /// Time at which the most recent packet in this list was received + ArTime myLastActivityTime; + /// List of network packets received from the client for these map changes + std::list myPacketList; + }; // end struct ClientChangeInfo + + + /// Aria map currently in use + ArMapInterface *myMap; + /// Copy of the current Aria map, used to make sure the changes can be successfully made + ArMapInterface *myWorkingMap; + + /// Change details to apply to the Aria map + ArMapChangeDetails *myChangeDetails; + /// Number of info types in the associated Aria map + //int myInfoCount; + + /// List of info types in the associated info map + std::list myInfoNames; + + /// Associated server base; non-NULL only when changer instantiated on the server + ArServerBase *myServer; + + /// Associated client switch manager; non-NULL when changer instantiated on robot with EM + ArClientSwitchManager *myClientSwitch; + + /// Whether the client switch manager's serverClient has been initialized with a handler (for EM) + bool myIsServerClientInit; + + + /// Mutex that protects access to the myClient member + ArMutex myClientMutex; + /// Associated client base; non-NULL only when changer instantiated on the client + ArClientBase *myClient; + + /// Mutex that protects access to the myClientInfo member + ArMutex myClientInfoMutex; + /// Information regarding the server client that is currently sending map changes + ClientChangeInfo *myClientInfo; + + /// Mutex that protects access to the interleave data + ArMutex myInterleaveMutex; + /// Whether the client is ready to send another packet + bool myReadyForNextPacket; + /// Whether the client is waiting for a reply from the server + bool myIsWaitingForReturn; + + /// Mutex that protects access to the myIsIdleProcessingPending member + ArMutex myIdleProcessingMutex; + /// Whether the server has data to process once it becomes idle + bool myIsIdleProcessingPending; + + /// List of callbacks to be invoked before the changed map file is written + std::list myPreWriteCBList; + /// List of callbacks to be invoked after the changed map file is written + std::list myPostWriteCBList; + + /// List of server client callbacks to be invoked after the map has been changed + std::list< ArFunctor2 *> *> + myChangeCBList; + + /// List of server client callbacks to be invoked after the map has been changed + std::list< ArFunctor2 *> myRobotChangeReplyCBList; + + /// Server handler for the network packets that describe map changes. + ArFunctor2C myHandleChangePacketCB; + + ArFunctor2C myHandleRobotReplyPacketCB; + + /// Client handler for the map-changes-in-progress packet + ArFunctor1C myHandleChangesInProgressPacketCB; + /// Client handler for the reply packet + ArFunctor1C myHandleReplyPacketCB; + /// Client handler for the idle-processing-in-progress packet + ArFunctor1C myHandleIdleProcessingPacketCB; + /// Handler invoked when the client shuts down + ArFunctorC myClientShutdownCB; + +}; // end class ArMapChanger + +#endif // ARMAPCHANGER diff --git a/Legacy/Aria/ArNetworking/include/ArNetPacket.h b/Legacy/Aria/ArNetworking/include/ArNetPacket.h new file mode 100644 index 0000000..00781fb --- /dev/null +++ b/Legacy/Aria/ArNetworking/include/ArNetPacket.h @@ -0,0 +1,84 @@ +#ifndef NLNETPACKET_H +#define NLNETPACKET_H + +#include "Aria.h" + +/// our packet for the network stuff +class ArNetPacket : public ArBasePacket +{ +public: + /// Constructor + AREXPORT ArNetPacket( + ArTypes::UByte2 bufferSize = ArNetPacket::MAX_LENGTH + 5); + + /// Copy constructor + AREXPORT ArNetPacket(const ArNetPacket &other); + + /// Assignment operator + AREXPORT ArNetPacket &operator=(const ArNetPacket &other); + + /// Destructor + AREXPORT virtual ~ArNetPacket(); + + + /// Sets the command this packet is + AREXPORT void setCommand(ArTypes::UByte2 command); + /// Gets the command this packet is + AREXPORT ArTypes::UByte2 getCommand(void); + enum { + SIZE_OF_LENGTH = 2, ///< Number of bytes needed to store packet length value + MAX_LENGTH = 32000, ///< Suggested maximum total size of a packet (bytes) + HEADER_LENGTH = 6, ///< Bytes of packet data used for header + FOOTER_LENGTH = 2, ///< Byset of packet data used for footer + + /** Suggested maximum size for data payload (this is the total suggested + packet size minus headers and footers) + */ + MAX_DATA_LENGTH = MAX_LENGTH - HEADER_LENGTH - FOOTER_LENGTH - SIZE_OF_LENGTH + }; + + /// Puts a double into the packet buffer + AREXPORT virtual void doubleToBuf(double val); + /// Gets a double from the packet buffer + AREXPORT virtual double bufToDouble(void); + AREXPORT virtual void empty(void); + AREXPORT virtual void finalizePacket(void); + AREXPORT virtual void resetRead(void); + AREXPORT virtual void duplicatePacket(ArNetPacket *packet); + + /// returns true if the checksum matches what it should be + AREXPORT bool verifyCheckSum(void); + /// returns the checksum, probably used only internally + AREXPORT ArTypes::Byte2 calcCheckSum(void); + + /// Iternal function that sets if we already added the footer(for forwarding) + bool getAddedFooter(void) { return myAddedFooter; } + /// Iternal function that sets if we already added the footer(for forwarding) + void setAddedFooter(bool addedFooter) { myAddedFooter = addedFooter; } + + /// an enum for where the packet came from + enum PacketSource + { + TCP, ///< Came in over tcp + UDP ///< Came in over udp + }; + PacketSource getPacketSource(void) { return myPacketSource; } + void setPacketSource(PacketSource source) { myPacketSource = source; } + void setArbitraryString(const char *string) { myArbitraryString = string; } + const char *getArbitraryString(void) { return myArbitraryString.c_str(); } + +private: + + /// Inserts the header information (command, length, etc.) into the buffer. + void insertHeader(); + + +protected: + PacketSource myPacketSource; + bool myAddedFooter; + std::string myArbitraryString; + ArTypes::UByte2 myCommand; +}; + + +#endif diff --git a/Legacy/Aria/ArNetworking/include/ArNetPacketReceiverTcp.h b/Legacy/Aria/ArNetworking/include/ArNetPacketReceiverTcp.h new file mode 100644 index 0000000..eb96486 --- /dev/null +++ b/Legacy/Aria/ArNetworking/include/ArNetPacketReceiverTcp.h @@ -0,0 +1,79 @@ +#ifndef NLNETPACKETRECEIVERTCP_H +#define NLNETPACKETRECEIVERTCP_H + +#include "Aria.h" +#include "ArNetPacket.h" + +/** + This class receives TCP packets from a socket, you need to have an + open socket and give it to the socket with setSocket, then you need + to set up a callback to process packets with setProcessPacketCB, + finally call readData which will read in all the data and call the + processPacketCB. +**/ +class ArNetPacketReceiverTcp +{ +public: + /// Constructor + AREXPORT ArNetPacketReceiverTcp(); + /// Destructor + AREXPORT ~ArNetPacketReceiverTcp(); + + /// Sets the socket this receiver uses + AREXPORT void setSocket(ArSocket *socket); + /// Gets the socket this receiver uses + AREXPORT ArSocket *getSocket(void); + + /// Sets the callback for use when a packet is received + AREXPORT void setProcessPacketCB(ArFunctor1 *functor); + + /// Gets the callback used when a packet is received + AREXPORT ArFunctor1 *getProcessPacketCB(void); + + /// Sets the logging prefix + AREXPORT void setLoggingPrefix(const char *loggingPrefix); + + /// Reads in all the data available calling the processPacketCB + AREXPORT bool readData(void); + + /// Sets whether we're quiet about errors or not + void setQuiet(bool quiet) { myQuiet = quiet; } + /// Gets whether we're quiet about errors or not + bool getQuiet(void) { return myQuiet; } +protected: + enum Ret { + RET_CONN_CLOSED, // the connection was closed (in a good manner) + RET_CONN_ERROR, // the connection was has an error (so close it) + RET_GOT_PACKET, // we got a good packet + RET_BAD_PACKET, // we got a bad packet (checksum wrong) + RET_FAILED_READ, // our read failed (no data) + RET_TIMED_OUT}; // we were reading and timed out + /// Reads in a single packet, returns NULL if not one + AREXPORT Ret readPacket(int msWait); + + + enum State { STATE_SYNC1, STATE_SYNC2, STATE_LENGTH1, + STATE_LENGTH2, STATE_ACQUIRE_DATA }; + + enum { + TOTAL_PACKET_LENGTH = ArNetPacket::MAX_LENGTH+ArNetPacket::HEADER_LENGTH+ArNetPacket::FOOTER_LENGTH + }; + + State myState; + ArFunctor1 *myProcessPacketCB; + bool myQuiet; + ArSocket *mySocket; + ArTime myLastPacket; + ArNetPacket myPacket; + + + char myReadBuff[TOTAL_PACKET_LENGTH]; + int myReadCount; + int myReadLength; + int myReadCommand; + unsigned char mySync1; + unsigned char mySync2; + std::string myLoggingPrefix; +}; + +#endif // NLNETPACKETRECEIVERTCP diff --git a/Legacy/Aria/ArNetworking/include/ArNetPacketReceiverUdp.h b/Legacy/Aria/ArNetworking/include/ArNetPacketReceiverUdp.h new file mode 100644 index 0000000..64393e0 --- /dev/null +++ b/Legacy/Aria/ArNetworking/include/ArNetPacketReceiverUdp.h @@ -0,0 +1,41 @@ +#ifndef NLNETPACKETRECEIVERUDP_H +#define NLNETPACKETRECEIVERUDP_H + +#include "ArNetPacket.h" + +/** + This is the receiver for UDP packets. +**/ + +class ArNetPacketReceiverUdp +{ +public: + AREXPORT ArNetPacketReceiverUdp(); + AREXPORT ~ArNetPacketReceiverUdp(); + + /// Sets the socket this receiver uses + AREXPORT void setSocket(ArSocket *socket); + /// Gets the socket this receiver uses + AREXPORT ArSocket *getSocket(void); + + /// Sets the callback for use when a packet is received + AREXPORT void setProcessPacketCB(ArFunctor2 *functor); + + /// Gets the callback used when a packet is received + AREXPORT ArFunctor2 * + getProcessPacketCB(void); + + /// Reads in all the data available calling the processPacketCB + AREXPORT bool readData(void); + +protected: + ArFunctor2 *myProcessPacketCB; + ArSocket *mySocket; + ArTime myLastPacket; + ArNetPacket myPacket; + char myBuff[ArNetPacket::MAX_LENGTH+20]; + +}; + +#endif // NLNETPACKETRECEIVERUDP_H diff --git a/Legacy/Aria/ArNetworking/include/ArNetPacketSenderTcp.h b/Legacy/Aria/ArNetworking/include/ArNetPacketSenderTcp.h new file mode 100644 index 0000000..4404cca --- /dev/null +++ b/Legacy/Aria/ArNetworking/include/ArNetPacketSenderTcp.h @@ -0,0 +1,51 @@ +#ifndef ARNETPACKETSENDERTCP_H +#define ARNETPACKETSENDERTCP_H + +#include "Aria.h" +#include "ArNetPacket.h" + +class ArNetPacketSenderTcp +{ +public: + /// Constructor + AREXPORT ArNetPacketSenderTcp(); + /// Destructor + AREXPORT ~ArNetPacketSenderTcp(); + + /// Sets the socket this sender uses + AREXPORT void setSocket(ArSocket *socket); + /// Gets the socket this sender uses + AREXPORT ArSocket *getSocket(void); + + /// Sets the connection timeout + AREXPORT void setBackupTimeout(double connectionTimeoutInMins); + + /// Sets debug logging + AREXPORT void setDebugLogging(bool debugLogging); + + /// Sets the logging prefix + AREXPORT void setLoggingPrefix(const char *prefix); + + /// Sends a packet + AREXPORT void sendPacket(ArNetPacket *packet, + const char *loggingString = ""); + + /// Tries to send the data there is to be sent + AREXPORT bool sendData(void); +protected: + ArMutex myDataMutex; + bool myDebugLogging; + std::string myLoggingPrefix; + ArLog::LogLevel myVerboseLogLevel; + ArSocket *mySocket; + std::list myPacketList; + ArNetPacket *myPacket; + int myAlreadySent; + const char *myBuf; + int myLength; + double myBackupTimeout; + ArTime myLastGoodSend; + +}; + +#endif diff --git a/Legacy/Aria/ArNetworking/include/ArNetworking.h b/Legacy/Aria/ArNetworking/include/ArNetworking.h new file mode 100644 index 0000000..a01448c --- /dev/null +++ b/Legacy/Aria/ArNetworking/include/ArNetworking.h @@ -0,0 +1,188 @@ +#ifndef ARNETWORKING_H +#define ARNETWORKING_H + +#include "ArServerBase.h" +#include "ArServerClient.h" +#include "ArServerCommands.h" +#include "ArClientBase.h" +#include "ArClientCommands.h" +#include "ArMapChanger.h" +#include "ArServerHandlerCamera.h" +#include "ArServerHandlerCameraCollection.h" +#include "ArServerHandlerCommMonitor.h" +#include "ArServerHandlerCommands.h" +#include "ArServerHandlerPopup.h" +#include "ArServerInfoDrawings.h" +#include "ArServerInfoRobot.h" +#include "ArServerInfoSensor.h" +#include "ArServerHandlerMap.h" +#include "ArServerMode.h" +#include "ArServerModeDrive.h" +#include "ArServerModeRatioDrive.h" +#include "ArServerModeStop.h" +#include "ArServerModeWander.h" +#include "ArServerHandlerConfig.h" +#include "ArClientHandlerConfig.h" +#include "ArHybridForwarderVideo.h" +#include "ArServerSimpleCommands.h" +#ifndef WIN32 +#include "ArServerFileUtils.h" +#endif +#include "ArClientFileUtils.h" +#include "ArServerUserInfo.h" +#include "ArClientSimpleConnector.h" +#include "ArServerHandlerMapping.h" +#include "ArServerSimpleOpener.h" +#include "ArServerInfoStrings.h" +#include "ArClientArgUtils.h" +#include "ArServerHandlerPopup.h" +#include "ArCentralManager.h" +#include "ArCentralForwarder.h" +#include "ArClientSwitchManager.h" +#include "ArServerModeIdle.h" +#include "ArTempDirectoryHelper.h" + +/** + \mainpage ArNetworking + + MobileRobots Advanced Robotics Networking Infrastructure (ArNetworking) + Developer's API Reference Manual
+ Copyright 2005 ActivMedia Robotics, LLC. All rights reserved.
+ Copyright 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. All rights reserved. + + + ArNetworking is an extensible networking protocol and infrastructure. It + is used to add networking services to a robot control program, integrated + with ARIA and other MobileRobots software libraries. + + ArNetworking is used to set up a client-server architecture. A client + issues requests to a server to issue a single command the server, + or to start retrieving data from the server at a specified time interval. + A request type is identified by a short string. + + A client may be an operator's graphical interface, or a component requiring + off-board resources (such as a multi-robot planning system, for example). + However, a program onboard the robot could also implement a client, and issue + requests to an offboard server (e.g. to retrieve data from a central database). + + In a typical application, however, a program acting as the server runs on the robot's + computer, and uses ARIA (and possibly ARNL or SONARNL) to control the robot. + This creates a three-tier system: the robot itself is the first tier, and acts as a + "robot server" to a program on its onboard computer which is simultaneously a + "robot client" and an "ArNetworking server". Offboard ArNetworking clients are the final + tier. This three-tier architecture allows a tight, reliable control loop between the robot + control program on the onboard computer, and removes higher level user-interface clients + accross the potentially unreliable network, protecting the more critical robot control program, + and providing a more immediate and flexible user interface. + + ArNetworking can use both TCP and UDP. + + \image html ArNetworking_overview.png Abstract overview of ArNetworking in a typical client-server configuration with one client issuing requests to a server + + \section Servers Servers + + An ArNetworking server program is comprised of an ArServerBase object, to which + callback functors are added for each request type you wish to handle (keyed + by a request identifier string, though this string is internally converted + into a more efficient integer value) using ArServerBase::addData(). + These callbacks are often encapsulated in "ServerHandler" or "ServerInfo" + classes. The ArNetworking library provides a variety of prewritten classes for + providing current state information about the robot, and for teleoperation + control. A callback functor for a request, when invoked, receives an ArNetPacket + object containing the request's payload data, and a pointer + to an object used to send a reply packet to the client. + ArServerBase creates a background thread to asyncronously accept client connections + and receive clients' requests, while your main program thread executes simultaneously. + This thread runs in a loop, and you may add general-purpose callback functors + to be invoked each cycle of this loop using ArServerBase::addCycleCallback(). + + To simplify server program setup, a helper class ArServerSimpleOpener is available. + + The default port number for an ArServerBase object to open is 7272, though + an alternate port number may be used via a command line argument to the program, + or specified in the ArServerBase constructor. + + \subsection ServerModes Server Modes + + ArNetworking also provides a system of server mode classes (see ArServerMode + base class). The server may only be in one mode at a time, each of which + enables and disables ARIA ArAction objects. + + \subsection SimpleServerCommands Simple Server Commands + + ArNetworking includes the ArServerHandlerCommands class that provides a very + simple API for simple "command" requests: requests, perhaps with a few + parameters, that simply perform some action or change some state, and have + no data to reply with. Callback functors added for requests via + an ArServerHandlerCommands object do not receive the request packet data, so they + do not need to do any decoding of that data. Additionally, ArServerHandlerCommands + keeps a list of requests that it manages, which is available to clients. + ArNetworking includes some prewritten classes (ArServerSimpleCom*) which + simply add new commands to an ArServerHandlerCommands object and encapsulate their + request callbacks. + + For example, MobileEyes queries this list on + connection, and if some of these simple + commands are available, it makes a menu in the toolbar called Custom Commands + accessible. This is a way to make special features of your custom robot server + application controllable from MobileEyes. + + \subsection ARNLServerClasses Networking in ARNL and SONARNL + + The ARNL and SONARNL libraries contain some ServerHandler/ServerInfo classes + that implement useful server requests, as well as server Mode classes. + + \subsection PreMadeServices Standard Services Available in ArNetworking + + These are some of the pre-written services which are available in the ArNetworking + library for you to use in your server programs. To use these services, your + server program typically only needs to create and retain an instance of the class, + though some require some additional setup. + +
    +
  • ArServerInfoRobot - Supplies clients with basic robot state information (current position and velocity, active server mode and status, battery voltage)
  • +
  • ArServerInfoSensor - Supplies clients with current sensor readings (Sonar or Laser)
  • +
  • ArServerHandlerMap - Supplies clients with data from an ArMap
  • +
  • ArServerInfoDrawings - Supplies clients with a set of graphical figures to be displayed with the map (e.g. point sets, lines, circles)
  • +
  • ArServerHandlerCamera - Allows clients to control a pan-tilt camera and provides information about its current position
  • +
  • ArServerInfoStrings - A set of general purpose key,value string pairs obtained from a global table (See Aria::getInfoGroup())
  • +
  • ArServerHandlerMapping - Allows clients to trigger collection of laser scan data for use in making a map later (with the Mapper3 application)
  • +
  • ArServerFileToClient, ArServerFileFromClient, ArServerFileLister - Allows clients to upload and download files from the server filesystem
  • +
+ + + \section Clients Clients + + A client program is comprised of an ArClientBase object which must be connected + to a server via a network socket (either TCP or the default, UDP). The server is + identified by network hostname and port number, which may be given + through ArClientBase API or in the program command line arguments. Requests + are made to the server via ArClientBase::request() or ArClientBase::requestOnce(). + Callback functors may be added to the ArClientBase object to receive reply packets. + ArClientBase creates a background thread to asyncronously communicate with the server. + + A client may query a server to discover if a data request type is available using + ArClientBase::dataExists(). + + To simplify client program setup and connection to a server, a helper class + ArClientSimpleConnector is available. + + + \section Auth Authenticated Connections + + A simple scheme for authenticated connections is available in ArNetworking. + When connecting to a server, a client may supply a username and password. + If the server has loaded a user info file, it may reject a connection + with an incorrect password. Data requests may be categorized into + command groups, and which command groups are allowed to which users may + be specified in the user info file. + + The login process is not impossible to defeat with some concerted effort and expertise, + but is sufficient to prevent basic attempts at unauthorized use of a server, and + to present only relevant features for different users' purposes. + + See ArServerBase for more discussion. + +**/ + +#endif // ARNETWORKING diff --git a/Legacy/Aria/ArNetworking/include/ArServerBase.h b/Legacy/Aria/ArNetworking/include/ArServerBase.h new file mode 100644 index 0000000..cfe9a22 --- /dev/null +++ b/Legacy/Aria/ArNetworking/include/ArServerBase.h @@ -0,0 +1,513 @@ +#ifndef NLSERVERBASE_H +#define NLSERVERBASE_H + +#include "Aria.h" +#include "ArServerCommands.h" +#include "ArServerClient.h" +#include "ArServerData.h" +#include "ArNetPacket.h" +#include "ArNetPacketReceiverUdp.h" +#include "ArServerUserInfo.h" + +/** + Base server for all networking services. + + This class is the "base" server for network services. Start + this server by calling open(), and then running the loop with run() or runAsync(), + (or loopOnce() if it is absolutely neccesary to use your own loop; see the + implementation of run()). + You can then pass this object to the various "ArServerInfo", "ArServerHandler", and ArServerMode classes. + + Data request callbacks are added to an ArServerBase object by calling + addData(). + + This class takes care of locking in its own function calls so you + don't need to worry about locking and unlocking the class before + you do things. + + The counterpart of this class for clients is ArClientBase. + + You can require user names and passwords for making connections to + the server, so each user has a set of permissions for different + command groups. To do this, load configuration from a userInfo file + with loadUserInfo(). You can log the + user info (and what commands users have) with logUserInfo(). You can + log the command groups with logCommandGroups() or + logCommandGroupsToFile(). For a description of the file see + ArServerUserInfo. There is also an example in + ArNetworking/examples/serverDemo.userInfo. + + In addition to the user and password requirement you can set a server "key" + (a special string of text) required (in addition to user and password) + to access the server with setServerKey(), though this is ONLY used if + user and password information is requied (so that older clients can + connect if there's no user and password information required). + + The way that the passwords are transmitted across the network is this: + Upon connection the server sends a randomly generated (for that + connection) string of text to the client which we'll call the + passwordKey. The client then combines the serverKey (a string which must be + known to connect to the server at all), the password, and the + passwordKey (that string that is generated uniquely for each + connection) and comes up with an md5 of that string and sends that + md5 value across the line. The server then compares the md5 from + the client with the md5 generated with the correct information on + the server... if they match the password is good, otherwise it + rejects the connection. This is NOT perfect security but should be + much better then plaintext. If you care about perfect security + then use an ssh tunnel with something like PUTTY from the machine + the client is on to the machine the server is on with an openssh + server set up (this'll likely even work in windows with cygwin) and + set up a firewall on the machine the server is on that disallows + port the server port connection from outside and only allows ssh + from outside (and get a book or three and read those). + + This class now handles identifiers for the ArServerClients... all + server bases will let a client set a self identifier string, and a + here goal... those may be used by any server. Messages can be sent + to just server clients that match that message (so that its easier + to send messages to people who sent commands). + + Master servers (the main connection server base on the central + server) can also give each connection an id number (with + identGetConnectionID). Things that then connect to the other + server bases on a master server (slave servers) should then set + their ConnectionID (with identSetConnectionID) so that things can + relate the different connections together. + + @sa ArServerSimpleOpener + @sa ArClientBase + @sa ArServerMode +**/ + +class ArServerBase: public ArASyncTask +{ +public: + /// Constructor + AREXPORT ArServerBase( + bool addAriaExitCB = true, + const char *serverName = "", + bool addBackupTimeoutToConfig = true, + const char *backupTimeoutName = "RobotToClientTimeoutInMins", + const char *backupTimeoutDesc = "The amount of time the central server can go without sending a packet to the robot successfully (when there are packets to send). A number less than 0 means this won't happen. The time is in minutes but takes doubles (ie .5) (5 seconds is used if the value is positive, but less than that amount)", + bool masterServer = false, bool slaveServer = false, + bool logPasswordFailureVerbosely = false, + bool allowSlowPackets = true, bool allowIdlePackets = true, + int maxClientsAllowed = -1); + + /// Destructor + AREXPORT virtual ~ArServerBase(); + + /// Opens the server to accept new client connections + AREXPORT bool open(unsigned int port, const char *openOnIP = NULL, + bool tcpOnly = false); + /// Closes the server + AREXPORT void close(void); + /// Runs the server loop once + AREXPORT void loopOnce(void); + + /// Adds a callback to be called when requests for some data are recieved. + AREXPORT bool addData(const char *name, const char *description, + ArFunctor2 *functor, + const char *argumentDescription, + const char *returnDescription, + const char *commandGroup = NULL, + const char *dataFlags = NULL); + + /// Loads up a set of usernames/passwords/permissions from a file + AREXPORT bool loadUserInfo(const char *fileName, + const char *baseDirectory = ""); + + /// Logs the users and their groups + AREXPORT void logUserInfo(void); + + /// Logs the groups and commands in those groups + AREXPORT void logCommandGroups(void); + + /// Logs the groups and commands in those groups to a file + AREXPORT void logCommandGroupsToFile(const char *fileName); + + /// Logs the command group names and command group descriptions for those names + AREXPORT void setGroupDescription(const char *GrpName, const char *GrpDesc); + + /// Logs the command group names and descriptions + AREXPORT void logGroupDescriptions(void); + + /// Logs the command group names and descriptions to a file + AREXPORT void logGroupDescriptionsToFile(const char *fileName); + + /// Sets a 'key' needed to access the server through any account + AREXPORT void setServerKey(const char *serverKey); + + + /// Tells the server to reject connectings because we're usinga central server + AREXPORT void rejectSinceUsingCentralServer( + const char *centralServerIPString); + + /// Enforces that the server is using this protocol version + AREXPORT void enforceProtocolVersion(const char *protocolVersion); + + /// Enforces that the robots that connect are this type + AREXPORT void enforceType(ArServerCommands::Type type); + + /// Sets the backup timeout + AREXPORT void setBackupTimeout(double timeoutInMins); + + /// Runs the server in this thread + AREXPORT virtual void run(void); + + /// Runs the server in its own thread + AREXPORT virtual void runAsync(void); + + /// Logs the connections + AREXPORT void logConnections(const char *prefix = ""); + + /// Gets the number of clients connected + AREXPORT int getNumClients(void); + + /// Gets the number of a command + AREXPORT unsigned int findCommandFromName(const char *command); + + /// Broadcasts packets to any client wanting this data + AREXPORT bool broadcastPacketTcp(ArNetPacket *packet, const char *name); + + /// Broadcasts packets to any client wanting this data that matches the ID + AREXPORT bool broadcastPacketTcpToMatching( + ArNetPacket *packet, const char *name, + ArServerClientIdentifier identifier, bool matchConnectionID = false); + + /// Broadcasts packets to any client wanting this data + AREXPORT bool broadcastPacketTcpWithExclusion( + ArNetPacket *packet, const char *name, + ArServerClient *excludeClient, bool match = false, + ArServerClientIdentifier identifier = ArServerClientIdentifier(), + bool matchConnectionID = false); + + /// Broadcasts packets to any client wanting this data + AREXPORT bool broadcastPacketUdp(ArNetPacket *packet, const char *name); + + /// Broadcasts packets to any client wanting this data + AREXPORT bool broadcastPacketUdpWithExclusion( + ArNetPacket *packet, const char *name, ArServerClient *excludeClient, + bool match = false, + ArServerClientIdentifier identifier = ArServerClientIdentifier(), + bool matchConnectionID = false); + + /// Broadcasts packets to any client wanting this data that matches + AREXPORT bool broadcastPacketUdpToMatching( + ArNetPacket *packet, const char *name, + ArServerClientIdentifier identifier, bool matchConnectionID); + + /// Delays the current thread by the specified msecs, for use after packet sent. + AREXPORT void sleepAfterSend(int msecDelay); + + /// Sees if we have any idle processing pending (idle packets or callbacks) + AREXPORT bool idleProcessingPending(void); + + /// Processes udp packets + AREXPORT void processPacket(ArNetPacket *packet, + struct sockaddr_in *sin); + + /// Sends Udp packets + AREXPORT bool sendUdp(ArNetPacket *packet, + struct sockaddr_in *sin); + + /// Logs the tracking on each client (how many packets and bytes were sent) + AREXPORT void logTracking(bool terse = true); + + /// Clears the tracking on all the clients (resets counters) + AREXPORT void resetTracking(void); + + // the function for the thread + AREXPORT virtual void * runThread(void *arg); + + /// Gets the tcp port we're using + AREXPORT unsigned int getTcpPort(void); + /// Gets the udp port we're using + AREXPORT unsigned int getUdpPort(void); + /// Gets the IP we're opening on (or NULL if there's none) + AREXPORT const char *getOpenOnIP(void); + + /// Add a callback to be called at every cycle + AREXPORT void addCycleCallback(ArFunctor* functor); + + /// Remove a callback to be called at every cycle + AREXPORT void remCycleCallback(ArFunctor* functor); + + /// Add a callback to be invoked when a client has been removed (but before it is deleted) + AREXPORT void addClientRemovedCallback(ArFunctor1 *functor); + /// Remove the callback invoked when a client has been removed + AREXPORT void remClientRemovedCallback(ArFunctor1 *functor); + /// Makes a new serverclient from this socket (for switching, needs no password since this was an outgoing connection to a trusted server) + AREXPORT ArServerClient *makeNewServerClientFromSocket( + ArSocket *socket, bool overrideGeneralReject); + /// Gets the user info we're using (mostly internal for switching) + AREXPORT const ArServerUserInfo *getUserInfo(void) const; + /// Sets the user info we'll use (mostly internal for switching) + AREXPORT void setUserInfo(const ArServerUserInfo *userInfo); + /// Adds a callback for requests in a more advanced manner, for internal use + AREXPORT bool addDataAdvanced( + const char *name, const char *description, + ArFunctor2 *functor, + const char *argumentDescription, const char *returnDescription, + const char *commandGroup = NULL, const char *dataFlags = NULL, + unsigned int commandNumber = 0, + ArFunctor2 *requestChangedFunctor = NULL, + ArRetFunctor2 + *requestOnceFunctor = NULL); + /// Sets the data flags to add in addition to those passed in + AREXPORT void setAdditionalDataFlags(const char *additionalDataFlags); + /// Gets the frequncy a command is requested (mostly internal) + AREXPORT long getFrequency(unsigned int command, + bool internalCall = false); + /// Broadcasts packets to any client wanting this data + AREXPORT bool broadcastPacketTcpByCommand( + ArNetPacket *packet, unsigned int command); + + /// Broadcasts packets to any client wanting this data + AREXPORT bool broadcastPacketTcpByCommandWithExclusion( + ArNetPacket *packet, unsigned int command, + ArServerClient *excludeClient, bool match = false, + ArServerClientIdentifier identifier = ArServerClientIdentifier(), + bool matchConnectionID = false); + + /// Broadcasts packets to any client wanting this data + AREXPORT bool broadcastPacketUdpByCommand( + ArNetPacket *packet, unsigned int command); + + /// Broadcasts packets to any client wanting this data + AREXPORT bool broadcastPacketUdpByCommandWithExclusion( + ArNetPacket *packet, unsigned int command, + ArServerClient *excludeClient, bool match = false, + ArServerClientIdentifier identifier = ArServerClientIdentifier(), + bool matchConnectionID = false); + + /// Closes connection with a given connection ID + AREXPORT void closeConnectionID(ArTypes::UByte4 idNum); + /// Returns if a command has a data flag + AREXPORT bool dataHasFlag(const char *name, const char *dataFlag); + /// Returns if a command has a data flag by command number + AREXPORT bool dataHasFlagByCommand(unsigned int command, + const char *dataFlag); + /// Sets debug logging + AREXPORT void setDebugLogging(bool debugLogging = false); + /// Gets if this is using debug logging + AREXPORT bool getDebugLogging(void); + /// Gets the most clients we've had connected + AREXPORT int getMostClients(void); + + /// Gets if we're allowing idle packets + AREXPORT bool allowingIdlePackets(void); + + /// Adds an idle callback to be called once next time the robot is idle + AREXPORT bool addIdleSingleShotCallback(ArFunctor *functor); + + /// Internal, Sees if we have any slow packets we are waiting to process + AREXPORT bool hasSlowPackets(void); + + /// Internal, Sees if we have any idle packets we are waiting to process + AREXPORT bool hasIdlePackets(void); + + /// Internal, Sees if we have any idle callbacks we are waiting to process + AREXPORT bool hasIdleCallbacks(void); + + /// Internal, sets the maximum number of clients + AREXPORT void internalSetNumClients(int numClients); + + /// Adds a callback when we switch states while starting + AREXPORT void addTooManyClientsCB( + ArFunctor1 *functor, int position = 50) + { myTooManyClientsCBList.addCallback(functor, position); } + /// Removes a callback when we switch to running + AREXPORT void remTooManyClientsCB(ArFunctor1 *functor) + { myTooManyClientsCBList.remCallback(functor); } + + /// Internal call that sets the default frequency as a helper for forwarding (if it's faster than the current default) + AREXPORT bool internalSetDefaultFrequency(const char *command, int frequency); + + /// Internal call to lockup the server (for testing) + AREXPORT void internalLockup(void); +protected: + + /// The command get the ConnectionID of this server client connection + AREXPORT void identGetConnectionID(ArServerClient *client, + ArNetPacket *packet); + /// The command set the ConnectionID of this server client connection + AREXPORT void identSetConnectionID(ArServerClient *client, + ArNetPacket *packet); + /// The command set the self identifier of this server client connection + AREXPORT void identSetSelfIdentifier(ArServerClient *client, + ArNetPacket *packet); + /// The command set the here goal of this server client connection + AREXPORT void identSetHereGoal(ArServerClient *client, ArNetPacket *packet); + + + /// Handles the "startRequestTransaction" packet, and updates the state of the client. + /** + * "Request transactions" are used to indicate that a sequence of request / + * reply packets must be completed before idle processing can proceed. + * Any "startRequestTransaction" MUST be followed by an "endRequestTransaction". + * + * The packets are meant to be used sparingly. They are currently only used + * when the Central Server is determining whether the map file needs to + * be downloaded to the client robot. + * + * @param client the ArServerClient* that sent the request; updated to indicate + * a new transaction is in progress + * @param packet the ArNetPacket* that contains the request (no additional data) + **/ + AREXPORT void handleStartRequestTransaction(ArServerClient *client, + ArNetPacket *packet); + + /// Handles the "endRequestTransaction" packet, and updates the state of the client. + /** + * @param client the ArServerClient* that sent the request; updated to indicate + * that a transaction has completed + * @param packet the ArNetPacket* that contains the request (no additional data) + * @see handleStartRequestTransaction + **/ + AREXPORT void handleEndRequestTransaction(ArServerClient *client, + ArNetPacket *packet); + + /// Returns the number of request transactions in progress for all connected clients. + /** + * @see handleStartRequestTransaction + **/ + AREXPORT int getRequestTransactionCount(); + + + /// accepts new sockets and moves them into the client list + void acceptTcpSockets(void); + /// Internal function for server/client switching + AREXPORT ArServerClient *finishAcceptingSocket( + ArSocket *socket, bool skipPassword = false, + bool overrideGeneralReject = false); + bool processFile(void); + + /// callback for our slow idle thread, which is down below... + /// The command that returns if there is idle processing to do + AREXPORT void netIdleProcessingPending(ArServerClient *client, + ArNetPacket *packet); + + void slowIdleCallback(void); + + + + std::string myServerName; + std::string myLogPrefix; + ArMutex myDataMutex; + ArMutex myClientsMutex; + ArMutex myCycleCallbacksMutex; + bool myTcpOnly; + bool myDebugLogging; + ArLog::LogLevel myVerboseLogLevel; + + unsigned int myTcpPort; + unsigned int myUdpPort; + std::string myOpenOnIP; + // our mapping of the ints to the serverData + std::map myDataMap; + /// our mapping of the group names + std::map myGroupDescription; + + // default frequency (helper for forwarding) + std::map myDefaultFrequency; + + int myRejecting; + std::string myRejectingString; + + std::string myEnforceProtocolVersion; + ArServerCommands::Type myEnforceType; + + double myBackupTimeout; + bool myNewBackupTimeout; + ArMutex myBackupTimeoutMutex; + + ArCallbackList1 myTooManyClientsCBList; + + // the number we're on for the current data + unsigned int myNextDataNumber; + std::string myAdditionalDataFlags; + bool myOpened; + std::list myClients; + ArNetPacketReceiverUdp myUdpReceiver; + ArFunctor2C myProcessPacketCB; + ArRetFunctor2C mySendUdpCB; + ArSocket myTcpSocket; + ArSocket myUdpSocket; + std::list myCycleCallbacks; + std::list *> myClientRemovedCallbacks; + + ArTypes::UByte4 myConnectionNumber; + + ArSocket myAcceptingSocket; + + int myMostClients; + bool myUsingOwnNumClients; + int myNumClients; + + + unsigned int myLoopMSecs; + + ArMutex myAddListMutex; + std::list myAddList; + ArMutex myRemoveSetMutex; + std::set myRemoveSet; + + const ArServerUserInfo *myUserInfo; + bool myLogPasswordFailureVerbosely; + std::string myServerKey; + ArFunctorC myAriaExitCB; + ArRetFunctor2C myGetFrequencyCB; + ArRetFunctorC myProcessFileCB; + + ArFunctor2C myIdentGetConnectionIDCB; + ArFunctor2C myIdentSetConnectionIDCB; + ArFunctor2C myIdentSetSelfIdentifierCB; + ArFunctor2C myIdentSetHereGoalCB; + + ArFunctor2C myStartRequestTransactionCB; + ArFunctor2C myEndRequestTransactionCB; + + ArFunctor2C myIdleProcessingPendingCB; + + bool myAllowSlowPackets; + bool myAllowIdlePackets; + + int myMaxClientsAllowed; + + ArMutex myProcessingSlowIdleMutex; + + + class SlowIdleThread : public ArASyncTask + { + public: + /// Constructor + SlowIdleThread(ArServerBase *serverBase); + /// Destructor + virtual ~SlowIdleThread(void); + virtual void *runThread(void *arg); + protected: + ArServerBase *myServerBase; + }; + friend class ArServerBase::SlowIdleThread; + + SlowIdleThread *mySlowIdleThread; + bool myHaveSlowPackets; + bool myHaveIdlePackets; + + bool myLastIdleProcessingPending; + + ArMutex myIdleCallbacksMutex; + bool myHaveIdleCallbacks; + std::list myIdleCallbacks; +}; + +#endif diff --git a/Legacy/Aria/ArNetworking/include/ArServerClient.h b/Legacy/Aria/ArNetworking/include/ArServerClient.h new file mode 100644 index 0000000..64e997d --- /dev/null +++ b/Legacy/Aria/ArNetworking/include/ArServerClient.h @@ -0,0 +1,284 @@ +#ifndef NLSERVERCLIENT_H +#define NLSERVERCLIENT_H + +#include "ArNetPacket.h" +#include "ArServerCommands.h" +#include "ArNetPacketReceiverTcp.h" +#include "ArNetPacketSenderTcp.h" + +class ArServerData; +class ArServerUserInfo; + +#include "ArServerClientData.h" +#include "ArServerClientIdentifier.h" + +/** + This class represents the server's connection to the client, and + contains the socket that the server uses to talk to the client and + the information for sending packets to the client. +**/ + +class ArServerClient +{ +public: + /// The state of the connection + enum ServerState { + STATE_SENT_INTRO, ///< opened socket, sent our intro to the server + STATE_REJECTED, ///< Client was rejected by server + STATE_CONNECTED, ///< Client is connected to server + STATE_DISCONNECTED ///< Client has disconnected from server + }; + + + /// Constructor + AREXPORT ArServerClient( + ArSocket *tcpSocket, unsigned int udpPort, long authKey, + long introKey, ArRetFunctor2 *sendUdpCallback, + std::map *dataMap, + const char *passwordKey, const char *serverKey, + const ArServerUserInfo *userInfo = NULL, + int rejecting = 0, const char *rejectingString = "", + bool debugLogging = false, + const char *serverClientName = "ArServerBase_unknown", + bool logPasswordFailureVerbosely = false, + bool allowSlowPackets = true, bool allowIdlePackets = true, + const char *enforceProtocolVersion = "", + ArServerCommands::Type enforceType = ArServerCommands::TYPE_UNSPECIFIED); + /// Destructor + AREXPORT virtual ~ArServerClient(); + + /// The callback for taking care of the TCP connection + AREXPORT bool tcpCallback(void); + + /// The callback for taking care of slow packets + AREXPORT bool slowPacketCallback(void); + + /// The callback for taking care of idle packets (logic on idle elsewhere) + AREXPORT bool idlePacketCallback(void); + + /// Sets the backup timeout + AREXPORT void setBackupTimeout(double timeoutInMins); + + /// Process the packet whever it came from + AREXPORT void processPacket(ArNetPacket *packet, bool tcp = true); + + /// Send a packet over TCP. + /// The command ID of the outgoing packet will be set to the current command ID + /// (from the incoming packet). + AREXPORT virtual bool sendPacketTcp(ArNetPacket *packet); + /// Send a packet over UDP (unless client only wants TCP; then sends over TCP). + /// The command ID of the outgoing packet will be set to the current command ID + /// (from the incoming packet). + AREXPORT virtual bool sendPacketUdp(ArNetPacket *packet); + + /// Sees if this client has access to a given group + AREXPORT bool hasGroupAccess(const char *group); + + /** Broadcasts a packet over TCP if this client wants this data -- For internal + * use only! + * @internal + */ + AREXPORT void broadcastPacketTcp(ArNetPacket *packet); + + /** Broadcasts a packet over UDP if this client wants this data (unless client only wants tcp then sends over tcp) -- For internal ArNetworking use only! + * @internal + */ + AREXPORT void broadcastPacketUdp(ArNetPacket *packet); + + /// Logs the tracking information (packet and byte counts) + AREXPORT void logTracking(bool terse); + + /// Clears the tracking information (resets counters) + AREXPORT void resetTracking(void); + + /// Gets the IP string of the client + AREXPORT const char *getIPString(void) const; + + /// Gets the identifier of this server client + AREXPORT ArServerClientIdentifier getIdentifier(void) const; + + /// Sets the identifier of this server client + AREXPORT void setIdentifier(ArServerClientIdentifier identifier); + + /// Sends a shutdown command to the socket + AREXPORT void shutdown(void); + + /// Sets the sin (network address) for the UDP socket + AREXPORT void setUdpAddress(struct sockaddr_in *sin); + + /// Gets the sin (network address) for the UDP socket + AREXPORT struct sockaddr_in *getUdpAddress(void); + + /// Gets the authKey used for setting up UDP from this client to the server + AREXPORT long getAuthKey(void); + + /// Processes the auth packets that came from udp + AREXPORT void processAuthPacket(ArNetPacket *packet, struct sockaddr_in *sin); + + /// Handles the requests for packets + AREXPORT void handleRequests(void); + + /// Internal function to get the tcp socket + AREXPORT ArSocket *getTcpSocket(void) { return &myTcpSocket; } + /// Forcibly disconnect a client (for client/server switching) + AREXPORT void forceDisconnect(bool quiet); + /// Gets how often a command is asked for + AREXPORT long getFrequency(ArTypes::UByte2 command); + /// Sets the TCP only flag + AREXPORT void useTcpOnly(void) { myTcpOnly = true; } + /// Gets the tcp only flag + AREXPORT bool isTcpOnly(void) { return myTcpOnly; } + /// Gets the state + AREXPORT ServerState getState(void) { return myState; } + /// Gets if we have any slow packets to process + AREXPORT bool hasSlowPackets(void) { return myHaveSlowPackets; } + /// Gets if we have any idle packets to process + AREXPORT bool hasIdlePackets(void) { return myHaveIdlePackets; } + + + /// Starts a new request transaction, incrementing the count. + /** + * This method is intended to be called solely by the ArServerBase. + * It MUST be followed by a call to endRequestTransaction(). + * + * Request transactions are used under certain circumstances to + * indicate that a number of related request/reply packets must + * be completely processed before background idle processing can + * proceed. See ArServerBase for more information. + **/ + AREXPORT void startRequestTransaction(); + + /// Ends the most recent request transaction, decrementing the count. + /** + * This method is intended to be called solely by the ArServerBase. + * @see startRequestTransaction(). + **/ + AREXPORT bool endRequestTransaction(); + + /// Returns the number of request transactions that are currently in progress. + /** + * This method is intended to be called solely by the ArServerBase. + * @see startRequestTransaction(). + **/ + AREXPORT int getRequestTransactionCount(); + + + /// Returns the command ID for the specified name, or 0 if it is not found + AREXPORT unsigned int findCommandFromName(const char *commandName) const; + + /// Get creation time + AREXPORT ArTime getCreationTime(void) { return myCreationTime; } +protected: + const char *findCommandName(unsigned int command) const; + // Some members so that we don't have to pass the number around + std::list myCommandStack; + std::list myForceTcpStack; + std::list mySlowIdleCommandStack; + std::list mySlowIdleForceTcpStack; + + AREXPORT bool setupPacket(ArNetPacket *packet); + // Pushes a new number onto our little stack of numbers + void pushCommand(unsigned int num); + // Pops the command off the stack + void popCommand(void); + // Pushes a new number onto our little stack of numbers + void pushSlowIdleCommand(unsigned int num); + // Pops the command off the stack + void popSlowIdleCommand(void); + // Gets the command we're on + unsigned int getCommand(); + // Gets the command we're on + bool getForceTcpFlag(); + // Pushes a new forceTcp flag onto our little stack of flags + void pushForceTcpFlag(bool forceTcp); + // Pops the command off the stack + void popForceTcpFlag(void); + // Pushes a new forceTcp flag onto our little stack of flags + void pushSlowIdleForceTcpFlag(bool forceTcp); + // Pops the command off the stack + void popSlowIdleForceTcpFlag(void); + + // this sends a list packet to our client + void sendListPacket(void); + + // this could just be dealth with by seeing if myUserInfo is NULL, + // but that may be confusing + const ArServerUserInfo *myUserInfo; + std::set myGroups; + ArNetPacketSenderTcp myTcpSender; + std::map *myDataMap; + std::list myRequested; + void internalSwitchState(ServerState state); + ServerState myState; + ArTime myStateStart; + bool myUdpConfirmedFrom; + bool myUdpConfirmedTo; + ArSocket myTcpSocket; + ArNetPacketReceiverTcp myTcpReceiver; + ArFunctor2C myProcessPacketCB; + ArRetFunctor2 *mySendUdpCB; + struct sockaddr_in mySin; + long myAuthKey; + long myIntroKey; + bool myTcpOnly; + bool mySentTcpOnly; + std::string myPasswordKey; + std::string myServerKey; + bool myDebugLogging; + ArLog::LogLevel myVerboseLogLevel; + std::string myLogPrefix; + ArServerClientIdentifier myIdentifier; + std::string myIPString; + + double myBackupTimeout; + + int myRejecting; + std::string myRejectingString; + + std::string myEnforceProtocolVersion; + ArServerCommands::Type myEnforceType; + + ArTime myTrackingStarted; + class Tracker + { + public: + Tracker() { reset(); } + virtual ~Tracker() {} + void reset(void) + { myPacketsTcp = 0; myBytesTcp = 0; myPacketsUdp = 0; myBytesUdp = 0; } + long myPacketsTcp; + long myBytesTcp; + long myPacketsUdp; + long myBytesUdp; + }; + AREXPORT void trackPacketSent(ArNetPacket *packet, bool tcp); + AREXPORT void trackPacketReceived(ArNetPacket *packet, ArTypes::UByte2); + std::map myTrackingSentMap; + std::map myTrackingReceivedMap; + bool myLogPasswordFailureVerbosely; + + bool myAllowSlowPackets; + bool myAllowIdlePackets; + + ArThread *mySlowIdleThread; + + bool myHaveSlowPackets; + bool myHaveIdlePackets; + + ArMutex mySlowPacketsMutex; + std::list mySlowPackets; + ArMutex myIdlePacketsMutex; + std::list myIdlePackets; + + /// Number of "request transactions" that are currently in progress for this client. + int myRequestTransactionCount; + /// Mutex for multi-threaded access to the request transaction count. + ArMutex myRequestTransactionMutex; + + ArTime myCreationTime; +}; + + + +#endif diff --git a/Legacy/Aria/ArNetworking/include/ArServerClientData.h b/Legacy/Aria/ArNetworking/include/ArServerClientData.h new file mode 100644 index 0000000..d8898a5 --- /dev/null +++ b/Legacy/Aria/ArNetworking/include/ArServerClientData.h @@ -0,0 +1,40 @@ +#ifndef ARSERVERCLIENTDATA_H +#define ARSERVERCLIENTDATA_H + +#include "Aria.h" + +class ArServerClientData +{ +public: + ArServerClientData(ArServerData *serverData, long mSecInterval, + ArNetPacket *packet) + { + myServerData = serverData; + myMSecInterval = mSecInterval; + myPacket.duplicatePacket(packet); + myReadLength = myPacket.getReadLength(); + myLastSent.setToNow(); + } + virtual ~ArServerClientData() {} + ArServerData *getServerData(void) { return myServerData; } + long getMSec(void) { return myMSecInterval; } + ArNetPacket *getPacket(void) + { myPacket.setReadLength(myReadLength); return &myPacket; } + ArTime getLastSent (void) { return myLastSent; } + void setLastSentToNow(void) { myLastSent.setToNow(); } + void setMSec(long mSec) { myMSecInterval = mSec; } + void setPacket(ArNetPacket *packet) + { + myPacket.duplicatePacket(packet); + myReadLength = myPacket.getReadLength(); + } +protected: + ArServerData *myServerData; + long myMSecInterval; + ArNetPacket myPacket; + unsigned int myReadLength; + ArTime myLastSent; + +}; + +#endif // ARSERVERCLIENTDATA_H diff --git a/Legacy/Aria/ArNetworking/include/ArServerClientIdentifier.h b/Legacy/Aria/ArNetworking/include/ArServerClientIdentifier.h new file mode 100644 index 0000000..dd451f0 --- /dev/null +++ b/Legacy/Aria/ArNetworking/include/ArServerClientIdentifier.h @@ -0,0 +1,133 @@ +#ifndef ARSERVERCLIENTIDENTIFIER_H +#define ARSERVERCLIENTIDENTIFIER_H + + +/// Class that holds an identifier for a particular serverClient +class ArServerClientIdentifier +{ +public: + /// Constructor + ArServerClientIdentifier() { myConnectionID = 0; rebuildIDString(); } + /// Destructor + virtual ~ArServerClientIdentifier() {} + /// Gets an ID string which is just the other information in this combined + const char *getIDString(void) { return myIDString.c_str(); } + /// set the id num + void setConnectionID(ArTypes::UByte4 idNum) { myConnectionID = idNum; rebuildIDString(); } + /// Gets the id num + ArTypes::UByte4 getConnectionID(void) { return myConnectionID; } + /// Sets the self identifier + void setSelfIdentifier(const char *selfIdentifier) + { + if (selfIdentifier != NULL) + mySelfIdentifier = selfIdentifier; + else + mySelfIdentifier = ""; + rebuildIDString(); + } + /// Gets the self identifier + const char *getSelfIdentifier(void) { return mySelfIdentifier.c_str(); } + /// Sets the here goal + void setHereGoal(const char *selfIdentifier) + { + if (selfIdentifier != NULL) + myHereGoal = selfIdentifier; + else + myHereGoal = ""; + rebuildIDString(); + } + /// Gets the here goal + const char *getHereGoal(void) { return myHereGoal.c_str(); } + /// Sees if an identifier matches + /** + It can either match id, or the other parameters (for the other + parameters if the self id matches its a match, otherwise it + checks the here goal, and if that matches its a match)... this + is so that if someone's set a self id but changes their here + goal they'll still get their messages + */ + bool matches(ArServerClientIdentifier identifier, + bool matchConnectionID) + { + // if the ID's don't match then they don't match, this doesn't + // make sure they've been set like the others because here if it + // isn't set it means its an old client, but if its set it means + // its a new client... and if its one old client, we want to + // send stuff to all the old clients (since we don't know which + // one did it) + if (matchConnectionID && getConnectionID() != identifier.getConnectionID()) + return false; + else if (matchConnectionID) + return true; + + // if they both have identifiers see if they match (if they do + // then we're good) + if (getSelfIdentifier() != NULL && getSelfIdentifier()[0] != '\0' && + identifier.getSelfIdentifier() != NULL && + identifier.getSelfIdentifier()[0] != '\0' && + strcasecmp(getSelfIdentifier(), identifier.getSelfIdentifier()) == 0) + return true; + + // if they both have here goals see if they match + if (getHereGoal() != NULL && getHereGoal()[0] != '\0' && + identifier.getHereGoal() != NULL && + identifier.getHereGoal()[0] != '\0' && + strcasecmp(getHereGoal(), identifier.getHereGoal()) != 0) + return false; + + return true; + } + void rebuildIDString(void) + { + char buf[1024]; + bool first = true; + buf[0] = '\0'; + sprintf(buf, "connectionID %u", myConnectionID); + if (myConnectionID != 0 || !mySelfIdentifier.empty() || + !myHereGoal.empty()) + { + if (myConnectionID != 0) + { + if (first) + myIDString = "("; + else + myIDString += " "; + first = false; + myIDString += buf; + } + if (!mySelfIdentifier.empty()) + { + if (first) + myIDString = "("; + else + myIDString += " "; + first = false; + myIDString += "selfID "; + myIDString += mySelfIdentifier; + } + if (!myHereGoal.empty()) + { + if (first) + myIDString = "("; + else + myIDString += " "; + first = false; + myIDString += "hereGoal "; + myIDString += myHereGoal; + } + myIDString += ")"; + } + else + myIDString = ""; + } +protected: + // the identifiers + ArTypes::UByte4 myConnectionID; + std::string mySelfIdentifier; + std::string myHereGoal; + + // the string that describes them just for debugging + std::string myIDString; +}; + +#endif // ArServerClientIdentifier diff --git a/Legacy/Aria/ArNetworking/include/ArServerCommands.h b/Legacy/Aria/ArNetworking/include/ArServerCommands.h new file mode 100644 index 0000000..84f679d --- /dev/null +++ b/Legacy/Aria/ArNetworking/include/ArServerCommands.h @@ -0,0 +1,49 @@ +#ifndef NLSERVERCOMMANDS_H +#define NLSERVERCOMMANDS_H + +/** + The commands from the server to the client +**/ + +class ArServerCommands +{ +public: + enum ServerCommands { + SHUTDOWN = 1, ///< Closes the connection + INTRODUCTION = 2, ///< Introduces the server to the client + UDP_INTRODUCTION = 3, ///< Udp introduction of the server to the client + UDP_CONFIRMATION = 4, ///< Confirmation Udp was received from client + CONNECTED = 5, ///< Server accepts clients connection + REJECTED = 6, ///< Server rejects clients connection, has a byte2, then a string.... these reasons (1 = bad username password, string then is empty, 2 = rejecting connection because using central server, string then is central server IP, 3 = client rejecting server because server has wrong protocol, 4 = server rejected client because client has wrong protocol, 5 = maxClients exceeded, 6 = type of client is specified, but doesn't match) + TCP_ONLY = 7, ///< Server tells client to only send TCP + LIST = 129, ///< Map of the string names for a type to a number along with a long description of the data type + LISTSINGLE = 130, ///< Map of a single type to a number (for late additions to server) along with its description + LISTARGRET = 131, ///< Map of the number to their arguments and returns descriptions + LISTARGRETSINGLE = 132, ///< Map of a single type to a number (for late additions to server) along with its argument and return descriptions + LISTGROUPANDFLAGS = 133, ///< Map of the number to their command groups and data flags + LISTGROUPANDFLAGSSINGLE = 134 ///< Map of a single type to a number (for late additions to server) along with its command group and data flags + }; + + enum Type + { + TYPE_UNSPECIFIED = 0, /// Unspecified (anything can connect) + TYPE_REAL = 1, ///< Only real robots permitted to connect + TYPE_SIMULATED = 2, ///< Only simulated robots permitted to connect + TYPE_NONE = 3 ///< Nothing is permitted to connect + }; + static const char *toString(Type type) + { + if (type == TYPE_UNSPECIFIED) + return "unspecified"; + else if (type == TYPE_REAL) + return "real"; + else if (type == TYPE_SIMULATED) + return "simulated"; + else if (type == TYPE_NONE) + return "none"; + else + return "unknown"; + } +}; + +#endif // NLSERVERCOMMANDS_H diff --git a/Legacy/Aria/ArNetworking/include/ArServerData.h b/Legacy/Aria/ArNetworking/include/ArServerData.h new file mode 100644 index 0000000..0972b02 --- /dev/null +++ b/Legacy/Aria/ArNetworking/include/ArServerData.h @@ -0,0 +1,70 @@ +#ifndef ARSERVERDATA_H +#define ARSERVERDATA_H + +/// class to hold information about the different data the server has +/** + This class is mostly just for holding all the information about one + of the server data entires in one convenient spot +**/ + +#include "Aria.h" + +class ArServerClient; +class ArNetPacket; + + +class ArServerData +{ +public: + /// Constructor + AREXPORT ArServerData( + const char *name, const char *description, unsigned int command, + ArFunctor2 *functor, + const char *argumentDescription, const char *returnDescription, + const char *commandGroup = NULL, const char *dataFlags = NULL, + ArRetFunctor1 *getFrequencyFunctor = NULL, + ArFunctor2 *requestChangedFunctor = NULL, + ArRetFunctor2 + *requestOnceFunctor = NULL); + /// Destructor + AREXPORT virtual ~ArServerData(); + const char *getName(void) { return myName.c_str(); } + const char *getDescription(void) { return myDescription.c_str(); } + unsigned int getCommand(void) { return myCommand; } + ArFunctor2 *getFunctor(void) + { return myFunctor; }; + const char *getArgumentDescription(void) + { return myArgumentDescription.c_str(); } + const char *getReturnDescription(void) + { return myReturnDescription.c_str(); } + const char *getCommandGroup(void) + { return myCommandGroup.c_str(); } + ArRetFunctor2 *getRequestOnceFunctor(void) + { return myRequestOnceFunctor; } + AREXPORT bool hasDataFlag(const char *dataFlag); + AREXPORT bool addDataFlags(const char *dataFlags); + AREXPORT bool remDataFlag(const char *dataFlag); + bool isSlowPacket(void) { return mySlowPacket; } + bool isIdlePacket(void) { return myIdlePacket; } + const char *getDataFlagsString(void) + { return myDataFlagsBuilder.getFullString(); } + AREXPORT void callRequestChangedFunctor(void); +protected: + std::string myName; + std::string myDescription; + std::string myArgumentDescription; + std::string myReturnDescription; + std::string myCommandGroup; + std::string myRawDataFlags; + ArMutex myDataMutex; + ArArgumentBuilder myDataFlagsBuilder; + unsigned int myCommand; + ArFunctor2 *myFunctor; + ArRetFunctor1 *myGetFrequencyFunctor; + ArFunctor2 *myRequestChangedFunctor; + ArRetFunctor2 *myRequestOnceFunctor; + bool mySlowPacket; + bool myIdlePacket; +}; + +#endif // ARSERVERDATA_H diff --git a/Legacy/Aria/ArNetworking/include/ArServerFileUtils.h b/Legacy/Aria/ArNetworking/include/ArServerFileUtils.h new file mode 100644 index 0000000..1d6b389 --- /dev/null +++ b/Legacy/Aria/ArNetworking/include/ArServerFileUtils.h @@ -0,0 +1,244 @@ +#ifndef ARSERVERFILEUTILS_H +#define ARSERVERFILEUTILS_H + +#include "Aria.h" +#include "ArServerBase.h" + + +/// Provides a list of files to clients +/** + * @note Linux only + * + This class is set up so that a client can get file information from + the robot, this class ONLY lists files, and doesn't do any + manipulation of them. You should use this class by using + ArClientFileLister and NOT by using this classes interface + directly, this is because the API is and will remain fairly + volatile, just use ArClientFileLister, if you need more + functionality let us know and we'll add it if its reasonable. +**/ +class ArServerFileLister +{ +public: + /// Constructor + AREXPORT ArServerFileLister(ArServerBase *server, const char *topDir, + const char *defaultUploadDownloadDir = NULL); + /// Destructor + AREXPORT virtual ~ArServerFileLister(); + /// The function that gets the directory listing + AREXPORT void getDirListing(ArServerClient *client, + ArNetPacket *packet); + /// The function that gets the directory listing in a better way + AREXPORT void getDirListingMultiplePackets(ArServerClient *client, + ArNetPacket *packet); + /// The function that gets the default upload/download dir + AREXPORT void getDefaultUploadDownloadDir( + ArServerClient *client, ArNetPacket *packet); +protected: + char myBaseDir[2048]; + std::string myDefaultUploadDownloadDir; + ArServerBase *myServer; + ArFunctor2C myGetDirListingCB; + ArFunctor2C myGetDirListingMultiplePacketsCB; + ArFunctor2C myGetDefaultUploadDownloadDirCB; +}; + +// ---------------------------------------------------------------------------- +// ArServerFileToClient +// ---------------------------------------------------------------------------- + +/// Gets files from the server +/** + * @note Linux only + * + This class is set up so that a client can get files the robot, this + class ONLY gets files. You should use this class by using + ArClientFileToClient and NOT by using this classes interface + directly, this is because the API is and will remain fairly + volatile... if you need more functionality let us know and we'll + add it if its reasonable. +**/ +class ArServerFileToClient +{ +public: + /// Constructor + AREXPORT ArServerFileToClient(ArServerBase *server, const char *topDir); + /// Destructor + AREXPORT virtual ~ArServerFileToClient(); + /// Gets the file + AREXPORT void getFile(ArServerClient *client, + ArNetPacket *packet); + + /// Gets the file, and sets its timestamp to the original server value + AREXPORT void getFileWithTimestamp(ArServerClient *client, + ArNetPacket *packet); + + +protected: + + AREXPORT void doGetFile(ArServerClient *client, + ArNetPacket *packet, + bool isSetTimestamp); + +protected: + + char myBaseDir[2048]; + ArServerBase *myServer; + ArFunctor2C myGetFileCB; + + ArFunctor2C myGetFileWithTimestampCB; +}; + +// ---------------------------------------------------------------------------- +// ArServerFileToClient +// ---------------------------------------------------------------------------- + +/// Puts files onto the server +/** + * @note Linux only + * + This class is set up so that a client can put files on the robot, + this class ONLY puts files. This class will take a file from a + client, writing it into the tempDir given in the constructor, then + after receiving the file it'll move it over to the actual location + requested. You should use this class by using ArClientFileToClient + and NOT by using this classes interface directly, this is because + the API is and will remain fairly volatile... if you need more + functionality let us know and we'll add it if its reasonable. +**/ +class ArServerFileFromClient +{ +public: + /// Constructor + AREXPORT ArServerFileFromClient(ArServerBase *server, const char *topDir, + const char *tempDir); + /// Destructor + AREXPORT virtual ~ArServerFileFromClient(); + /// Puts the file + AREXPORT void putFile(ArServerClient *client, + ArNetPacket *packet); + /// Puts the file with interleaved responses + AREXPORT void putFileInterleaved(ArServerClient *client, + ArNetPacket *packet); + /// Puts the file + AREXPORT void putFileWithTimestamp(ArServerClient *client, + ArNetPacket *packet); + /// Puts the file with interleaved responses + AREXPORT void putFileWithTimestampInterleaved(ArServerClient *client, + ArNetPacket *packet); + + /// Adds a callback to be called before moving from temp dir to final loc + AREXPORT void addPreMoveCallback( + ArFunctor *functor, ArListPos::Pos position = ArListPos::LAST); + /// Removes a callback to be called before moving from temp dir to final loc + AREXPORT void remPreMoveCallback(ArFunctor *functor); + /// Adds a callback to be called after moving from temp dir to final loc + AREXPORT void addPostMoveCallback( + ArFunctor *functor, ArListPos::Pos position = ArListPos::LAST); + /// Removes a callback to be called after moving from temp dir to final loc + AREXPORT void remPostMoveCallback(ArFunctor *functor); + /// Internal call for getting the name of the file we're moving + const char *getMovingFileName(void) { return myMovingFileName.c_str(); } +protected: + + AREXPORT void internalPutFile(ArServerClient *client, + ArNetPacket *packet, + bool interleaved, + bool isSetTimestamp); + + char myBaseDir[2048]; + char myTempDir[2048]; + ArServerBase *myServer; + std::list myPreMoveCallbacks; + std::list myPostMoveCallbacks; + + ArFunctor2C myPutFileCB; + ArFunctor2C myPutFileInterleavedCB; + ArFunctor2C myPutFileWithTimestampCB; + ArFunctor2C myPutFileWithTimestampInterleavedCB; + + std::string myMovingFileName; + + int myFileNumber; + + class FileInfo + { + public: + FileInfo() { myFile = NULL; } + virtual ~FileInfo() {} + std::string myRealFileName; + std::string myTempFileName; + FILE *myFile; + ArTime myStartedTransfer; + ArTime myLastActivity; + time_t myFileTimestamp; + // pointer to the client that is sending the file, we can compare + // this against other client pointers but WE CANNOT ACCESS THE OLD + // ONE since its possible that it disconnected and is an invalid + // pointer + ArServerClient *myClient; + ArTime myClientCreationTime; + }; + + // map of raw filenames to FileInfo (so we don't have to walk it all the time) + std::map myMap; +}; + + +/// Deletes files from the server +/** + * @note Linux only + * + This class is set up so that a client can get delete files on the + robot, this class ONLY deletes files. You should use this class by + using ArClientDeleteFileOnServer and NOT by using this classes + interface directly, this is because the API is and will remain + fairly volatile... if you need more functionality let us know and + we'll add it if its reasonable. +**/ +class ArServerDeleteFileOnServer +{ +public: + /// Constructor + AREXPORT ArServerDeleteFileOnServer(ArServerBase *server, + const char *topDir); + /// Destructor + AREXPORT virtual ~ArServerDeleteFileOnServer(); + /// Deletes the file + AREXPORT void deleteFile(ArServerClient *client, + ArNetPacket *packet); + /// Adds a callback to be called before moving from temp dir to final loc + AREXPORT void addPreDeleteCallback( + ArFunctor *functor, ArListPos::Pos position = ArListPos::LAST); + /// Removes a callback to be called before moving from temp dir to final loc + AREXPORT void remPreDeleteCallback(ArFunctor *functor); + /// Adds a callback to be called after moving from temp dir to final loc + AREXPORT void addPostDeleteCallback( + ArFunctor *functor, ArListPos::Pos position = ArListPos::LAST); + /// Removes a callback to be called after moving from temp dir to final loc + AREXPORT void remPostDeleteCallback(ArFunctor *functor); + /// Gets the filename of the file we're deleting + const char *getDeletingFileName(void) { return myDeletingFileName.c_str(); } +protected: + char myBaseDir[2048]; + ArServerBase *myServer; + ArFunctor2C myDeleteFileCB; + std::string myDeletingFileName; + std::list myPreDeleteCallbacks; + std::list myPostDeleteCallbacks; + +}; + +#endif // ARSERVERFILEUTILS_H diff --git a/Legacy/Aria/ArNetworking/include/ArServerHandlerCamera.h b/Legacy/Aria/ArNetworking/include/ArServerHandlerCamera.h new file mode 100644 index 0000000..7c813e6 --- /dev/null +++ b/Legacy/Aria/ArNetworking/include/ArServerHandlerCamera.h @@ -0,0 +1,418 @@ +#ifndef ARSERVERHANDLERCAMERA_H +#define ARSERVERHANDLERCAMERA_H + +#include "Aria.h" + +#include "ArNetworking.h" + +/** Accepts and processes camera pan/tilt/zoom requests from the client, and + provides information about the camera (such as its current position). + + The following requests are accepted. Arguments and return values are stored + in the packet as signed 16-bit values. (They are converted to double-precision + floating point values when received by dividing by 100; to store floating + point values, multiply by 100 first: + packet.byte2ToBuf((ArTypes::Byte2)(100.0 * doubleVal)); or + see also getDoubleFromPacket() and addDoubleToPacket().) + + Each request name is suffixed by the name of the camera to control. If more than one + camera is used, each can have a different name (given in the constructor), and commands for the different cameras + are differentiated by appending the camera name to the command requests listed below. For example, + an ArServerHandlerCamera with camera name of "A" would receive "setCameraRelA". while the + handler with camera name of "B" would receive "setCameraAbsB". If no camera name is given + (typical if just one ArServerHandlerCamera object is created), + just the base requests are used. To provide information to the client about the multiple cameras and their names, use ArCameraCollection and an ArServerHandlerCameraCollection object. + + + + + + + + + + + In addition, some older camera requests are accepted for partial backwards + compatability with old clients: cameraUpdate, cameraInfo, cameraAbs, camera, + and cameraPct. These requests take values as single bytes, rather than multiplied + floats as 2-bytes as the above commands do. Note, these cannot be used in a multi-camera + configuration. + + These requests are in a user permission group called CameraControl. + + In addition to positioning the camera, ArServerHandlerCamera can support additional "modes" for camera control, if additional code is added to update ArServerHandlerCamera with the state of other systems such as navigation. The additional modes are LookAtGoal and LookAtPoint. An external system such as navigation (e.g. ARNL) must keep the camera handler object updated with its current goal by calling cameraModeLookAtGoalSetGoal() and cameraModeLookAtGoalClearGoal(), and ArServerHandlerCamera will continuously point the camera at that point or goal as the robot moves. The network requests associated with setting modes are: +
    +
  • getCameraModeList: Gets the list of modes that this camera + supports
  • +
  • getCameraModeUpdated: Sent when the mode is changed
  • +
  • setCameraMode: Command to change the camera mode (give mode name)
  • +
+*/ +class ArServerHandlerCamera : public ArCameraCollectionItem +{ +private: + static const char *CONTROL_COMMAND_GROUP; + static const char *INFO_COMMAND_GROUP; + static const char *NO_ARGS; +public: + + /// Constructs a new handler for the specified camera. + /** + * @param cameraName the unique char * name of the associated camera + * @param server the ArServerBase * used to send/receive requests + * @param robot the associated ArRobot * + * @param camera the ArPTZ * that provides access to the actual camera + * @param collection the ArCameraCollection * to which to add the + * camera command information; if NULL, then addToCameraCollection() + * must be called manually. + **/ + AREXPORT ArServerHandlerCamera(const char *cameraName, + ArServerBase *server, + ArRobot *robot, + ArPTZ *camera, + ArCameraCollection *collection); + + /// Constructor + /** + * This constructor is maintained for backwards compatibility. It will + * not work in a multi-camera configuration. + * @deprecated + * @param server the ArServerBase * used to send/receive requests + * @param robot the associated ArRobot * + * @param camera the ArPTZ * that provides access to the actual camera + **/ + AREXPORT ArServerHandlerCamera(ArServerBase *server, + ArRobot *robot, + ArPTZ *camera); + + /// Destructor + AREXPORT virtual ~ArServerHandlerCamera(); + + // ----------------------------------------------------------------------------- + // ArCameraCollectionItem Interface: + // ----------------------------------------------------------------------------- + + /// Sends the camera absolute commands to the camera (and puts it in position mode) + AREXPORT void setCameraAbs(double pan, double tilt, double zoom, + bool lockRobot = true); + + /// Sends the camera relative commands to the camera (and puts it in position mode) + AREXPORT void setCameraRel(double pan, double tilt, double zoom, + bool lockRobot = true); + + /// Sends the camera percent commands to the camera (and puts it in position mode) + AREXPORT void setCameraPct(double panPct, double tiltPct, + bool lockRobot = true); + + /// Resets the camera + AREXPORT void resetCamera(bool lockRobot = true); + + /// Puts the camera into a mode where it will look at the goal + AREXPORT void cameraModeLookAtGoal(void); + + /// Puts the camera into a mode where it will look at a point + AREXPORT void cameraModeLookAtPoint(ArPose pose, bool controlZoom = true); + + /// Sets the goal for the camera mode that points at the goal + AREXPORT void cameraModeLookAtGoalSetGoal(ArPose pose); + /// Clears the goal for the camera mode that points at the goal + AREXPORT void cameraModeLookAtGoalClearGoal(void); + + /// Puts the camera in position mode + AREXPORT void cameraModePosition(void); + + + + + + + /// Returns the name of the camera that is controlled by this handler. + /** + * @return char * the unique name of the associated camera (if specified in + * the constructor) + **/ + AREXPORT const char *getCameraName(); + + /// Adds the camera commands to the given collection. + /** + * @param collection the ArCameraCollection to which to add the camera commands + **/ + AREXPORT virtual void addToCameraCollection(ArCameraCollection &collection); + + + // ----------------------------------------------------------------------------- + // Packet Handlers: + // ----------------------------------------------------------------------------- + + // New methods that send/receive "double"s + + /// Handles the getCameraData network packet, returning information in double format. + /** + * @param client the ArServerClient * that sent the request + * @param packet the ArNetPacket * that contains the request + **/ + AREXPORT void handleGetCameraData(ArServerClient *client, ArNetPacket *packet); + + /// Handles the getCameraInfo network packet, returning information in double format. + /** + * @param client the ArServerClient * that sent the request + * @param packet the ArNetPacket * that contains the request + **/ + AREXPORT void handleGetCameraInfo(ArServerClient *client, ArNetPacket *packet); + + /// Handles the setCameraAbs network packet, with information in double format. + /** + * @param client the ArServerClient * that sent the request + * @param packet the ArNetPacket * that contains the request + **/ + AREXPORT void handleSetCameraAbs(ArServerClient *client, ArNetPacket *packet); + + /// Handles the setCameraPct network packet, with information in double format. + /** + * @param client the ArServerClient * that sent the request + * @param packet the ArNetPacket * that contains the request + **/ + AREXPORT void handleSetCameraPct(ArServerClient *client, ArNetPacket *packet); + + /// Handles the setCameraRel network packet, with information in double format. + /** + * @param client the ArServerClient * that sent the request + * @param packet the ArNetPacket * that contains the request + **/ + AREXPORT void handleSetCameraRel(ArServerClient *client, ArNetPacket *packet); + + /// Handles the mode list for the camera + /** + * @param client the ArServerClient * that sent the request + * @param packet the ArNetPacket * that contains the request + **/ + AREXPORT void handleGetCameraModeList(ArServerClient *client, ArNetPacket *packet); + + /// Handle the mode request, generally this is sent when it changes + /** + * Refer to handleSetCameraMode for a description of the supported modes + * and the various packet structures. + * + * @param client the ArServerClient * that sent the request + * @param packet the ArNetPacket * that contains the request + **/ + AREXPORT void handleCameraModeUpdated(ArServerClient *client, + ArNetPacket *packet); + + /// Handle the set mode request + /** + * The following modes are currently supported: + * - Position: The user controls the camera position; no additional parameters + * in the packet + * - LookAtGoal: The robot automatically points the camera in the direction + * of its destination goal; no additional parameters in the packet + * - LookAtPoint: The robot "looks" at a specified point in the map; the packet + * contains: byte4, the x coordinate; byte4, the y coordinate + * @param client the ArServerClient * that sent the request + * @param packet the ArNetPacket * that contains the request + **/ + AREXPORT void handleSetCameraMode(ArServerClient *client, + ArNetPacket *packet); + + /// Handle the reset + /** + * @param client the ArServerClient * that sent the request + * @param packet the ArNetPacket * that contains the request + **/ + AREXPORT void handleResetCamera(ArServerClient *client, + ArNetPacket *packet); + // Old methods that send/receive ints + + /// Handles the camera network packet, with information stored as byte integers. + AREXPORT void camera(ArServerClient *client, ArNetPacket *packet); + /// Handles the cameraAbs network packet, with information stored as byte integers. + AREXPORT void cameraAbs(ArServerClient *client, ArNetPacket *packet); + /// Handles the cameraPct network packet, with information stored as byte integers. + AREXPORT void cameraPct(ArServerClient *client, ArNetPacket *packet); + /// Handles the cameraUpdate network packet, with information returned as byte2 integers. + AREXPORT void cameraUpdate(ArServerClient *client, ArNetPacket *packet); + /// Handles the cameraInfo network packet, with information returned as byte2 integers. + AREXPORT void cameraInfo(ArServerClient *client, ArNetPacket *packet); + +protected: + + + // ----------------------------------------------------------------------------- + // Helper Methods: + // ----------------------------------------------------------------------------- + + enum { + DOUBLE_FACTOR = 100 ///< Multiplier for putting/getting "double" values to/from a packet + }; + + /// Adds the given value as a "double" to the given network packet. + /** + * The "double" value is really a 2-byte integer multiplied by the DOUBLE_FACTOR. + **/ + AREXPORT void addDoubleToPacket(double val, + ArNetPacket &packet) + { + // TODO: Does this need to be rounded? Any error/overflow checking? + packet.byte2ToBuf((ArTypes::Byte2) (val * DOUBLE_FACTOR)); + } + + + /// Reads a "double" value from the given network packet. + /** + * The "double" value is really a 2-byte integer multiplied by the DOUBLE_FACTOR. + **/ + AREXPORT double getDoubleFromPacket(ArNetPacket &packet) + { + int tempVal = packet.bufToByte2(); + return ((double) tempVal / (double) DOUBLE_FACTOR); + } + + /// Gets the current camera zoom as a ratio of its zoom range. + AREXPORT double getCurrentZoomRatio() + { + if (myCamera->getMaxZoom() != myCamera->getMinZoom()) { + + return ((double)(myCamera->getZoom() - myCamera->getMinZoom())) + / ((double)(myCamera->getMaxZoom() - myCamera->getMinZoom())); + } + else { + return 0; + } + } // end method getCurrentZoomRatio + + + /// Converts the given absolute zoom value to a ratio of the camera's zoom range. + AREXPORT double getZoomRatio(double absZoom) + { + if (myCamera->getMaxZoom() != myCamera->getMinZoom()) { + + return ((double)(absZoom - myCamera->getMinZoom())) + / ((double)(myCamera->getMaxZoom() - myCamera->getMinZoom())); + } + else { + return 0; + } + } // end method getZoomRatio + + + /// Gets the range of the camera's zoom. + AREXPORT double getZoomRange() + { + return myCamera->getMaxZoom() - myCamera->getMinZoom(); + + } // end method getZoomRange + + +private: + + /// Performs initialization common to all constructors. + void init(); + + /// Creates command (packet) names for the current camera. + void createCommandNames(); + + /// Creates the handlers for each of the supported commands. + void createCommandCBs(); + + /// Adds all supported commands to the server. + void addAllCommandsToServer(); + + /// Adds the specified command to the server. + void addCommandToServer(const char *command, + const char *description, + const char *argumentDescription, + const char *returnDescription, + const char *commandGroup); + + /// Removes an unsupported command. + void removeCommand(const char *command); + + /// Adds the information about all supported commands to the camera collection. + void doAddToCameraCollection(ArCameraCollection &collection); + +protected: + + /// Associated robot (primarily used for locking) + ArRobot *myRobot; + /// Server from which requests are received + ArServerBase *myServer; + /// Camera that is controlled + ArPTZ *myCamera; + + /// Unique name of the associated camera + std::string myCameraName; + /// Pointer to the camera collection (if any) + ArCameraCollection *myCameraCollection; + + /// Map of ArCameraCommand names to a unique network packet name + std::map myCommandToPacketNameMap; + /// Map of ArCameraCommand names to the preferred default request interval + std::map myCommandToIntervalMap; + + /// Map of ArCameraCommand names to the callback that handles the packet + std::map *> myCommandToCBMap; + + enum CameraMode + { + CAMERA_MODE_POSITION, + CAMERA_MODE_LOOK_AT_GOAL, + CAMERA_MODE_LOOK_AT_POINT + }; + + ArMutex myModeMutex; + CameraMode myCameraMode; + std::map myCameraModeNameMap; + ArNetPacket myCameraModePacket; + ArPose myLookAtPoint; + bool myPointResetZoom; + ArPose myGoal; + bool myGoalAchieved; + bool myGoalAchievedLast; + bool myGoalResetZoom; + + + void userTask(void); + void buildModePacket(void); + + ArFunctorC myUserTaskCB; + + // Leaving these just in case they are used by someone... + + /// Old (integer-style) handler for the camera packet. + /** + * @deprecated + **/ + ArFunctor2C myCameraCB; + /// Old (integer-style) handler for the cameraAbs packet. + /** + * @deprecated + **/ + ArFunctor2C myCameraAbsCB; + /// Old (integer-style) handler for the cameraUpdate packet. + /** + * @deprecated + **/ + ArFunctor2C myCameraUpdateCB; + /// Old (integer-style) handler for the cameraInfo packet. + /** + * @deprecated + **/ + ArFunctor2C myCameraInfoCB; + +}; // end class ArServerHandlerCamera + +#endif diff --git a/Legacy/Aria/ArNetworking/include/ArServerHandlerCameraCollection.h b/Legacy/Aria/ArNetworking/include/ArServerHandlerCameraCollection.h new file mode 100644 index 0000000..a428533 --- /dev/null +++ b/Legacy/Aria/ArNetworking/include/ArServerHandlerCameraCollection.h @@ -0,0 +1,142 @@ +#ifndef ARSERVERHANDLERCAMERACOLLECTION_H +#define ARSERVERHANDLERCAMERACOLLECTION_H + +#include +#include +#include +#include + +#include "ArServerBase.h" +#include "ArServerClient.h" + +/// Provides information to a client about different cameras and how to send requests to their different ArServerHandlerCamera and video image server objects. +/** + * ArServerHandlerCameraCollection defines the network packet handlers to + * transmit information regarding the cameras and their video streams that are installed on the robot. + * + * This class handles the following requests: + *
    + *
  • getCameraList: Replies with a packet containing a 2-byte integer + * indicating the number of cameras. Then, for each camera: + *
      + *
    1. camera name (string)
    2. + *
    3. camera type (string)
    4. + *
    5. camera name for user display (string)
    6. + *
    7. camera type for user display (string)
    8. + *
    9. list of requests that can be sent for this camera, beginning with the 2-byte number of commands, then, for + * each command: + *
        + *
      1. the generic descriptive name (string)
      2. + *
      3. the specific command request name (string)
      4. + *
      5. an appropriate frequency for making this request (4-byte integer)
      6. + *
      + *
    10. + *
    11. list of parameters, beginning with the 2-byte number of parameters, then, + * for each parameter, the parameter definition/value (see ArClientArg for format). + *
    12. + *
    + *
  • + * + *
  • setCameraParams: Set some camera parameters. Begins with camera name + * string, then for each parameter, the parameter name and value (see + * ArClientArg for the format). An empty parameter name string terminates + * the list. In reply, this handler sends a packet confirming the changes + * (see cameraParamUpdated below).
  • + *
+ * + * When a camera is added or a parameter changes, the server broadcasts the + * following packets to each client: + *
    + *
  • cameraListUpdate: no arguments, use getCameraList to get the new list.
  • + * + *
  • cameraParamUpdated: starts with camera name, then a list of parameter + * name and value (see ArClientArg for format). An empty parameter name + * string terminates the list.
  • + *
+ * Note that the cameraParamUpdated is currently only sent in response to a + * setCameraParams request. That is, it does not monitor the actual parameter + * values in the ArCameraCollection. + *

+ * In order to manipulate a particular camera using the request names and other + * information provided by ArServerHandlerCameraCollection, see ArServerHandlerCamera and + * ArVideoServer. + */ +class ArServerHandlerCameraCollection +{ +protected: + /// Name of the network packet to get the camera list. + static const char *GET_COLLECTION_PACKET_NAME; + /// Name of the network packet to set a particular camera parameter. + static const char *SET_PARAMS_PACKET_NAME; + + /// Name of the network packet broadcast when the collection is modified. + static const char *COLLECTION_UPDATED_PACKET_NAME; + /// Name of the network packet broadcast when a parameter value is modified. + static const char *PARAMS_UPDATED_PACKET_NAME; + + /// Command group for these packets. + static const char *COMMAND_GROUP; + +public: + /// Constructor. + /** + * @param server the ArServerBase * used to send/receive requests + * @param cameraCollection the ArCameraCollection * to be transmitted + **/ + AREXPORT ArServerHandlerCameraCollection(ArServerBase *server, + ArCameraCollection *cameraCollection); + /// Destructor. + AREXPORT virtual ~ArServerHandlerCameraCollection(); + + // -------------------------------------------------------------------------- + // Network Packet Handlers + // -------------------------------------------------------------------------- + + /// Handles the request to get the camera list / collection. + /** + * @param client the ArServerClient * that is making the request + * @param packet the ArNetPacket * that contains the request + **/ + AREXPORT void getCameraList(ArServerClient *client, ArNetPacket *packet); + + /// Handles the request to edit a camera's parameters. + /** + * @param client the ArServerClient * that is making the request + * @param packet the ArNetPacket * that contains the request + **/ + AREXPORT void setParams(ArServerClient *client, ArNetPacket *packet); + + // -------------------------------------------------------------------------- + // ArCameraCollection Modified Callback + // -------------------------------------------------------------------------- + + /// Callback executed when the associated camera collection is modified. + AREXPORT void handleCameraCollectionModified(); + + +private: + + /// Disabled copy ctor + ArServerHandlerCameraCollection(const ArServerHandlerCameraCollection &); + /// Disabled assignment operator + ArServerHandlerCameraCollection &operator=(const ArServerHandlerCameraCollection &); + +protected: + + /// The server used to send/receive requests + ArServerBase *myServer; + /// The associated camera collection + ArCameraCollection *myCameraCollection; + + /// Server callback for the get camera list request + ArFunctor2 *myGetCameraListCB; + /// Server callback for the set parameter request + ArFunctor2 *mySetParamCB; + + /// Notification callback when the camera collection has been modified + ArFunctor *myCollectionModifiedCB; + +}; // end class ArServerHandlerCameraCollection + + +#endif // ARSERVERHANDLERCAMERACOLLECTION_H diff --git a/Legacy/Aria/ArNetworking/include/ArServerHandlerCommMonitor.h b/Legacy/Aria/ArNetworking/include/ArServerHandlerCommMonitor.h new file mode 100644 index 0000000..2780c56 --- /dev/null +++ b/Legacy/Aria/ArNetworking/include/ArServerHandlerCommMonitor.h @@ -0,0 +1,125 @@ +#ifndef ARSERVERHANDLERCOMMMONITOR_H +#define ARSERVERHANDLERCOMMMONITOR_H + +#include "Aria.h" + +#include "ArNetworking.h" + +/// Handler that enables the client to monitor communication to the robot server. +/** + * ArServerHandlerCommMonitor defines network packet handlers that simply verify + * the communication between the robot and server. + * + * This class handles the following requests: + *

    + *
  • heartbeatTcp: Packet broadcast (TCP) periodically to confirm that + * the server is alive.
  • + *
  • heartbeatUdp: Packet broadcast (UDP) periodically to confirm that + * the server is alive.
  • + *
  • getHeartbeatInterval: Command to return the expected heartbeat interval. + * Packet contains: + *
      + *
    1. uByte4 : Interval (msecs)
    2. + *
    + *
  • ackCommTcp: Command to acknowledge two-way communication over TCP. + * An empty packet is returned.
  • + *
  • ackCommUdp: Command to acknowledge two-way communication over UDP. + * An empty packet is returned.
  • + *
+**/ +class ArServerHandlerCommMonitor +{ +public: + + enum { + MIN_HEARTBEAT_INTERVAL = 100, + DEFAULT_HEARTBEAT_INTERVAL = 500 + }; + +protected: + /// Name of the network packet broadcast (TCP) to confirm the server is alive. + static const char *HEARTBEAT_TCP_PACKET_NAME; + /// Name of the network packet broadcast (UDP) to confirm the server is alive. + static const char *HEARTBEAT_UDP_PACKET_NAME; + + /// Name of the network packet to get the heartbeat interval. + static const char *GET_HEARTBEAT_INTERVAL_PACKET_NAME; + /// Name of the network packet to confirm TCP communication. + static const char *ACK_COMM_TCP_PACKET_NAME; + /// Name of the network packet to confirm UDP communication. + static const char *ACK_COMM_UDP_PACKET_NAME; + + + static const char *COMMAND_GROUP; + static const char *NO_ARGS; + +public: + + /// Constructs a new handler to monitor communication between the robot server and client. + /** + * @param server the ArServerBase used to send/receive requests + * @param heartBeatInterval How often to send a "heartbeat" packet to the client + **/ + AREXPORT ArServerHandlerCommMonitor(ArServerBase *server, + int heartbeatInterval = DEFAULT_HEARTBEAT_INTERVAL); + + + /// Destructor + AREXPORT virtual ~ArServerHandlerCommMonitor(); + + + // ----------------------------------------------------------------------------- + // Packet Handlers: + // ----------------------------------------------------------------------------- + + /// Handles the getHeartbeatInterval network packet. + /** + * @param client the ArServerClient * that sent the request + * @param packet the ArNetPacket * that contains the request + **/ + AREXPORT void handleGetHeartbeatInterval(ArServerClient *client, ArNetPacket *packet); + + /// Handles the ackCommTcp network packet. + /** + * @param client the ArServerClient * that sent the request + * @param packet the ArNetPacket * that contains the request + **/ + AREXPORT void handleAckCommTcp(ArServerClient *client, ArNetPacket *packet); + + + /// Handles the ackCommUdp network packet. + /** + * @param client the ArServerClient * that sent the request + * @param packet the ArNetPacket * that contains the request + **/ + AREXPORT void handleAckCommUdp(ArServerClient *client, ArNetPacket *packet); + + + /// Callback for the server cycle; broadcasts heartbeat packets when interval has elapsed. + AREXPORT void cycleCallback(); + +protected: + + /// Server from which requests are received + ArServerBase *myServer; + + /// Number of msecs between heartbeat broadcasts + int myHeartbeatInterval; + /// Time that the last heartbeat packets were broadcast + ArTime myLastHeartbeatTime; + + /// Callback for getting the heartbeat interval + ArFunctor2C myGetHeartbeatIntervalCB; + /// Callback for replying to the ack request (UDP) + ArFunctor2C myAckCommUdpCB; + /// Callback for replying to the ack request (TCP) + ArFunctor2C myAckCommTcpCB; + /// Cycle callback executed to broadcast the heartbeat packets + ArFunctorC myCycleCB; + +}; // end class ArServerHandlerCommMonitor + +#endif // ARSERVERHANDLERCOMMMONITOR_H diff --git a/Legacy/Aria/ArNetworking/include/ArServerHandlerCommands.h b/Legacy/Aria/ArNetworking/include/ArServerHandlerCommands.h new file mode 100644 index 0000000..751bda6 --- /dev/null +++ b/Legacy/Aria/ArNetworking/include/ArServerHandlerCommands.h @@ -0,0 +1,69 @@ +#ifndef ARSERVERHANDLERCOMMANDS_H +#define ARSERVERHANDLERCOMMANDS_H + +#include "Aria.h" +#include "ArServerBase.h" + +/// Class for having commands that can be called easily on the client +/** + You can add commands with addCommand and addStringCommand, you can + get the list of commands by requesting the data "listCommands" and + "listStringCommands". + **/ +class ArServerHandlerCommands +{ +public: + /// Constructor + AREXPORT ArServerHandlerCommands(ArServerBase *server); + /// Destructor + AREXPORT virtual ~ArServerHandlerCommands(); + /// Sets the text server + AREXPORT void setTextServer(ArNetServer *textServer) + { myTextServer = textServer; } + /// Adds a command with no arguments + AREXPORT bool addCommand(const char *name, const char *description, + ArFunctor *functor, + const char *commandGroup = NULL); + /// Adds a command that takes a string argument + AREXPORT bool addStringCommand(const char *name, const char *description, + ArFunctor1 *functor, + const char *commandGroup = NULL); + /// Sets a prefix for commands + AREXPORT void setPrefix(const char *prefix); + /// Gets the prefix + AREXPORT const char *getPrefix(void); + /// The function that lists the commands + AREXPORT void netListCommands(ArServerClient *client, ArNetPacket *packet); + /// The function that lists the string commands + AREXPORT void netListStringCommands(ArServerClient *client, + ArNetPacket *packet); + +protected: + ArServerBase *myServer; + ArNetServer *myTextServer; + void netParseCommand(ArServerClient *client, ArNetPacket *packet, + ArFunctor *functor); + void netParseStringCommand(ArServerClient *client, ArNetPacket *packet, + ArFunctor1 *functor); + + void textParseCommand(char **argv, int argc, ArSocket *socket, ArFunctor *functor); + void textParseStringCommand(char **argv, int argc, ArSocket *socket, + ArFunctor1 *functor); + + std::list myCommands; + std::list myCommandDescriptions; + std::list myStringCommands; + std::list myStringCommandDescriptions; + std::list *> myFunctors; + std::list *> *> myStringFunctors; + std::string myPrefix; + ArFunctor2C myNetListCommandsCB; + ArFunctor2C myNetListStringCommandsCB; + +}; + +#endif diff --git a/Legacy/Aria/ArNetworking/include/ArServerHandlerConfig.h b/Legacy/Aria/ArNetworking/include/ArServerHandlerConfig.h new file mode 100644 index 0000000..a684160 --- /dev/null +++ b/Legacy/Aria/ArNetworking/include/ArServerHandlerConfig.h @@ -0,0 +1,321 @@ +#ifndef ARSERVERCONFIGHANDLER_H +#define ARSERVERCONFIGHANDLER_H + +#include "Aria.h" +#include "ArServerBase.h" + +class ArServerClient; + +/// Class for sending and receiving ArConfig data via ArNetworking. +/** + * ArServerHandlerConfig defines the network packet handlers used to transmit + * ArConfig objects to a client, and to modify them based on information + * received from the client. Since the packet structure for the ArConfig is + * rather complex, this class is best used in conjunction with the + * ArClientHandlerConfig. + * + * This class handles the following requests: + *
    + *
  • getConfigBySections/getConfigBySectionsV2: Replies with multiple + * packets, one for each ArConfig section plus an empty packet that + * terminates the reply. Each packet contains the following header + * information: + *
      + *
    1. Section Indicator: Always set to 'S' (byte)
    2. + *
    3. Section Name: (string)
    4. + *
    5. Section Comment: (string)
    6. + *
    7. Section Category Name: (string) Only for getConfigBySectionsV2
    8. + *
    + * For each parameter in the section, the packet then contains a + * a Parameter Indicator (always set to 'P' (byte)) followed by a + * complete description of the parameter (display hints are included). + * See ArClientArgUtils for more information. + *
  • + *
  • getConfig: This request has been superceded by getConfigBySections. (It + * replies with a single packet containing all of the ArConfig + * sections as described above. If the ArConfig is large, then it + * may not be sent successfully. In addition, it contains no parameter + * display hints.) + *
  • + *
  • setConfig: Parses the received packet and updates the robot's + * ArConfig (and saves it to the file). For each modified section, + * the received packet is expected to contain: + *
      + *
    1. Section Indicator: Always set to "Section" (string)
    2. + *
    3. Section Name: (string)
    4. + *
    + * Followed by a brief "text" description of each modified parameter. + * This is the parameter name (string) followed by the parameter value + * formatted as text (string). See ArClientArgUtils for more information. + * + * A reply packet containing a string is sent to the client. If the + * string is empty, then the config was successfully updated. Otherwise, + * the string contains the name of the first parameter that caused an + * error during the update handling. + *
  • + *
  • reloadConfig: Reloads the ArConfig from the text file. + *
  • + *
  • configUpdated: An empty packet is broadcast to all interested clients + * after setConfig or reloadConfig has been completed. The clients may + * then request the modified ArConfig data with getConfigBySections + * (or getConfig). + *
  • + *
  • getConfigDefaults: If a "default" configuration file is available, + * then this command can be used to send the preferred default values + * to the client. The received packet should contain a single string, + * which is the name of the section to be retrieved, or an empty string + * to indicate all sections. + * + * For each requested section, the reply packet contains: + *
      + *
    1. Section Indicator: Always set to "Section" (string)
    2. + *
    3. Section Name: (string)
    4. + *
    + * Followed by a brief "text" description of each default parameter value. + * This is the parameter name (string) followed by the parameter value + * formatted as text (string). See ArClientArgUtils for more information. + *
  • + *
+ * + * If you are using this class with the default file option you'll + * want to make it AFTER you're done adding things to the config, ie + * last, so that the default code can work correctly (it needs to know + * about all the info). +**/ +class ArServerHandlerConfig +{ +public: + + /// Constructor + /** + * @param server the ArServerBase * used to send and receive network packets; + * must be non-NULL + * @param config the ArConfig * that is maintained by this server handler + * @param defaultFile the char * name of the file that contains the default + * values for the ArConfig; if NULL, then getConfigDefaults will not be + * supported + * @param defaultFileBaseDirectory the char * name of the directory that + * contains the default file + **/ + AREXPORT ArServerHandlerConfig(ArServerBase *server, + ArConfig *config, + const char *defaultFile = NULL, + const char *defaultFileBaseDirectory = NULL, + bool allowFactory = true, + const char *robotName = NULL, + bool preventChanges = false, + const char *preventChangesString = NULL); + + /// Destructor + AREXPORT virtual ~ArServerHandlerConfig(); + + // --------------------------------------------------------------------------- + // Network Packet Handlers + // --------------------------------------------------------------------------- + + /// Handles the "reloadConfig" request. + AREXPORT void reloadConfig(ArServerClient *client, ArNetPacket *packet); + + /// Handles the "getConfigBySections" request. + AREXPORT void getConfigBySections(ArServerClient *client, ArNetPacket *packet); + + /// Handles the "getConfigBySectionsV2" request. + AREXPORT void getConfigBySectionsV2(ArServerClient *client, ArNetPacket *packet); + + /// Handles the "getConfigBySectionsV3" request. + AREXPORT void getConfigBySectionsV3(ArServerClient *client, ArNetPacket *packet); + + /// Handles the (deprecated) "getConfig" request. + AREXPORT void getConfig(ArServerClient *client, ArNetPacket *packet); + + /// Handles the "setConfig" request. + AREXPORT void setConfig(ArServerClient *client, ArNetPacket *packet); + + AREXPORT void setConfigBySections(ArServerClient *client, ArNetPacket *packet); + + AREXPORT void setConfigBySectionsV2(ArServerClient *client, ArNetPacket *packet); + + /// Handles the "getConfigDefaults" request. + AREXPORT void getConfigDefaults(ArServerClient *client, ArNetPacket *packet); + + /// Handles the "getConfigSectionFlags" request. + AREXPORT void getConfigSectionFlags(ArServerClient *client, + ArNetPacket *packet); + + /// Handles the "getLastEditablePriority" request. + AREXPORT void getLastEditablePriority(ArServerClient *client, + ArNetPacket *packet); + + // --------------------------------------------------------------------------- + // Callback Methods + // --------------------------------------------------------------------------- + + /// Adds a callback to be called before writing to disk + AREXPORT void addPreWriteCallback(ArFunctor *functor, + ArListPos::Pos position = ArListPos::LAST); + /// Removes a callback to be called before writing to disk + AREXPORT void remPreWriteCallback(ArFunctor *functor); + + /// Adds a callback to be called after writing to disk + AREXPORT void addPostWriteCallback(ArFunctor *functor, + ArListPos::Pos position = ArListPos::LAST); + /// Removes a callback to be called after writing to disk + AREXPORT void remPostWriteCallback(ArFunctor *functor); + + /// Adds a callback to be called when the config is updated + AREXPORT void addConfigUpdatedCallback(ArFunctor *functor, + ArListPos::Pos position = ArListPos::LAST); + /// Removes a callback to be called when the config is updated + AREXPORT void remConfigUpdatedCallback(ArFunctor *functor); + + /// Restarts the IO manually (mostly for because of a config change) + void restartIO(const char *reason); + /// Restarts the software manually (mostly for because of a config change) + void restartSoftware(const char *reason); + /// Restarts the hardware manually (mostly for because of a config change) + void restartHardware(const char *reason); + + /// Adds a callback for when the IO is changed + void addRestartIOCB(ArFunctor *functor, int position = 50) + { myRestartIOCBList.addCallback(functor, position); } + /// Adds a callback for when the IO is changed + void remRestartIOCB(ArFunctor *functor) + { myRestartIOCBList.remCallback(functor); } + + /// Sets a callback for when a RESTART_SERVER config param is changed + AREXPORT void setRestartSoftwareCB(ArFunctor *restartServerCB); + + /// Gets the callback for when a RESTART_SERVER config param is changed + AREXPORT ArFunctor *getRestartSoftwareCB(void); + + /// Sets a callback for when a RESTART_ROBOT config param is changed + AREXPORT void setRestartHardwareCB(ArFunctor *restartRobotCB); + + /// Gets the callback for when a RESTART_ROBOT config param is changed + AREXPORT ArFunctor *getRestartHardwareCB(void); + + /// Locks the config so we don't do anything with it + AREXPORT int lockConfig(void) { return myConfigMutex.lock(); } + /// Tries to lock the config so we don't do anything with it + AREXPORT int tryLockConfig(void) { return myConfigMutex.tryLock(); } + /// Unlocks the config so we can use it again + AREXPORT int unlockConfig(void) { return myConfigMutex.unlock(); } + + /// Writes the config out + AREXPORT bool writeConfig(void); + /// Notifies the clients that the config was updated + AREXPORT bool configUpdated(ArServerClient *client = NULL); + + /// Changes the variables that prevent changes + void setPreventChanges(bool preventChanges = false, + const char *preventChangesString = NULL); + + /// loads the whole of a default file (for internal use) + AREXPORT bool loadDefaultsFromFile(void); + /// Parses a line of the default config (for internal use) + AREXPORT bool loadDefaultsFromPacket(ArNetPacket *packet); + /// Creates an empty default config... + AREXPORT void createEmptyConfigDefaults(void); + + /// Changes if factory is allowed... this is internal, only for when + /// that decision is deferred + void setAllowFactory(bool allowFactory) + { myPermissionAllowFactory = allowFactory; } + /// Changes if factory is allowed... this is internal, only for when + /// that decision is deferred + bool getAllowFactory(void) + { return myPermissionAllowFactory; } +protected: + + AREXPORT void doGetConfigBySections(ArServerClient *client, + ArNetPacket *packet, + int version); + + /// Helper method for the get config callbacks (e.g. getConfigBySections, getConfig, ...). + AREXPORT void handleGetConfig(ArServerClient *client, + ArNetPacket *packet, + bool isMultiplePackets, + ArPriority::Priority lastPriority, + bool isSendIneditablePriorities, + int version); + + /// Helper method for the get config callbacks (e.g. getConfigBySections, getConfig, ...). + AREXPORT bool handleGetConfigSection(ArNetPacket &sending, + ArServerClient *client, + ArNetPacket *packet, + bool isMultiplePackets, + ArPriority::Priority lastPriority, + bool isSendIneditablePriorities, + int version, + ArConfigSection *section, + int startIndex, + int paramCount, + int sectionIndex, + std::set &sentParams); + + + /// Internal method that handles a setConfig packet for myConfig or + /// myDefaults + bool internalSetConfig(ArServerClient *client, + ArNetPacket *packet, + int version, + bool isMultiplePackets = false); + + /// just creates the default config... (internal, don't use) + void createDefaultConfig(const char *defaultFileBaseDir); + /// Adds the default config callbacks; + void addDefaultServerCommands(void); + + /// Determines the last editable priority based on the input flags + ArPriority::Priority findLastEditablePriority(); + + ArPriority::Priority convertToPriority(int priorityVal, + ArPriority::Priority defaultPriority); + + +protected: + + std::string myRobotName; + std::string myLogPrefix; + + ArServerBase *myServer; + ArConfig *myConfig; + + + ArConfig *myDefault; + std::string myDefaultFile; + std::string myDefaultFileBaseDir; + ArMutex myDefaultConfigMutex; + bool myAddedDefaultServerCommands; + + bool myPermissionAllowFactory; + bool myPreventChanges; + std::string myPreventChangesString; + + ArMutex myConfigMutex; + + std::list myPreWriteCallbacks; + std::list myPostWriteCallbacks; + std::list myConfigUpdatedCallbacks; + + ArCallbackList myRestartIOCBList; + ArFunctor *myRestartSoftwareCB; + bool myRestartSoftwareCBSet; + ArFunctor *myRestartHardwareCB; + bool myRestartHardwareCBSet; + + ArFunctor2C myGetConfigBySectionsCB; + ArFunctor2C myGetConfigBySectionsV2CB; + ArFunctor2C myGetConfigBySectionsV3CB; + ArFunctor2C myGetConfigCB; + ArFunctor2C mySetConfigCB; + ArFunctor2C mySetConfigBySectionsCB; + ArFunctor2C mySetConfigBySectionsV2CB; + ArFunctor2C myReloadConfigCB; + ArFunctor2C myGetConfigDefaultsCB; + ArFunctor2C myGetConfigSectionFlagsCB; + ArFunctor2C myGetLastEditablePriorityCB; + +}; + +#endif diff --git a/Legacy/Aria/ArNetworking/include/ArServerHandlerMap.h b/Legacy/Aria/ArNetworking/include/ArServerHandlerMap.h new file mode 100644 index 0000000..ba1a739 --- /dev/null +++ b/Legacy/Aria/ArNetworking/include/ArServerHandlerMap.h @@ -0,0 +1,185 @@ +#ifndef ARSERVERMAP_H +#define ARSERVERMAP_H + +#include "Aria.h" +#include "ArServerBase.h" +#include "ArConfig.h" + + +class ArServerClient; + +class ArMapInterface; + +/** @brief Service providing the contents of a map file to the client. + * + * A map can be provided from an ArMap object, or else the + * filename can be given in the global ArConfig object (see Aria::getConfig()) + * as "Map" in the "Files" section. This handler can also be configured to + * only send "point" data, "line" data, or both kinds of data from the map. + * + * This service accepts the following data requests: + *
    + *
  • getMapId + *
  • getMapName + *
  • getMap + *
  • getGoals + *
  • getMapBinary + *
  • getMapMultiScans + *
+ * + * The following data types will also be broadcast to all clients to indicate + * certain events: + *
    + *
  • mapUpdated + *
  • goalsUpdated + *
+ * + * The getMapId request replies with: a map + * source identifier (NULL-terminated string); a filename for the map + * (NULL-terminated string); a checksum value preceded by a 4-byte unsigned + * integer providing the length (in bytes) of that checksum value; the total + * data size of the map contents (4-byte unsigned integer); and a timestamp + * for the map file (last modified, 4-byte signed integer, UNIX time). + * + * The getMapName request replies with a packet containing a + * NULL-terminated string containing the filename of the map, or an empty string + * ("") if there is no map. + * + * The getMap request replies with a series of packets each + * containing one line from the map file (as a null-terminated string), + * followed by an empty packet signifying + * the end of the packet. + * (see the documentation for ArMap for the map file + * format). This data may be written (with newlines added) to a map file, + * or may be parsed directly by an empty ArMap object using ArMap::parseLine() + * and ArMap::parsingComplete(). See tests/mapClient.cpp for an example of usage. + * + * The getGoals request replies with a packet containing a series of NULL-terminated + * strings containing the names of the Goal objects in the map. + * + * The getMapBinary request replies with the map headers and + * objects list (see ArMap for map file format) as text, but supplies point + * "DATA" and/or "LINES" as an undelimited sequence of 2-byte integers. (In + * the case of point data, each pair of integers is a point; for lines, each + * sequence of four integers defines a line). This binary representation of data + * is more compact than the ASCII text representation. This request results in a + * series of packets, with an empty packet signifying the end of the series. + * + * The getMapMultiScans request is similar to getMapBinary, + * but it includes a list of the scan sources, along with the point and lines + * for each scan source in binary format. + * + * The mapUpdated packet is sent to all connected clients whenever + * a new map is loaded or the map is changed. The packet contains no data; the + * new map can be downloaded using one of the above requests. + * + * The goalsUpdated packet is sent to all connected clients + * whenever the list of Goal objects changes in the map or a new map is loaded. + * The packet contains no data; the new list of goals can be downloaded using + * getGoals, or by downloading the entire map. + * + */ +class ArServerHandlerMap +{ +public: + enum DataToSend { LINES = 1, POINTS = 2, BOTH = 3 }; + /// Constructor + AREXPORT ArServerHandlerMap(ArServerBase *server, + ArMapInterface *arMap = NULL, + DataToSend dataToSend = BOTH); + /// Destructor + AREXPORT virtual ~ArServerHandlerMap(); + /// Loads the map from a file + AREXPORT bool loadMap(const char *mapFile); + /// Uses a map already loaded + AREXPORT void useMap(ArMapInterface *mapObj, + bool takeOwnershipOfMap = false); + /// Gets the map object this is using + AREXPORT ArMapInterface *getMap(void); + + /// Handles the request for the map ID. + AREXPORT void serverGetMapId(ArServerClient *client, + ArNetPacket *packet); + /// The command that gets the map name + AREXPORT void serverGetMapName(ArServerClient *client, + ArNetPacket *packet); + /// The command that'll get the map itself + AREXPORT void serverGetMap(ArServerClient *client, + ArNetPacket *packet); + /// The command that gets the map, with the data in binary format for improved performance + AREXPORT void serverGetMapBinary(ArServerClient *client, + ArNetPacket *packet); + + /// Requests that the server send the map, including scan data for multiple sources if available. + AREXPORT void serverGetMapMultiScans(ArServerClient *client, + ArNetPacket *packet); + + /// Requests that the server send the map with the specified maximum features. + AREXPORT void serverGetMapWithMaxCategory(ArServerClient *client, + ArNetPacket *packet); + + /// The command that'll get the goals + AREXPORT void serverGetGoals(ArServerClient *client, + ArNetPacket *packet); + + /// Sets which kind of data we send + AREXPORT void setDataToSend(DataToSend dataToSend) + { myDataToSend = dataToSend; } + /// Gets which kind of data we send + DataToSend getDataToSend(void) { return myDataToSend; } + +protected: + AREXPORT void handleCheckMap(ArServerClient *client, + ArNetPacket *packet); + + AREXPORT void sendMapWithMaxCategory(ArServerClient *client, + const char *maxCategory); + + AREXPORT bool processFile(void); + AREXPORT void mapChanged(void); + // internal function that is used to toss the map to the client + AREXPORT void writeMapToClient(const char *line, ArServerClient *client); + + + AREXPORT void writePointsToClient(int pointCount, + std::vector *points, + ArServerClient *client); + + AREXPORT void writeLinesToClient(int lineCount, + std::vector *points, + ArServerClient *client); + + ArServerBase *myServer; + bool myOwnMap; + DataToSend myDataToSend; + ArMapInterface *myMap; + std::string myMapName; + ArServerHandlerMap *myServerHandlerMap; + + bool myAlreadyLoaded; + char myMapFileName[512]; + char myLastMapFile[1024]; + struct stat myLastMapFileStat; + + ArFunctor2C myGetMapIdCB; + ArFunctor2C myGetMapNameCB; + ArFunctor2C myGetMapCB; + ArFunctor2C myGetMapBinaryCB; + ArFunctor2C myGetMapMultiScansCB; + ArFunctor2C myGetMapMaxCategoryCB; + ArFunctor2C myGetGoalsCB; + ArFunctor2C myCheckMapCB; + ArRetFunctorC myProcessFileCB; + ArFunctorC myMapChangedCB; +}; + +#endif + diff --git a/Legacy/Aria/ArNetworking/include/ArServerHandlerMapping.h b/Legacy/Aria/ArNetworking/include/ArServerHandlerMapping.h new file mode 100644 index 0000000..0f1e648 --- /dev/null +++ b/Legacy/Aria/ArNetworking/include/ArServerHandlerMapping.h @@ -0,0 +1,193 @@ +#ifndef ARSERVERHANDLERMAPPING_H +#define ARSERVERHANDLERMAPPING_H + +#include "Aria.h" +#include "ArServerBase.h" +#include "ArServerHandlerCommands.h" +#include "ArTempDirectoryHelper.h" + +/// Class that handles the starting, stopping, and status of mapping +class ArServerHandlerMapping +{ +public: + /// Constructor + AREXPORT ArServerHandlerMapping(ArServerBase *server, ArRobot *robot, + ArLaser *laser, + const char *baseDirectory = "", + const char *tempDirectory = "", + bool useReflectorValues = false, + ArLaser *laser2 = NULL, + const char *sickSuffix = NULL, + const char *sick2Suffix = NULL, + std::list *extraLasers = NULL); + /// Deconstructor + AREXPORT virtual ~ArServerHandlerMapping(); + /// Starts a new map unless ones already made + AREXPORT void serverMappingStart(ArServerClient *client, + ArNetPacket *packet); + /// Ends a map + AREXPORT void serverMappingEnd(ArServerClient *client, + ArNetPacket *packet); + /// Gets the mapping status + AREXPORT void serverMappingStatus(ArServerClient *client, + ArNetPacket *packet); + /// Returns if we're mapping or not + AREXPORT bool isMapping(void); + + /// Forces a reading to be taken + AREXPORT void forceReading(void); + + /// Gets the filename we're using (make sure the robot's locked) + AREXPORT const char *getFileName(void); + /// Gets the mapname we're using (make sure the robot's locked) + AREXPORT const char *getMapName(void); + /// Adds the simple commands to the simple command handler passed in + AREXPORT void addSimpleCommands(ArServerHandlerCommands *handlerCommands); + /// Adds a loop start to the log + AREXPORT void simpleLoopStart(ArArgumentBuilder *arg); + /// Adds a loop end to the log + AREXPORT void simpleLoopEnd(ArArgumentBuilder *arg); + /// Adds a string for adding to the log when we start + AREXPORT void addStringForStartOfLogs( + const char *str, ArListPos::Pos position = ArListPos::LAST); + /// Removes a string for adding to the log when we start + AREXPORT void remStringForStartOfLogs(const char *str); + /// Adds a tag to the logg (has robot pose and stuff) (make sure the + /// robot's locked) + AREXPORT void addTagToLog(const char *str); + /// Adds an info to the log (has no robot pose) (make sure the + /// robot's locked) + AREXPORT void addInfoToLog(const char *str); + /// Adds a new type of location data to the logger + AREXPORT bool addLocationData( + const char *name, + ArRetFunctor3 *functor); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Callback Methods + // + // The mapping callbacks are invoked in the order in which they appear + // in this header file. Namely: + // 1. MappingStart + // 2. MappingBegun (this is logically "mapping started") + // 3. MappingEnd + // 4. MappingEnded + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + /// Adds a callback for the start of mapping + AREXPORT void addMappingStartCallback( + ArFunctor *functor, ArListPos::Pos position = ArListPos::LAST); + /// Removes a callback for the start of mapping + AREXPORT void remMappingStartCallback(ArFunctor *functor); + + /// Adds a callback for just after mapping has started + AREXPORT void addMappingBegunCallback( + ArFunctor *functor, ArListPos::Pos position = ArListPos::LAST); + /// Removes a callback for just after mapping has started + AREXPORT void remMappingBegunCallback(ArFunctor *functor); + + /// Adds a callback for the end of mapping + AREXPORT void addMappingEndCallback( + ArFunctor *functor, ArListPos::Pos position = ArListPos::LAST); + /// Removes a callback for the end of mapping + AREXPORT void remMappingEndCallback(ArFunctor *functor); + + /// Adds a callback that is invoked after mapping has been ended. + AREXPORT void addMappingEndedCallback( + ArFunctor *functor, ArListPos::Pos position = ArListPos::LAST); + /// Removes a callback from the list invoked after mapping has been ended. + AREXPORT void remMappingEndedCallback(ArFunctor *functor); + + + /// Adds a callback to be called before moving from temp dir to base dir + AREXPORT void addPreMoveCallback( + ArFunctor *functor, ArListPos::Pos position = ArListPos::LAST); + /// Removes a callback to be called before moving from temp dir to base dir + AREXPORT void remPreMoveCallback(ArFunctor *functor); + + /// Adds a callback to be called after moving from temp dir to base dir + AREXPORT void addPostMoveCallback( + ArFunctor *functor, ArListPos::Pos position = ArListPos::LAST); + /// Removes a callback to be called after moving from temp dir to base dir + AREXPORT void remPostMoveCallback(ArFunctor *functor); + + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Misc Methods + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + /// The packet handler for starting/stopping scans from the lcd + AREXPORT bool packetHandler(ArRobotPacket *packet); + /// Get location data map (mostly for internal things) + AREXPORT const std::map *, + ArStrCaseCmpOp> *getLocationDataMap(void); + /// A method to add the strings for the start of a log just straight to an ArMap + AREXPORT void addStringsForStartOfLogToMap(ArMap *arMap); + + + /// Returns a pointer to the optional zip file installed on this handler. + AREXPORT ArZippable *getZipFile(); + + /// Returns a pointer to a second optional zip file used to contain snapshot images. + AREXPORT ArZippable *getSnapshotZipFile(); + + /// Sets the optional zip file installed on this handler. + AREXPORT void setZipFile(ArZippable *zipFile); + + /// Sets the optional zip file installed on this handler. + AREXPORT void setSnapshotZipFile(ArZippable *zipFile); + +protected: + + + AREXPORT std::string makeFilePathName(const char *fileName); + + ArServerBase *myServer; + ArRobot *myRobot; + ArLaser *myLaser; + ArLaser *myLaser2; + bool myUseReflectorValues; + + std::list myMappingStartCallbacks; + std::list myMappingBegunCallbacks; + std::list myMappingEndCallbacks; + std::list myMappingEndedCallbacks; + + std::list myPreMoveCallbacks; + std::list myPostMoveCallbacks; + + std::list myStringsForStartOfLog; + ArLaserLogger *myLaserLogger; + ArLaserLogger *myLaserLogger2; + std::string myMapName; + std::string myFileName; + std::string myFileName2; + + std::string mySuffix; + std::string mySuffix2; + + std::list *myExtraLasers; + + ArTempDirectoryHelper myTempDirectoryHelper; + + /// Optional zip file in which mapping results may be saved + ArZippable *myZipFile; + /// Second optional zip file in which snaphots may be saved + ArZippable *mySnapshotZipFile; + + std::map *, + ArStrCaseCmpOp> myLocationDataMap; + + ArFunctor2C myMappingStartCB; + ArFunctor2C myMappingEndCB; + ArFunctor2C myMappingStatusCB; + ArServerHandlerCommands *myHandlerCommands; + ArRetFunctor1C myPacketHandlerCB; + ArFunctor1C myLoopStartCB; + ArFunctor1C myLoopEndCB; +}; + + + +#endif // ARSERVERHANDLERMAPPING_H diff --git a/Legacy/Aria/ArNetworking/include/ArServerHandlerPopup.h b/Legacy/Aria/ArNetworking/include/ArServerHandlerPopup.h new file mode 100644 index 0000000..3a0cf6c --- /dev/null +++ b/Legacy/Aria/ArNetworking/include/ArServerHandlerPopup.h @@ -0,0 +1,256 @@ +#ifndef ARSERVERHANDLERPOPUP_H +#define ARSERVERHANDLERPOPUP_H + +#include "Aria.h" +#include "ArServerBase.h" + + +class ArServerClient; + +class ArServerHandlerPopupInfo; + +/// Class for having generic popups appear in MobileEyes (created on the server) +/** + TODO make the callbacks actually happen +**/ + +class ArServerHandlerPopup +{ +public: + /// Constructor + AREXPORT ArServerHandlerPopup(ArServerBase *server); + /// Destructor + AREXPORT virtual ~ArServerHandlerPopup(); + /// Creates a new popup + AREXPORT ArTypes::Byte4 createPopup( + ArServerHandlerPopupInfo *popupInfo, + ArFunctor2 *callback = NULL); + /// Cancels a popup with the ID + AREXPORT void closePopup(ArTypes::Byte4 id, + const char *closeMessage); + /// The call from the network that the popup was clicked + /// @internal + AREXPORT void netPopupClicked(ArServerClient *client, + ArNetPacket *packet); + /// The call from the network for getting the popup list + /// @internal + AREXPORT void netPopupList(ArServerClient *client, + ArNetPacket *packet); + /// Our cycle callback + /// @internal + AREXPORT void serverCycleCallback(void); + enum PopupType { + NOICON = 0, ///< No icon at all + INFORMATION = 1, ///< Just an informational message + WARNING = 2, ///< A warning + CRITICAL = 3, ///< A critical problem (program failure likely) + QUESTION = 4 ///< A question + }; +protected: + ArServerBase *myServer; + + class PopupData { + public: + /// Constructor (copies and owns popupInfo, leaves callback) + PopupData(ArServerHandlerPopupInfo *popupInfo, + ArTypes::Byte4 id, + ArFunctor2 *callback); + /// Destructor, deleted the popup info + virtual ~PopupData(); + /// The popup info + ArServerHandlerPopupInfo *myPopupInfo; + /// The functor to call when its done + ArFunctor2 *myCallback; + /// When we started this popup + ArTime myStarted; + /// The popup this was serving + ArTypes::Byte4 myID; + + }; + void buildPacket(ArNetPacket *sendingPacket, PopupData *popupData); + + ArMutex myDataMutex; + std::map myMap; + ArTypes::Byte4 myLastID; + ArTime myLastTimeCheck; + ArFunctor2C myNetPopupClickedCB; + ArFunctor2C myNetPopupListCB; + ArFunctorC myServerCycleCB; +}; + +/// Holds the information for a popup +/** + This holds the information for the popup.... So there's a message + box with the title which has in it the message, and has between 1 + and 3 buttons (button0, button1, and button2) with labels of + button0Label, button1Label, and button2Label (if the label is empty + or NULL then there'll be no button), the default button of + defaultButtonNumber (0 - 2) and the escape button number of + escapeButtonNumber (0 - 2)... when a button is pushed the + + @param ignoreIdentifier The identifier to use for ignoring these + boxes, this should be NULL or empty if you don't want this + particular box to be able to be ignored (if any popup with this + identifier is already being ignored this one will be too) + + @param title The title of the box (displayed in the titlebar) + + @param message The string that will be displayed in the message box + (the point of the whole thing) + + @param popupType The type of popup this is, which controls the icon + displayed, may someday affect behavior + + @param defaultButtonPressed The button that enter defaults to (This + should be whatever is most likely) + + @param escapeButtonPressed The button that escape defaults to (this + should be doesn't change the state, ie like cancel), this also + should be whats returned if the X is hit. + + @param button0Label The label that is displayed on button 0, the + leftmost button + + @param timeoutInSeconds the number of seconds we should give people + to respond to the popup before timing it out, 0 means leave it up + forever (note that no clients may be watching this or no one may be + at the console and use this option wisely (way too many untimed out + popups could bog down the server)) + + @param timeoutString The string that will be displayed if a timeout + happens + + @param button0Pressed The string that will be put into the box if + button0 is pressed (this is mainly so that with multiple clients + connected the other clients will get feedback) + + @param button1Label The label that is displayed on button 1 (the + middle button if there are 3, right button if there are two) + + @param button1Pressed The string that will be put into the box if + button1 is pressed (this is mainly so that with multiple clients + connected the other clients will get feedback) + + @param button2Label The label that is displayed on button 2 (the + right button) + + @param button2Pressed The string that will be put into the box if + button2 is pressed (this is mainly so that with multiple clients + connected the other clients will get feedback) + **/ +class ArServerHandlerPopupInfo +{ +public: + /// Constructor + AREXPORT ArServerHandlerPopupInfo( + const char *ignoreIdentifier, const char *title, + const char *message, ArServerHandlerPopup::PopupType popupType, + ArTypes::Byte defaultButtonNumber, + ArTypes::Byte escapeButtonNumber, + int timeoutInSeconds, const char *timeoutString, + const char *button0Label, const char *button0Pressed, + const char *button1Label = "", const char *button1Pressed = "", + const char *button2Label = "", const char *button2Pressed = ""); + + /// Destructor + AREXPORT virtual ~ArServerHandlerPopupInfo(); + /// Copy constructor + AREXPORT ArServerHandlerPopupInfo(const ArServerHandlerPopupInfo &popupInfo); + /// Assignment operator + AREXPORT ArServerHandlerPopupInfo &operator=( + const ArServerHandlerPopupInfo &popupInfo); + + /// Gets the popup identifer (this is used only for ignoring popups, if empty or NULL then it can't be ignored) + const char *getIgnoreIdentifier(void) { return myIgnoreIdentifier.c_str(); } + /// Gets the title (the title of the popup box) + const char *getTitle(void) { return myTitle.c_str(); } + /// Gets the message (the long string that is displayed that explains things) + const char *getMessage(void) { return myMessage.c_str(); } + /// Gets the type (the icon thats displayed and what type of popup it is) + ArServerHandlerPopup::PopupType getPopupType(void) { return myPopupType; } + /// Gets the default button number (whats pressed when enter is hit) + ArTypes::Byte getDefaultButtonNumber(void) { return myDefaultButtonNumber; } + /// Gets the escape button number (whats pressed when escape is hit) + ArTypes::Byte getEscapeButtonNumber(void) { return myEscapeButtonNumber; } + /// Gets the timeout in seconds (0 is never) + int getTimeout(void) { return myTimeout; } + /// Gets the timeout string (the string that is displayed on the popup if timeout occurs) + const char * getTimeoutString(void) + { return myTimeoutString.c_str(); } + /// Gets the button0Label (the label on the leftmost button, must have a label) + const char *getButton0Label(void) { return myButton0Label.c_str(); } + /// Gets the button0Pressed (string sent as box disppears if this button is pressed) + const char *getButton0Pressed(void) { return myButton0Pressed.c_str(); } + + /// Gets the button1Label (the label on the middle button, empty string or NULL for no button) + const char *getButton1Label(void) { return myButton1Label.c_str(); } + /// Gets the button1Pressed (string sent as box disppears if this button is pressed) + const char *getButton1Pressed(void) { return myButton1Pressed.c_str(); } + /// Gets the button2Label (the label on the right button, empty string or NULL for no button) + const char *getButton2Label(void) { return myButton2Label.c_str(); } + /// Gets the button2Pressed (string sent as box disppears if this button is pressed) + const char *getButton2Pressed(void) { return myButton2Pressed.c_str(); } + + /// Gets the popup identifer (this is used only for ignoring popups, if empty or NULL then it can't be ignored) + void setIgnoreIdentifier(const char *identifier) + { if (identifier != NULL) myIgnoreIdentifier = identifier; else myIgnoreIdentifier = ""; } + /// Sets the title (the title of the popup box) + void setTitle(const char *title) + { if (title != NULL) myTitle = title; else myTitle = ""; } + /// Sets the message (the long string that is displayed that explains things) + void setMessage(const char *message) + { if (message != NULL) myMessage = message; else myMessage = ""; } + /// Sets the type (the icon thats displayed and what type of popup it is) + void setPopupType(ArServerHandlerPopup::PopupType popupType) + { myPopupType = popupType; } + /// Sets the default button number (whats pressed when enter is hit) + void setDefaultButtonNumber(ArTypes::Byte defaultButtonNumber) + { myDefaultButtonNumber = defaultButtonNumber; } + /// Sets the escape button number (whats pressed when escape is hit) + void setEscapeButtonNumber(ArTypes::Byte escapeButtonNumber) + { myEscapeButtonNumber = escapeButtonNumber; } + /// Sets the timeout in seconds (0 is never) + void setTimeout(int timeoutInSeconds) + { myTimeout = timeoutInSeconds; } + /// Sets the timeout string (the string that is displayed on the popup if timeout occurs) + void setTimeoutString(const char *timeoutString) + { if (timeoutString != NULL) myTimeoutString = timeoutString; else myTimeoutString = ""; } + /// Sets the button0Label (the label on the leftmost button, must have a label) + void setButton0Label(const char *label) + { if (label != NULL) myButton0Label = label; else myButton0Label = ""; } + /// Sets the button0Pressed (string sent as box disppears if this button is pressed) + void setButton0Pressed(const char *pressed) + { if (pressed != NULL) myButton0Pressed = pressed; else myButton0Pressed = ""; } + /// Sets the button1Label (the label on the middle button, empty string or NULL for no button) + void setButton1Label(const char *label) + { if (label != NULL) myButton1Label = label; else myButton1Label = ""; } + /// Sets the button1Pressed (string sent as box disppears if this button is pressed) + void setButton1Pressed(const char *pressed) + { if (pressed != NULL) myButton1Pressed = pressed; else myButton1Pressed = ""; } + /// Sets the button2Label (the label on the right button, empty string or NULL for no button) + void setButton2Label(const char *label) + { if (label != NULL) myButton2Label = label; else myButton2Label = ""; } + /// Sets the button2Pressed (string sent as box disppears if this button is pressed) + void setButton2Pressed(const char *pressed) + { if (pressed != NULL) myButton2Pressed = pressed; else myButton2Pressed = ""; } + +protected: + std::string myIgnoreIdentifier; + std::string myTitle; + std::string myMessage; + ArServerHandlerPopup::PopupType myPopupType; + ArTypes::Byte myDefaultButtonNumber; + ArTypes::Byte myEscapeButtonNumber; + int myTimeout; + std::string myTimeoutString; + std::string myButton0Label; + std::string myButton0Pressed; + std::string myButton1Label; + std::string myButton1Pressed; + std::string myButton2Label; + std::string myButton2Pressed; +}; + +#endif // ARSERVERHANDLERPOPUP_H diff --git a/Legacy/Aria/ArNetworking/include/ArServerInfoDrawings.h b/Legacy/Aria/ArNetworking/include/ArServerInfoDrawings.h new file mode 100644 index 0000000..447c8bb --- /dev/null +++ b/Legacy/Aria/ArNetworking/include/ArServerInfoDrawings.h @@ -0,0 +1,88 @@ +#ifndef ARSERVERINFODRAWINGS_H +#define ARSERVERINFODRAWINGS_H + +#include "Aria.h" +#include "ArServerBase.h" + +class ArServerClient; + +/** Service to provide clients with information about graphical figures to be + displayed with the map. + + Use addDrawing() to add a figure, or use addRangeDevice() or + addRobotsRangeDevice() to automatically create standard drawings for + range devices. + + Clients may use the listDrawings data + request to receive a list of figures and metadata about those figures. + The reply packet to the listDrawings request is as follows: +
    +
  1. Number of figures (4-byte integer)Then, for each figure, the following values are given +
  2. For each figure: +
      +
    1. Figure name (null-terminated string)
    2. +
    3. Shape ID (null-terminated string)
    4. +
    5. Primary color:
        +
      1. Unused (byte)
      2. +
      3. Red (byte)
      4. +
      5. Green (byte)
      6. +
      7. Blue (byte)
      8. +
    6. +
    7. Shape size (4-byte integer)
    8. +
    9. Layer number (4-byte integer)
    10. +
    11. Suggested refresh time (4-byte integer)
    12. +
    13. Secordary color:
        +
      1. Unused (byte)
      2. +
      3. Red (byte)
      4. +
      5. Green (byte)
      6. +
      7. Blue (byte)
      8. +
    14. + +
    +
+ + This command is in the SensorInfo permission group for users. +*/ +class ArServerInfoDrawings +{ +public: + /// Constructor + AREXPORT ArServerInfoDrawings(ArServerBase *server); + /// Destructor + AREXPORT virtual ~ArServerInfoDrawings(); + /// Adds a shape to the set of figures + AREXPORT bool addDrawing(ArDrawingData *drawingData, const char *name, + ArFunctor2 *functor); + /// Adds a specific range device to be drawn (using its default shape) + AREXPORT bool addRangeDevice(ArRangeDevice *rangeDevice); + /// Adds all of the robot's range devices (using their default shape) + AREXPORT bool addRobotsRangeDevices(ArRobot *robot); + /// Client callback: Puts the list of shapes that can be drawn and their metadata into a reply packet (internal use mostly) + AREXPORT void netListDrawings(ArServerClient *client, ArNetPacket *packet); + + AREXPORT void netGetDrawingList(ArServerClient *client, ArNetPacket *packet); + + /// Client callback utility: Puts the current data for the given range device into a reply packet (internal use mostly) + AREXPORT void netRangeDeviceCurrent(ArServerClient *client, + ArNetPacket *packet, + ArRangeDevice *device); + /// Client callback utilit: Puts the cumulative buffer of the given range device into a reply packet (internal use mostly) + AREXPORT void netRangeDeviceCumulative(ArServerClient *client, + ArNetPacket *packet, + ArRangeDevice *device); + /// internal function that gets the drawing data for a drawing + /// @internal + AREXPORT ArDrawingData *internalGetDrawingData(const char *name); + /// internal function that gets the functor for a drawing + /// @internal + AREXPORT ArFunctor2 *internalGetDrawingCallback(const char *name); +protected: + ArServerBase *myServer; + std::map myDrawingDatas; + std::map *, ArStrCaseCmpOp> myDrawingCallbacks; + ArFunctor2C myNetListDrawingsCB; + ArFunctor2C myNetGetDrawingListCB; +}; + + +#endif diff --git a/Legacy/Aria/ArNetworking/include/ArServerInfoRobot.h b/Legacy/Aria/ArNetworking/include/ArServerInfoRobot.h new file mode 100644 index 0000000..94006d8 --- /dev/null +++ b/Legacy/Aria/ArNetworking/include/ArServerInfoRobot.h @@ -0,0 +1,123 @@ +#ifndef ARSERVERROBOTINFO_H +#define ARSERVERROBOTINFO_H + +#include "Aria.h" +#include "ArServerBase.h" + +class ArServerClient; + +/** Server component providing basic robot status information to clients. + * This service accepts the following data requests: + *
    + *
  • update
  • + *
  • physicalInfo
  • + *
  • batteryInfo
  • + *
  • activityTimeInfo
  • + *
+ * + * For bandwidth savings you should use updateNumbers + * and updateStrings instead of update. + * + * The update request returns data regarding the current + * state of the robot. + * It replies with the following data packet: + *
    + *
  1. Status (Null-terminated string)
  2. + *
  3. Mode (Null-terminated string)
  4. + *
  5. Battery voltage (times 10) (2 Byte integer)
  6. + *
  7. X position (4 byte floating point number)
  8. + *
  9. Y position (4 byte floating point number)
  10. + *
  11. Theta (2-byte floating point number)
  12. + *
  13. Forward velocity (2-byte integer)
  14. + *
  15. Rotation velocity (2-byte integer)
  16. + *
+ * + * The updateNumbers request returns data regarding the current + * state of the robot. + * It replies with the following data packet: + *
    + *
  1. Battery voltage (times 10) (2 Byte integer)
  2. + *
  3. X position (4 byte floating point number)
  4. + *
  5. Y position (4 byte floating point number)
  6. + *
  7. Theta (2-byte floating point number)
  8. + *
  9. Forward velocity (2-byte integer)
  10. + *
  11. Rotation velocity (2-byte integer)
  12. + *
+ * + * The updateStrings request broadcasts data regarding + * the current state of the robot. Request this at -1 to get the + * broadcasts and an initial packet with the inital data. + * It replies with the following data packet: + *
    + *
  1. Status (Null-terminated string)
  2. + *
  3. Mode (Null-terminated string)
  4. + *
+ * + * The physicalInfo request returns data regarding the physical characteristics of + * the robot. This information does not change during the robot execution. It replies with the + * following data packet: + *
    + *
  1. Robot type (Null-terminated string)
  2. + *
  3. Robot sub-type (Null-terminated string)
  4. + *
  5. Robot width in mm (2 byte integer)
  6. + *
  7. Robot front length - mm from center of rotation to front of robot (2 byte integer)
  8. + *
  9. Robot rear length - mm from center of rotation to back of robot (2 byte integer)
  10. + *
+ * + * The batteryInfo request replies with the following data packet: + *
    + *
  1. Warning voltage (double)
  2. + *
  3. Shutdown voltage (double)
  4. + *
+ * + * The activityTimeInfo request replies with the following data packet: + *
    + *
  1. Sec since - the ArServerMode::getActiveModeActivityTimeSecSince value (4-byte int)
  2. + *
+ * + * These requests are in the RobotInfo command group. + */ + +class ArServerInfoRobot +{ +public: + /// Constructor + AREXPORT ArServerInfoRobot(ArServerBase *server, ArRobot *robot); + /// Destructor + AREXPORT virtual ~ArServerInfoRobot(); + /// The function that sends updates about the robot off to the client + AREXPORT void update(ArServerClient *client, ArNetPacket *packet); + /// The function that sends updates about the robot off to the client + AREXPORT void updateNumbers(ArServerClient *client, ArNetPacket *packet); + /// The function that sends updates about the robot off to the client + AREXPORT void updateStrings(ArServerClient *client, ArNetPacket *packet); + /// The function that sends battery info about the robot off to the client + AREXPORT void batteryInfo(ArServerClient *client, ArNetPacket *packet); + /// The function that sends information about the physical robot + AREXPORT void physicalInfo(ArServerClient *client, ArNetPacket *packet); + /// The function that sends information about the time that the server mode was last active + AREXPORT void activityTimeInfo(ArServerClient *client, ArNetPacket *packet); +protected: + ArServerBase *myServer; + ArRobot *myRobot; + + void userTask(void); + + std::string myStatus; + std::string myExtendedStatus; + std::string myMode; + std::string myOldStatus; + std::string myOldExtendedStatus; + std::string myOldMode; + + + ArFunctor2C myUpdateCB; + ArFunctor2C myUpdateNumbersCB; + ArFunctor2C myUpdateStringsCB; + ArFunctor2C myBatteryInfoCB; + ArFunctor2C myPhysicalInfoCB; + ArFunctor2C myActivityTimeInfoCB; + ArFunctorC myUserTaskCB; +}; + +#endif diff --git a/Legacy/Aria/ArNetworking/include/ArServerInfoSensor.h b/Legacy/Aria/ArNetworking/include/ArServerInfoSensor.h new file mode 100644 index 0000000..39e6c87 --- /dev/null +++ b/Legacy/Aria/ArNetworking/include/ArServerInfoSensor.h @@ -0,0 +1,65 @@ +#ifndef ARSERVERSENSORINFO_H +#define ARSERVERSENSORINFO_H + +#include "Aria.h" +#include "ArServerBase.h" + +class ArServerClient; + +/** Service providing clients with data from range sensors. + * This service accepts the following data requests: + *
    + *
  • getSensorList to get a list of all robot sensors
  • + *
  • getSensorCurrent to get one range sensor's set of current readings
  • + *
  • getSensorCumulative to get one range sensor's set of cumualtive readings
  • + *
+ * + * The getSensorList request replies with the following data packet: + *
    + *
  1. Number of sensors (2-byte integer) + *
  2. For each sensor: + *
    1. sensor name (Null-terminated string)
    + *
  3. + *
+ * + * The getSensorCurrent and getSensorCumulative + * requests must include the following data: + *
    + *
  1. Sensor name (Null-terminated string)
  2. + *
+ * + * The getSensorCurrent and getSensorCumulative + * requests reply with the following data packets: + *
    + *
  1. Number of readings, or -1 for invalid sensor name error (2-byte integer)
  2. + *
  3. Sensor name (null-terminated string)
  4. + *
  5. For each reading: + *
      + *
    1. X coordinate of reading (4-byte integer)
    2. + *
    3. Y coordinate of reading (4-byte integer)
    4. + *
    + *
  6. + *
+ * + * This service's requests are all in the SensorInfo group. + */ +class ArServerInfoSensor +{ +public: + AREXPORT ArServerInfoSensor(ArServerBase *server, ArRobot *robot); + AREXPORT virtual ~ArServerInfoSensor(); + AREXPORT void getSensorList(ArServerClient *client, ArNetPacket *packet); + AREXPORT void getSensorCurrent(ArServerClient *client, ArNetPacket *packet); + AREXPORT void getSensorCumulative(ArServerClient *client, + ArNetPacket *packet); +protected: + ArRobot *myRobot; + ArServerBase *myServer; + ArFunctor2C myGetSensorListCB; + ArFunctor2C myGetSensorCurrentCB; + ArFunctor2C myGetSensorCumulativeCB; + +}; + + +#endif diff --git a/Legacy/Aria/ArNetworking/include/ArServerInfoStrings.h b/Legacy/Aria/ArNetworking/include/ArServerInfoStrings.h new file mode 100644 index 0000000..6669d2f --- /dev/null +++ b/Legacy/Aria/ArNetworking/include/ArServerInfoStrings.h @@ -0,0 +1,67 @@ +#ifndef ARSERVERHANDLERSTRINGS_H +#define ARSERVERHANDLERSTRINGS_H + +#include "Aria.h" +#include "ArServerBase.h" + +class ArServerClient; + +/** + This will set up strings to send to MobileEyes so that server + developers can easily add more information. There are different + ways ways you can add a string (they all are the same way + internally). The raw way is addString which takes a functor with a + buffer and a buffer len, the functor then has to fill in the string + when called. The other ways are set up for convenience and are + wrappers in this class around the addString, the other ways are + addStringInt, addStringDouble, addStringBool, these all take a + functor that returns the type and a format string (in addition to + the name and maxLen again). +**/ +class ArServerInfoStrings +{ +public: + /// Constructor + AREXPORT ArServerInfoStrings(ArServerBase *server); + /// Destructor + AREXPORT ~ArServerInfoStrings(); + /// Gets the information about the strings being sent + AREXPORT void netGetStringsInfo(ArServerClient *client, + ArNetPacket *packet); + /// Gets the strings + AREXPORT void netGetStrings(ArServerClient *client, + ArNetPacket *packet); + /// Adds a string to the list in the raw format + AREXPORT void addString(const char *name, ArTypes::UByte2 maxLen, + ArFunctor2 *functor); + /// Gets the functor for adding a string (for ArStringInfoGroup) + ArFunctor3 *> * + getAddStringFunctor(void) { return &myAddStringFunctor; } + + /// Gets a string info holder, for internal purposes + AREXPORT ArStringInfoHolder *internalGetStringInfoHolder(const char *name); + +protected: + ArServerBase *myServer; + + AREXPORT void buildStringsInfoPacket(void); + ArNetPacket myStringInfoPacket; + AREXPORT void buildStringsPacket(void); + ArNetPacket myStringPacket; + ArTime myLastStringPacketBuild; + + std::list myStrings; + ArTypes::UByte2 myMaxMaxLength; + ArMutex myStringsMutex; + ArFunctor3C *> myAddStringFunctor; + + ArFunctor2C myNetGetStringsInfoCB; + ArFunctor2C myNetGetStringsCB; + +}; + +#endif // ARSERVERHANDLERSTRINGS_H diff --git a/Legacy/Aria/ArNetworking/include/ArServerMode.h b/Legacy/Aria/ArNetworking/include/ArServerMode.h new file mode 100644 index 0000000..2d2a175 --- /dev/null +++ b/Legacy/Aria/ArNetworking/include/ArServerMode.h @@ -0,0 +1,252 @@ +#ifndef ARSERVERMODE_H +#define ARSERVERMODE_H + +#include "Aria.h" +#include "ArServerBase.h" + +class ArServerModeIdle; +class ArServerClient; + +/// A mode for controlling the robot (only one active) + +/** + This is a lot like ArMode but for net control instead... + + Only one mode can control the robot at once, this is made to be + subclassed. Each subclass needs to implement activate and + deactivate, activate MUST call baseActivate and if baseActivate + returns false then the mode is NOT active and shouldn't do + anything. Further each class should set myMode and myStatus to the + mode its in and the things its doing... You can lock your mode in + with lockMode and unlock it with unlockMode but you should redefine + the inherited requestUnlock and unlock yourself and deactivate + gracefully. + + If you want to implement a server mode as a default mode then you also + need to implement checkDefault which will be called when nothing + else is active + + Note that there's a new mechanism in place where if you use + addModeData instead of addData on the ArServerBase the command will + be placed into a map of available modes with commands that can be + gotten by the client. The active mode and whether its locked and + will unlock and such can now be gotten too... this is all so that + different commands can be disabled in client GUIs when they aren't + available. +**/ +class ArServerMode +{ +public: + /// Constructor + AREXPORT ArServerMode(ArRobot *robot, ArServerBase *server, const char *name); + /// Destructor + AREXPORT virtual ~ArServerMode(); + /// This function should return the action group this mode uses + AREXPORT virtual ArActionGroup *getActionGroup(void) { return NULL; } + /** The function called when the mode is activated. Subclasses must implement + * this, but also call baseActivate().- + */ + AREXPORT virtual void activate(void) = 0; + /** The function called when the mode is deactivated. Subclasses must + * implement this, and also call baseDeactivate(). + */ + AREXPORT virtual void deactivate(void) = 0; + /// The function called if the mode is not activated because another mode superceded it. + AREXPORT virtual void activationDenied(void) {} + + /// The ArMode's user task, don't need one, subclass must provide if needed + AREXPORT virtual void userTask(void) {} + /// This will be called if another mode wants the lock broken (can ignore) + AREXPORT virtual void requestUnlock(void) { } + /// This will be called if another mode has to break the lock + AREXPORT virtual void forceUnlock(void); + /// Locks this mode in until its unlocked (mode must be the active mode) + AREXPORT void lockMode(bool willUnlockIfRequested = false); + /// Unlocks the mode so other modes can activate + AREXPORT void unlockMode(void); + /// Gets a string representing the mode we're in + AREXPORT const char *getMode(void) const { return myMode.c_str(); } + /// Gets a string representing the status of the mode we're in + AREXPORT const char *getStatus(void) const { return myStatus.c_str(); } + /// Gets a string representing the extended status of the mode we're + /// in + AREXPORT const char *getExtendedStatus(void) const { return myExtendedStatus.c_str(); } + /// Gets the active mode string + AREXPORT static const char *getActiveModeModeString(void); + /// Gets the active status string + AREXPORT static const char *getActiveModeStatusString(void); + /// Gets the active extended status string + AREXPORT static const char *getActiveModeExtendedStatusString(void); + /// Gets the name of the mode we're in + AREXPORT const char *getName(void) const { return myName.c_str(); } + /// Gets if this mode is active or not + AREXPORT bool isActive(void) const { return myIsActive; } + /// Gets if the active mode is locked or not + AREXPORT static bool isLocked(void); + /// Gets whether we'll unlock if requested or not + AREXPORT static bool willUnlockIfRequested(void); + /// Gets the active mode + AREXPORT static ArServerMode *getActiveMode(void); + /// Gets if we've set our activity time + AREXPORT bool hasSetActivityTime(void) { return myHasSetActivityTime; } + /// Gets the time of our last activity + AREXPORT ArTime getActivityTime(void); + /// Sets that we're active right now + AREXPORT void setActivityTimeToNow(void); + /// Gets the seconds since the activity of our active mode + AREXPORT static int getActiveModeActivityTimeSecSince(void); + /// Gets if the active mode set the activity time this cycle or not + AREXPORT static bool getActiveModeSetActivityThisCycle(void); + /// Sets this mode to default (so if a mode deactivates it activates this) + AREXPORT void addAsDefaultMode(ArListPos::Pos pos = ArListPos::LAST); + /// Sees if this wants to become the default mode + /** + This will be called when there would be no other modes, if this + mode wants to take over it should activate itself, if it doesn't + want to take over it shouldn't activate + **/ + AREXPORT virtual void checkDefault(void) {} + /// This should only be used by careful people and probably not then + AREXPORT void setMode(const char *str) { myMode = str; } + /// This should only be used by careful people and probably not then + /** + This changes the status of the mode and sets the + myStatusSetThisCycle to true. If the mode inheriting is setting + the status in cycles then it should use this status instead and + then clear the myStatusSetThisFlag to false. + **/ + AREXPORT void setStatus(const char *str) + { myStatus = str; myStatusSetThisCycle = true; } + /// Adds data to the list of this mode's commands + + + /// Returns whether the mode should be automatically resumed after it was interrupted + /** + * This method primarily applies when the mode has been interrupted by a + * forced docking situation. In that case, when the docking mode is complete, + * it will resume the interrupted mode -- if this method returns true. This + * would primarily be applicable to very long, complex modes. + * + * The default return value is false. + **/ + AREXPORT virtual bool isAutoResumeAfterInterrupt(); + + + AREXPORT bool addModeData( + const char *name, const char *description, + ArFunctor2 *functor, + const char *argumentDescription, const char *returnDescription, + const char *commandGroup = NULL, const char *dataFlags = NULL); + /// Gets the list of data for each mode + AREXPORT static void getModeDataList(ArServerClient *client, + ArNetPacket *packet); + /// Gets the info about which mode is active and such + AREXPORT static void getModeInfo(ArServerClient *client, + ArNetPacket *packet); + /// Handles the packet request for the mode busy state. + AREXPORT static void getModeBusy(ArServerClient *client, + ArNetPacket *packet); + + /// Adds a callback for when this class is activated + void addActivateCallback( + ArFunctor *functor, int position = 50) + { myActivateCallbacks.addCallback(functor, position); } + /// Removes a callback for when this class is activated + void remActivateCallback(ArFunctor *functor) + { myActivateCallbacks.remCallback(functor); } + /// Adds a callback for when this class is deactivated + void addDeactivateCallback( + ArFunctor *functor, int position = 50) + { myDeactivateCallbacks.addCallback(functor, position); } + /// Removes a callback for when this class is deactivated + void remDeactivateCallback(ArFunctor *functor) + { myDeactivateCallbacks.remCallback(functor); } + + /// Adds a single shot callback for when this class is deactivated + void addSingleShotDeactivateCallback( + ArFunctor *functor, int position = 50) + { mySingleShotDeactivateCallbacks.addCallback(functor, position); } + /// Removes a single shot callback for when this class is deactivated + void remSingleShotDeactivateCallback(ArFunctor *functor) + { mySingleShotDeactivateCallbacks.remCallback(functor); } + + /// Call that gets our idle mode + AREXPORT static ArServerModeIdle *getIdleMode(void); +protected: + AREXPORT static void modeUserTask(void); + AREXPORT static void buildModeInfoPacket(ArNetPacket *packet); + AREXPORT static std::list *getRequestedActivateModes(void); + AREXPORT void checkBroadcastModeInfoPacket(void); + /** Activates this mode if it can (returns true if it can, false otherwise). + If we have an ArRobot instance (myRobot), then robot motion is stopped. + Activity time is reset, and activate callbacks are called. + */ + AREXPORT bool baseActivate(void); + /** Deactivates this mode. Deactivation callbacks are called. The next mode to + be activated is activated, if any. (E.g. the global default mode) + */ + AREXPORT void baseDeactivate(void); + + ArCallbackList myActivateCallbacks; + ArCallbackList myDeactivateCallbacks; + ArCallbackList mySingleShotDeactivateCallbacks; + + bool myIsActive; + ArRobot *myRobot; + ArServerBase *myServer; + std::string myName; + // inheritors will want to play with these two strings as they are + // what is shown to the user + std::string myMode; + std::string myStatus; + bool myStatusSetThisCycle; + std::string myExtendedStatus; + + // variables for activity time (so we can do things if idle) this + // isn't static so that each mode can have its own + // 'myHasSetActivityTime' so that if a mode doesn't use this scheme + // it doesn't get tromped on + bool myHasSetActivityTime; + bool mySetActivityThisCycle; + ArTime myActivityTime; + ArMutex myActivityTimeMutex; + + AREXPORT static bool ourActiveModeLocked; + AREXPORT static bool ourActiveModeWillUnlockIfRequested; + AREXPORT static ArServerMode *ourActiveMode; + AREXPORT static ArServerMode *ourNextActiveMode; + AREXPORT static ArServerMode *ourLastActiveMode; + AREXPORT static bool ourActiveModeSetActivityThisCycle; + + AREXPORT ArServerMode *getLastActiveMode(); + + AREXPORT static bool ourIsBusy; + AREXPORT static ArServerBase *ourServerBase; + + AREXPORT static std::list ourModes; + AREXPORT static std::list ourDefaultModes; + AREXPORT static std::list ourRequestedActivateModes; + AREXPORT static std::multimap ourModeDataMap; + AREXPORT static ArMutex ourModeDataMapMutex; + + AREXPORT static ArGlobalFunctor2 ourGetModeDataListCB; + AREXPORT static ArGlobalFunctor2 ourGetModeInfoCB; + AREXPORT static ArGlobalFunctor2 ourGetModeBusyCB; + + AREXPORT static bool ourBroadcastActiveModeLocked; + AREXPORT static ArServerMode *ourBroadcastActiveMode; + AREXPORT static bool ourBroadcastActiveModeWillUnlockIfRequested; + AREXPORT static ArGlobalFunctor ourUserTaskCB; + AREXPORT static bool ourUserTaskAdded; + // so we can easily just get the verbose out of this one + ArLog::LogLevel myVerboseLogLevel; + + AREXPORT static ArServerModeIdle *ourIdleMode; + AREXPORT static ArMutex ourIdleModeMutex; + AREXPORT static bool ourIdleModeCreated; +}; + +#endif // ARSERVERMODE_H diff --git a/Legacy/Aria/ArNetworking/include/ArServerModeDrive.h b/Legacy/Aria/ArNetworking/include/ArServerModeDrive.h new file mode 100644 index 0000000..99ee56d --- /dev/null +++ b/Legacy/Aria/ArNetworking/include/ArServerModeDrive.h @@ -0,0 +1,56 @@ +#ifndef ARSERVERMODEDRIVE_H +#define ARSERVERMODEDRIVE_H + +#include "ariaTypedefs.h" +#include "Aria.h" +#include "ArNetworking.h" +#include "ArServerMode.h" + +class ArServerModeDrive : public ArServerMode +{ +public: + AREXPORT ArServerModeDrive(ArServerBase *server, ArRobot *robot, + bool takeControlOnJoystick = false); + AREXPORT virtual ~ArServerModeDrive(); + AREXPORT virtual void activate(void); + AREXPORT virtual void deactivate(void); + /// This adds commands that'll let you disable and enable safe driving + AREXPORT void addControlCommands(ArServerHandlerCommands *handlerCommands); + AREXPORT void driveJoystick(double vel, + double rotVel, + bool isActivating = true); + AREXPORT void serverDriveJoystick(ArServerClient *client, + ArNetPacket *packet); + AREXPORT virtual void userTask(void); + AREXPORT void setThrottleParams(int lowSpeed, int highSpeed); + AREXPORT virtual ArActionGroup *getActionGroup(void) { return &myDriveGroup;} + AREXPORT void setSafeDriving(bool safe); + AREXPORT bool getSafeDriving(void); + /// this action will be activated in unsafe mode + AREXPORT void setExtraUnsafeAction(ArAction *action) + { myExtraUnsafeAction = action; } +protected: + AREXPORT void serverSafeDrivingEnable(void); + AREXPORT void serverSafeDrivingDisable(void); + AREXPORT void joyUserTask(void); + ArAction *myExtraUnsafeAction; + ArJoyHandler *myJoyHandler; + ArActionJoydrive myJoydriveAction; + ArActionInput *myInputAction; + ArActionStop myStopAction; + ArActionGroupInput myDriveGroup; + ArFunctor2C myServerDriveJoystickCB; + ArFunctorC myJoyUserTaskCB; + bool myDriveSafely; + bool myNewDriveSafely; + double myVel; + double myRotVel; + bool myTakeControlOnJoystick; + // for the simple commands + ArServerHandlerCommands *myHandlerCommands; + ArFunctorC myServerSafeDrivingEnableCB; + ArFunctorC myServerSafeDrivingDisableCB; +}; + + +#endif // ARNETMODEDRIVE_H diff --git a/Legacy/Aria/ArNetworking/include/ArServerModeIdle.h b/Legacy/Aria/ArNetworking/include/ArServerModeIdle.h new file mode 100644 index 0000000..725ee08 --- /dev/null +++ b/Legacy/Aria/ArNetworking/include/ArServerModeIdle.h @@ -0,0 +1,43 @@ +#ifndef ARNETMODEIDLE_H +#define ARNETMODEIDLE_H + +#include "Aria.h" +#include "ArServerMode.h" + +/// Mode that the ArServerMode infrastructure will activate if someone +/// tries to switch from one mode to another and there's idle +/// processing to be done... +class ArServerModeIdle : public ArServerMode +{ +public: + /// Constructor + AREXPORT ArServerModeIdle(ArServerBase *server, ArRobot *robot); + /// Destructor + AREXPORT virtual ~ArServerModeIdle(); + AREXPORT virtual void activate(void); + AREXPORT virtual void deactivate(void); + AREXPORT virtual void userTask(void); + /// Gets the mode that this mode interrupted (or NULL if none) + AREXPORT void setModeInterrupted(ArServerMode *modeInterrupted); + /// Gets the mode that this mode interrupted (or NULL if it didn't interrupt anything) + AREXPORT ArServerMode *getModeInterrupted(void); + AREXPORT virtual ArActionGroup *getActionGroup(void) { return &myStopGroup; } + /// Adds to the config + AREXPORT void addToConfig(ArConfig *config, const char *section = "Teleop settings"); + /// Sets whether we're using the range devices that depend on location + AREXPORT void setUseLocationDependentDevices( + bool useLocationDependentDevices, bool internal = false); + /// Gets whether we're using the range devices that depend on location + AREXPORT bool getUseLocationDependentDevices(void); +protected: + ArActionDeceleratingLimiter *myLimiterForward; + ArActionDeceleratingLimiter *myLimiterBackward; + ArActionDeceleratingLimiter *myLimiterLateralLeft; + ArActionDeceleratingLimiter *myLimiterLateralRight; + ArActionGroupStop myStopGroup; + bool myUseLocationDependentDevices; + ArServerMode *myModeInterrupted; + ArFunctor2C myNetIdleCB; +}; + +#endif // ARNETMODEIDLE_H diff --git a/Legacy/Aria/ArNetworking/include/ArServerModeRatioDrive.h b/Legacy/Aria/ArNetworking/include/ArServerModeRatioDrive.h new file mode 100644 index 0000000..c5705d5 --- /dev/null +++ b/Legacy/Aria/ArNetworking/include/ArServerModeRatioDrive.h @@ -0,0 +1,132 @@ +#ifndef ARSERVERMODERATIODRIVE_H +#define ARSERVERMODERATIODRIVE_H + +#include "ariaTypedefs.h" +#include "Aria.h" +#include "ArServerMode.h" + +class ArServerHandlerCommands; + +class ArServerModeRatioDrive : public ArServerMode +{ +public: + /// Constructor + AREXPORT ArServerModeRatioDrive(ArServerBase *server, ArRobot *robot, + bool takeControlOnJoystick = true, + bool useComputerJoystick = true, + bool useRobotJoystick = true, + bool useServerCommands = true, + const char *name = "ratioDrive", + bool robotJoystickOverridesLocks = true); + /// Destructor + AREXPORT virtual ~ArServerModeRatioDrive(); + AREXPORT virtual void activate(void); + AREXPORT virtual void deactivate(void); + /// This adds commands that'll let you disable and enable safe driving + AREXPORT void addControlCommands(ArServerHandlerCommands *handlerCommands); + /// Sets the ratio drive action + AREXPORT void ratioDrive(double transRatio, + double rotRatio, + double throttleRatio, + bool isActivating = false, + double latRatio = 0); + /// Adds to a config in a section + AREXPORT void addToConfig(ArConfig *config, const char *section); + AREXPORT virtual void userTask(void); + AREXPORT virtual ArActionGroup *getActionGroup(void) { return &myRatioDriveGroup;} + ArActionRatioInput *getActionRatioInput(void) { return myRatioAction; } + /// Sets whether we're safe driving or not + AREXPORT void setSafeDriving(bool safe, bool internal = false); + /// Gets whether we're driving safely or not + AREXPORT bool getSafeDriving(void); + /// Sets whether we're using the range devices that depend on location + AREXPORT void setUseLocationDependentDevices( + bool useLocationDependentDevices, bool internal = false); + /// Gets whether we're using the range devices that depend on location + AREXPORT bool getUseLocationDependentDevices(void); + /// Adds a callback mode for when safe driving is activated + void addSafeDrivingCallback(ArFunctor *functor, int position = 50) + { mySafeDrivingCallbacks.addCallback(functor, position); } + /// Removes a callback mode for when safe driving is activated + void remSafeDrivingCallback(ArFunctor *functor) + { mySafeDrivingCallbacks.remCallback(functor); } + /// Adds a callback mode for when unsafe driving is activated + void addUnsafeDrivingCallback(ArFunctor *functor, int position = 50) + { myUnsafeDrivingCallbacks.addCallback(functor, position); } + /// Removes a callback mode for when unsafe driving is activated + void remUnsafeDrivingCallback(ArFunctor *functor) + { myUnsafeDrivingCallbacks.remCallback(functor); } + /// Adds a callback mode for when trying to back up + void addDrivingBackwardsCallback(ArFunctor *functor, int position = 50) + { myDrivingBackwardsCallbacks.addCallback(functor, position); } + /// Removes a callback mode for when trying to back up + void remDrivingBackwardsCallback(ArFunctor *functor) + { myDrivingBackwardsCallbacks.remCallback(functor); } + +protected: + AREXPORT void serverRatioDrive(ArServerClient *client, + ArNetPacket *packet); + AREXPORT void serverSetSafeDrive(ArServerClient *client, + ArNetPacket *packet); + AREXPORT void serverGetSafeDrive(ArServerClient *client, + ArNetPacket *packet); + AREXPORT void serverSafeDrivingEnable(void); + AREXPORT void serverSafeDrivingDisable(void); + AREXPORT void ratioFireCallback(void); + AREXPORT void joyUserTask(void); + ArJoyHandler *myJoyHandler; + ArRobotJoyHandler *myRobotJoyHandler; + + bool myTakeControlOnJoystick; + bool myUseComputerJoystick; + bool myUseRobotJoystick; + bool myUseServerCommands; + bool myPrinting; + bool myRobotJoystickOverridesLock; + double myTransRatio; + double myRotRatio; + double myThrottleRatio; + double myLatRatio; + + double myTimeout; + + bool myGotServerCommand; + bool myLastTimedOut; + + ArActionDeceleratingLimiter *myLimiterForward; + ArActionDeceleratingLimiter *myLimiterBackward; + ArActionDeceleratingLimiter *myLimiterLateralLeft; + ArActionDeceleratingLimiter *myLimiterLateralRight; + ArRatioInputJoydrive *myJoydrive; + ArRatioInputRobotJoydrive *myRobotJoydrive; + ArActionRatioInput *myRatioAction; + ArActionMovementParameters *myMovementParameters; + ArActionGroup myRatioDriveGroup; + bool myDriveSafely; + bool myNewDriveSafely; + bool myUseLocationDependentDevices; + bool myLastRobotSafeDrive; + + ArTime myLastCommand; + + // SEEKUR + bool mySentRecenter; + + ArCallbackList mySafeDrivingCallbacks; + ArCallbackList myUnsafeDrivingCallbacks; + ArCallbackList myDrivingBackwardsCallbacks; + + ArFunctorC myJoyUserTaskCB; + ArFunctor2C myServerSetSafeDriveCB; + ArFunctor2C myServerGetSafeDriveCB; + ArFunctor2C myServerRatioDriveCB; + ArFunctorC myRatioFireCB; + + // for the simple commands + ArServerHandlerCommands *myHandlerCommands; + ArFunctorC myServerSafeDrivingEnableCB; + ArFunctorC myServerSafeDrivingDisableCB; +}; + + +#endif // ARNETMODERATIODRIVE_H diff --git a/Legacy/Aria/ArNetworking/include/ArServerModeStop.h b/Legacy/Aria/ArNetworking/include/ArServerModeStop.h new file mode 100644 index 0000000..96b7a0b --- /dev/null +++ b/Legacy/Aria/ArNetworking/include/ArServerModeStop.h @@ -0,0 +1,37 @@ +#ifndef ARNETMODESTOP_H +#define ARNETMODESTOP_H + +#include "Aria.h" +#include "ArServerMode.h" + +class ArServerModeStop : public ArServerMode +{ +public: + AREXPORT ArServerModeStop(ArServerBase *server, ArRobot *robot, + bool defunct = false); + AREXPORT virtual ~ArServerModeStop(); + AREXPORT virtual void activate(void); + AREXPORT virtual void deactivate(void); + AREXPORT void stop(void); + AREXPORT void netStop(ArServerClient *client, ArNetPacket *packet); + AREXPORT virtual void userTask(void); + AREXPORT virtual void checkDefault(void) { activate(); } + AREXPORT virtual ArActionGroup *getActionGroup(void) { return &myStopGroup; } + /// Adds to the config + AREXPORT void addToConfig(ArConfig *config, const char *section = "Teleop settings"); + /// Sets whether we're using the range devices that depend on location + AREXPORT void setUseLocationDependentDevices( + bool useLocationDependentDevices, bool internal = false); + /// Gets whether we're using the range devices that depend on location + AREXPORT bool getUseLocationDependentDevices(void); +protected: + ArActionDeceleratingLimiter *myLimiterForward; + ArActionDeceleratingLimiter *myLimiterBackward; + ArActionDeceleratingLimiter *myLimiterLateralLeft; + ArActionDeceleratingLimiter *myLimiterLateralRight; + ArActionGroupStop myStopGroup; + bool myUseLocationDependentDevices; + ArFunctor2C myNetStopCB; +}; + +#endif // ARNETMODESTOP_H diff --git a/Legacy/Aria/ArNetworking/include/ArServerModeWander.h b/Legacy/Aria/ArNetworking/include/ArServerModeWander.h new file mode 100644 index 0000000..e506bc3 --- /dev/null +++ b/Legacy/Aria/ArNetworking/include/ArServerModeWander.h @@ -0,0 +1,26 @@ +#ifndef ARNETMODEWANDER_H +#define ARNETMODEWANDER_H + +#include "ariaTypedefs.h" +#include "Aria.h" +#include "ArNetworking.h" +#include "ArServerMode.h" + +class ArServerModeWander : public ArServerMode +{ +public: + AREXPORT ArServerModeWander(ArServerBase *server, ArRobot *robot); + AREXPORT virtual ~ArServerModeWander(); + AREXPORT virtual void activate(void); + AREXPORT virtual void deactivate(void); + AREXPORT void wander(void); + AREXPORT void netWander(ArServerClient *client, ArNetPacket *packet); + AREXPORT virtual void userTask(void); + AREXPORT virtual void checkDefault(void) { activate(); } + AREXPORT virtual ArActionGroup *getActionGroup(void) {return &myWanderGroup;} +protected: + ArActionGroupWander myWanderGroup; + ArFunctor2C myNetWanderCB; +}; + +#endif // ARNETMODEWANDER_H diff --git a/Legacy/Aria/ArNetworking/include/ArServerSimpleCommands.h b/Legacy/Aria/ArNetworking/include/ArServerSimpleCommands.h new file mode 100644 index 0000000..20b5bd7 --- /dev/null +++ b/Legacy/Aria/ArNetworking/include/ArServerSimpleCommands.h @@ -0,0 +1,301 @@ +#ifndef ARSERVERSIMPLECOMMANDS_H +#define ARSERVERSIMPLECOMMANDS_H + +#include "Aria.h" +#include "ArServerBase.h" +#include "ArServerHandlerCommands.h" +#include "ArServerHandlerPopup.h" + +/// Class for sending commands to the microcontroller (uC) +/** + This class will let you send commands to the microcontroller (com, + comInt, and com2Bytes). + **/ +class ArServerSimpleComUC +{ +public: + /// Constructor + AREXPORT ArServerSimpleComUC(ArServerHandlerCommands *handlerCommands, + ArRobot *robot); + /// Destructor + AREXPORT virtual ~ArServerSimpleComUC(); + /// Handles the command + AREXPORT void command(ArArgumentBuilder *arg); + /// Handles the motor commands + AREXPORT void motionCommand(ArArgumentBuilder *arg); +protected: + void processCommand(ArArgumentBuilder *arg, bool motionCommand); + ArRobot *myRobot; + ArServerHandlerCommands *myHandlerCommands; + ArFunctor1C myCommandCB; + ArFunctor1C myMotionCommandCB; +}; + +/// Class for enabling or disabling logging of movement commands and data +/** + This just calls ArRobot::setLogMovementSent and + ArRobot::setLogLovementReceived. It makes these available for easy + enabling or disabling on the client side. +**/ +class ArServerSimpleComMovementLogging +{ +public: + /// Constructor + AREXPORT ArServerSimpleComMovementLogging( + ArServerHandlerCommands *handlerCommands, ArRobot *robot, + ArServerHandlerPopup *popupHandler = NULL); + /// Destructor + AREXPORT virtual ~ArServerSimpleComMovementLogging(); + /// Enable logging of movement commands sent to the robot + AREXPORT void logMovementSentEnable(void); + /// Disable logging of movement commands sent to the robot + AREXPORT void logMovementSentDisable(void); + /// Enable logging of movement received from the robot + AREXPORT void logMovementReceivedEnable(void); + /// Disable logging of movement received from the robot + AREXPORT void logMovementReceivedDisable(void); + /// Enable logging of velocities received from the robot + AREXPORT void logVelocitiesReceivedEnable(void); + /// Disable logging of velocities received from the robot + AREXPORT void logVelocitiesReceivedDisable(void); + /// Enable tracking of packets from the robot + AREXPORT void packetsReceivedTrackingEnable(void); + /// Disable tracking of packets from the robot + AREXPORT void packetsReceivedTrackingDisable(void); + /// Enable tracking of packets from the robot + AREXPORT void packetsSentTrackingEnable(void); + /// Disable tracking of packets from the robot + AREXPORT void packetsSentTrackingDisable(void); + /// Enable logging of velocities received from the robot + AREXPORT void logActionsEnable(void); + /// Disable logging of velocities received from the robot + AREXPORT void logActionsDisable(void); + /// Log the status of the actions on the robot + AREXPORT void logActions(void); + /// Popups up the movement parameters + AREXPORT void popupMovementParams(void); + /// Resets the odometer + AREXPORT void resetOdometer(void); +protected: + ArRobot *myRobot; + ArServerHandlerCommands *myHandlerCommands; + ArServerHandlerPopup *myPopupHandler; + + ArFunctorC myLogMovementSentEnableCB; + ArFunctorC myLogMovementSentDisableCB; + ArFunctorC myLogMovementReceivedEnableCB; + ArFunctorC myLogMovementReceivedDisableCB; + ArFunctorC myLogVelocitiesReceivedEnableCB; + ArFunctorC myLogVelocitiesReceivedDisableCB; + ArFunctorC myPacketsReceivedTrackingEnableCB; + ArFunctorC myPacketsReceivedTrackingDisableCB; + ArFunctorC myPacketsSentTrackingEnableCB; + ArFunctorC myPacketsSentTrackingDisableCB; + ArFunctorC myLogActionsEnableCB; + ArFunctorC myLogActionsDisableCB; + + ArFunctorC myLogActionsCB; + ArFunctorC myPopupMovementParamsCB; + ArFunctorC myResetOdometerCB; +}; + +/// Class for enabling or disabling the gyro +/** + This just calls ArAnalogGyro::activate and + ArAnalogGyro::deactivate. If you want to see the gyro data if you + use the robot's movement received (either + ArRobot::setLogMovementReceived or use + ArServerSimpleComMovementLogging) +**/ +class ArServerSimpleComGyro +{ +public: + /// Constructor + AREXPORT ArServerSimpleComGyro( + ArServerHandlerCommands *handlerCommands, ArRobot *robot, + ArAnalogGyro *gyro); + /// Destructor + AREXPORT virtual ~ArServerSimpleComGyro(); + /// Enables the gyro + AREXPORT void gyroEnable(void); + /// Disables the gyro + AREXPORT void gyroDisable(void); +protected: + ArRobot *myRobot; + ArAnalogGyro *myGyro; + ArServerHandlerCommands *myHandlerCommands; + ArFunctorC myGyroEnableCB; + ArFunctorC myGyroDisableCB; +}; + + +/// Request configuration from robot controller and log the result +class ArServerSimpleComLogRobotConfig +{ +public: + AREXPORT ArServerSimpleComLogRobotConfig( + ArServerHandlerCommands *commands, ArRobot* robot, + ArServerHandlerPopup *popupHandler = NULL); + AREXPORT void logConfig(void); + AREXPORT void logMovementConfig(void); + AREXPORT void logOrigConfig(void); + AREXPORT void popupConfig(void); + AREXPORT void popupOrigConfig(void); + AREXPORT void popupMovementConfig(void); +private: + void configPacketArrived(void); + ArServerHandlerCommands *myHandlerCommands; + ArRobot* myRobot; + ArServerHandlerPopup *myPopupHandler; + + bool myLogConfig; + bool myPopupConfig; + bool myLogConfigMovement; + bool myPopupConfigMovement; + + + ArFunctorC myPacketArrivedCB; + ArRobotConfigPacketReader myPacketReader; + ArFunctorC myLogConfigCB; + ArFunctorC myLogMovementConfigCB; + ArFunctorC myLogOrigConfigCB; + ArFunctorC myPopupConfigCB; + ArFunctorC myPopupOrigConfigCB; + ArFunctorC myPopupMovementConfigCB; +}; + +/// Log current ArRobot actions. +class ArServerSimpleComLogActions +{ +public: + AREXPORT ArServerSimpleComLogActions(ArServerHandlerCommands *commands, ArRobot* robot); + AREXPORT void logActions(); +private: + ArRobot* myRobot; + ArFunctorC myCallback; +}; + +class ArServerSimpleServerCommands +{ +public: + AREXPORT ArServerSimpleServerCommands( + ArServerHandlerCommands *commands, ArServerBase *server, + bool addLogConnections = true); + AREXPORT virtual ~ArServerSimpleServerCommands(); + AREXPORT void logTerseTracking(void); + AREXPORT void logVerboseTracking(void); + AREXPORT void resetTracking(void); + AREXPORT void logConnections(void); +private: + ArServerBase *myServer; + ArFunctorC myTerseTrackingCB; + ArFunctorC myVerboseTrackingCB; + ArFunctorC myResetTrackingCB; + ArFunctorC myLogConnectionsCB; + +}; + +/// Class for sending popups out the server +/** + This class will let you make a popup in MobileEyes, mostly for testing + **/ +class ArServerSimplePopup +{ +public: + /// Constructor + AREXPORT ArServerSimplePopup(ArServerHandlerCommands *commands, + ArServerHandlerPopup *popupHandler); + /// Destructor + AREXPORT virtual ~ArServerSimplePopup(); + /// Handles the command + AREXPORT void simplePopup(ArArgumentBuilder *arg); +protected: + ArServerHandlerCommands *myCommands; + ArServerHandlerPopup *myPopupHandler; + ArFunctor1C mySimplePopupCB; +}; + +/// Class that logs a special debug packet from the robot +class ArServerSimpleLogRobotDebugPackets +{ +public: + /// Constructor + AREXPORT ArServerSimpleLogRobotDebugPackets( + ArServerHandlerCommands *commands, ArRobot *robot, + const char *baseDirectory = ""); + /// Destructor + AREXPORT virtual ~ArServerSimpleLogRobotDebugPackets(); + /// Starts the logging + AREXPORT bool startLogging( + const char *fileName = "robotDebugPacketsLog.txt"); + /// Ends the logging + AREXPORT bool stopLogging(void); + /// Internal function that parses the packet + AREXPORT bool packetHandler(ArRobotPacket *packet); + /// Adds the robot debug info to the info group + AREXPORT void addToInfoGroup(ArStringInfoGroup *infoGroup, + const char *name, int whichVal, + const char *format = "%d"); + /// Gets the number of values there are + AREXPORT int getNumValues(void); + /// Gets a particular value + AREXPORT int getValue(int whichVal); +protected: + ArRobot *myRobot; + ArServerHandlerCommands *myCommands; + // the file we write to, if its NULL we're not logging + FILE *myFile; + std::string myBaseDir; + std::map myVals; + int myNumVals; + ArRetFunctor1C myPacketHandlerCB; + ArRetFunctor1C myStartLoggingCB; + ArRetFunctorC myStopLoggingCB; +}; + + +/// Class for sending commands to the microcontroller (uC) +/** + This class will let you send commands to the microcontroller (com, + comInt, and com2Bytes). + **/ +class ArServerSimpleConnectionTester +{ +public: + /// Constructor + AREXPORT ArServerSimpleConnectionTester( + ArServerHandlerCommands *handlerCommands, ArRobot *robot); + /// Destructor + AREXPORT virtual ~ArServerSimpleConnectionTester(); + /// Handles the command + AREXPORT void connectionTestStart(void); + /// Handles the motor commands + AREXPORT void connectionTestStop(void); +protected: + ArRobot *myRobot; + ArServerHandlerCommands *myHandlerCommands; + + bool packetHandler(ArRobotPacket *packet); + void userTask(void); + void log(void); + + bool myFirst; + int myReceivedPackets; + int myMissedPackets; + int myMissedMotorPackets; + int myPacketsThisCycle; + int myCyclesSincePacket; + ArTime myPacketReceived; + ArTime myLastLog; + + ArFunctorC myConnectionTestStartCB; + ArFunctorC myConnectionTestStopCB; + ArRetFunctor1C myPacketHandlerCB; + ArFunctorC myUserTaskCB; +}; + + +#endif diff --git a/Legacy/Aria/ArNetworking/include/ArServerSimpleOpener.h b/Legacy/Aria/ArNetworking/include/ArServerSimpleOpener.h new file mode 100644 index 0000000..5518680 --- /dev/null +++ b/Legacy/Aria/ArNetworking/include/ArServerSimpleOpener.h @@ -0,0 +1,103 @@ +#ifndef ARSERVERSIMPLEOPENER_H +#define ARSERVERSIMPLEOPENER_H + +#include "Aria.h" + +class ArServerBase; + +/** + @brief Set up and open an ArNetworking server + + Some program command line options affect behavior: + @verbinclude ArServerSimpleOpener_options + + To set the + port the server uses use '-serverPort serverPortNumber' or + '-sp serverPortNumber'. To set the file to look in for user + information use '-userInfo fileName' or "-ui + fileName'. To log out the user information use + '-logUserInfo' or 'lui'. To log out the command groups use + '-logCommandGroups' or '-lcg'. To set the key used for the server + (that the client has to know to connect if using user and password) + use '-serverInfoFile file'. With a file that has in it + 'serverKey serverKey'. You should obviously make sure no one you + don't want to know that server key can read your file that it is + in. + + For more details about all of these options see ArServerBase. + + @sa ArServerBase +**/ +class ArServerSimpleOpener +{ +public: + /// Constructor + AREXPORT ArServerSimpleOpener(ArArgumentParser *parser, + const char *prefix = "", + bool addAriaCallbacks = true); + /// Destructor + AREXPORT ~ArServerSimpleOpener(); + /// Function to open up the server + AREXPORT bool open(ArServerBase *server, const char *baseDirectory = "", + int secondsToTryFor = 240); + /// Function to parse the arguments given in the constructor + AREXPORT bool parseArgs(void); + /// Function to parse the arguments given in an arbitrary parser + AREXPORT bool parseArgs(ArArgumentParser *parser); + /// Log the options the simple connector has + AREXPORT void logOptions(void) const; + /// Logs the things requested for logging, may check things later + AREXPORT bool checkAndLog(void) const; + /// Returns true if the open failed because of a bad user file + bool wasUserFileBad(void) { return myBadUserFile; } + /// Returns true if the open failed because it couldn't open + bool didOpenFail(void) { return myOpenFailed; } + /** Get the server's port number + * @return the server's port number + */ + int getPort() { return myServerPort; } + + /** Set default server port number (normally 7272). This must be called before + * parsing command line arguments. + * @since 2.7.6 + */ + void setDefaultPort(int port) { myServerPort = port; } + + /// Parses the file for holding the server key + AREXPORT bool parseFile(const char *fileName); + /// Sets the tcpOnly flag + void setServerTcpOnly(bool serverTcpOnly) { myTcpOnly = serverTcpOnly; } +protected: + AREXPORT bool parseArgsWithOutPrefix(ArArgumentParser *parser); + AREXPORT bool parseArgsWithPrefix(ArArgumentParser *parser); + AREXPORT void logOptionsWithOutPrefix(void) const; + AREXPORT void logOptionsWithPrefix(void) const; + + bool fileServerKeyCallback(ArArgumentBuilder *arg); + + void reset(void); + const char *myUserFile; + //const char *myServerKey; + std::string myServerKey; + int myServerPort; + const char *myOpenOnIP; + ArServerBase *myServer; + bool myLogUserInfo; + bool myLogCommandGroups; + bool myTcpOnly; + bool myBadUserFile; + bool myOpenFailed; + // our parser + ArArgumentParser *myParser; + bool myOwnParser; + std::string myPrefix; + + // file parser for the server key file + ArFileParser myFileParser; + ArRetFunctorC myParseArgsCB; + ArConstFunctorC myLogOptionsCB; + ArRetFunctor1C myFileServerKeyCB; +}; + +#endif // ARSERVERSIMPLEOPENER_H diff --git a/Legacy/Aria/ArNetworking/include/ArServerUserInfo.h b/Legacy/Aria/ArNetworking/include/ArServerUserInfo.h new file mode 100644 index 0000000..fb9ee59 --- /dev/null +++ b/Legacy/Aria/ArNetworking/include/ArServerUserInfo.h @@ -0,0 +1,71 @@ +#ifndef ARSERVERUSERINFO_H +#define ARSERVERUSERINFO_H + +#include "Aria.h" + +/// This class holds information about users and loads it from a file +/** + For a description of the algorithm used to match passwords and keys + and all look at the documentation for ArServerBase. + + The file format for this class is set up to be easy to make a new + version of and yet read all the old versions. + + For all of the versions everything after ; or # is ignored. The + version information is then the first line of non comments. + + The first version is described as such: The version string is + 'UserInfoVersion1'. Then there are lines that follow for each user + which are 'user userName password groups'. The passwords are + plain text in the file, though they aren't sent that way over the + network (look at ArServerBase docs for details). + To display the groups available use ArServerBase::logCommandGroups(). + + There is an example user info file in ArNetworking/examples/serverDemo.userInfo + +**/ +class ArServerUserInfo +{ +public: + /// Constructor + AREXPORT ArServerUserInfo(const char *baseDirectory = NULL); + /// Destructor + AREXPORT ~ArServerUserInfo(); + /// Loads the file, returns false if it wasn't there + AREXPORT bool readFile(const char *fileName); + /// Sets the base directory + AREXPORT void setBaseDirectory(const char *baseDirectory); + /// Matchs a user and password, false if user or password is wrong + AREXPORT bool matchUserPassword(const char *user, unsigned char password[16], + const char *passwordKey, + const char *serverKey, + bool logFailureVerbosely = false) const; + AREXPORT bool doNotUse(void) const; + /// Gets the groups a user is in (returns empty set if no user) + AREXPORT std::set getUsersGroups( + const char *user) const; + /// Logs the users and groups + AREXPORT void logUsers(void) const; +protected: + bool v1HeaderCallback(ArArgumentBuilder * arg); + bool v1UserCallback(ArArgumentBuilder * arg); + bool v1DoNotUseCallback(ArArgumentBuilder * arg); + void removeHandlers(void); + void logDigest(unsigned char digest[16]) const; + + ArMutex myDataMutex; + std::map myPasswords; + std::map *, + ArStrCaseCmpOp> myGroups; + ArRetFunctor1C myV1HeaderCB; + ArRetFunctor1C myV1UserCB; + ArRetFunctor1C myV1DoNotUseCB; + std::string myBaseDirectory; + ArFileParser myParser; + bool myGotHeader; + bool myDoNotUse; + bool myLogFailureVerbosely; + +}; + +#endif // ARSERVERUSERINFO_H diff --git a/Legacy/Aria/ArNetworking/include/ArTempDirectoryHelper.h b/Legacy/Aria/ArNetworking/include/ArTempDirectoryHelper.h new file mode 100644 index 0000000..354f957 --- /dev/null +++ b/Legacy/Aria/ArNetworking/include/ArTempDirectoryHelper.h @@ -0,0 +1,75 @@ +#ifndef ARTEMPDIRECTORYHELPER_H +#define ARTEMPDIRECTORYHELPER_H + +#include "ariaTypedefs.h" +#include "ArFunctor.h" + +/// Helper class that manages the transition of temporary files to the base directory. +class ArTempDirectoryHelper +{ +public: + + /// Constructor + AREXPORT ArTempDirectoryHelper(const char *baseDirectory = "", + const char *tempDirectory = ""); + + /// Destructor + AREXPORT virtual ~ArTempDirectoryHelper(); + + + /// Returns the name of the directory for temporary files. + AREXPORT const char *getTempDirectory(); + /// Returns the name of the target base directory. + AREXPORT const char *getBaseDirectory(); + + + /// Creates a complete file path name for the specified file in the temporary directory. + AREXPORT std::string makeTempFilePathName(const char *fileName); + + /// Creates a complete file path name for the specified file in the base directory. + AREXPORT std::string makeBaseFilePathName(const char *fileName); + + + /// Moves the specified file from the temporary directory to the base directory. + AREXPORT bool moveFileToBaseDirectory(const char *fileName); + + /// Moves the specified files from the temporary directory to the base directory. + AREXPORT bool moveFilesToBaseDirectory + (const std::list &fileNameList); + + + /// Adds a callback to be called before moving from temp dir to base dir + AREXPORT void addPreMoveCallback(ArFunctor *functor, + ArListPos::Pos position = ArListPos::LAST); + /// Removes a callback to be called before moving from temp dir to base dir + AREXPORT void remPreMoveCallback(ArFunctor *functor); + /// Adds a callback to be called after moving from temp dir to base dir + AREXPORT void addPostMoveCallback(ArFunctor *functor, + ArListPos::Pos position = ArListPos::LAST); + /// Removes a callback to be called after moving from temp dir to base dir + AREXPORT void remPostMoveCallback(ArFunctor *functor); + + +protected: + + /// Creates a complete file path name for the specified file and directory. + AREXPORT std::string makeFilePathName(const char *fileName, + const char *dirName); + +protected: + + /// Path name of the base directory + std::string myBaseDirectory; + /// Path name of the temporary directory + std::string myTempDirectory; + + /// List of callbacks invoked before the files are moved + std::list myPreMoveCallbacks; + /// List of callbacks invoked after the files are moved + std::list myPostMoveCallbacks; + +}; // end class ArTempDirectoryHelper + +#endif // ARTEMPDIRECTORYHELPER_H + + diff --git a/Legacy/Aria/ArNetworking/include/md5.h b/Legacy/Aria/ArNetworking/include/md5.h new file mode 100644 index 0000000..d42b62e --- /dev/null +++ b/Legacy/Aria/ArNetworking/include/md5.h @@ -0,0 +1,104 @@ +/* + This is the software we use for doing the md5 checksums, its from + http://sourceforge.net/project/showfiles.php?group_id=42360 +*/ + +/* + Copyright (C) 1999, 2002 Aladdin Enterprises. All rights reserved. + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + L. Peter Deutsch + ghost@aladdin.com + + */ +/* + Independent implementation of MD5 (RFC 1321). + + This code implements the MD5 Algorithm defined in RFC 1321, whose + text is available at + http://www.ietf.org/rfc/rfc1321.txt + The code is derived from the text of the RFC, including the test suite + (section A.5) but excluding the rest of Appendix A. It does not include + any code or documentation that is identified in the RFC as being + copyrighted. + + The original and principal author of md5.h is L. Peter Deutsch + . Other authors are noted in the change history + that follows (in reverse chronological order): + + 2002-04-13 lpd Removed support for non-ANSI compilers; removed + references to Ghostscript; clarified derivation from RFC 1321; + now handles byte order either statically or dynamically. + 1999-11-04 lpd Edited comments slightly for automatic TOC extraction. + 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5); + added conditionalization for C++ compilation from Martin + Purschke . + 1999-05-03 lpd Original version. + */ + +#ifndef md5_INCLUDED +# define md5_INCLUDED + +/* + * This package supports both compile-time and run-time determination of CPU + * byte order. If ARCH_IS_BIG_ENDIAN is defined as 0, the code will be + * compiled to run only on little-endian CPUs; if ARCH_IS_BIG_ENDIAN is + * defined as non-zero, the code will be compiled to run only on big-endian + * CPUs; if ARCH_IS_BIG_ENDIAN is not defined, the code will be compiled to + * run on either big- or little-endian CPUs, but will run slightly less + * efficiently on either one than if ARCH_IS_BIG_ENDIAN is defined. + */ + +typedef unsigned char md5_byte_t; /* 8-bit byte */ +typedef unsigned int md5_word_t; /* 32-bit word */ + +/* Define the state of the MD5 Algorithm. */ +typedef struct md5_state_s { + md5_word_t count[2]; /* message length in bits, lsw first */ + md5_word_t abcd[4]; /* digest buffer */ + md5_byte_t buf[64]; /* accumulate block */ +} md5_state_t; + +// MPL (ActivMedia) taking out the extern since its only being used in c++ +/* +#ifdef __cplusplus +extern "C" +{ +#endif +*/ + +// RH (ActivMedia/MobileRobots) Added "AREXPORT" symbol to all public functions. On Windows, this must be defined +// to either import or export the symbols to/from DLLs. On other platforms, it should be defined to be nothing. + +/* Initialize the algorithm. */ +AREXPORT void md5_init(md5_state_t *pms); + +/* Append a string to the message. */ +AREXPORT void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes); + +/* Finish the message and return the digest. */ +AREXPORT void md5_finish(md5_state_t *pms, md5_byte_t digest[16]); + +/// MPL (ActivMedia) taking out the extern since its only being used in c++ +/* +#ifdef __cplusplus +} // end extern "C" +#endif +*/ + +#endif /* md5_INCLUDED */ diff --git a/Legacy/Aria/ArNetworking/include/wrapper.i b/Legacy/Aria/ArNetworking/include/wrapper.i new file mode 100644 index 0000000..3863896 --- /dev/null +++ b/Legacy/Aria/ArNetworking/include/wrapper.i @@ -0,0 +1,268 @@ +/* SWIG Wrapper for ArNetworking */ + +#ifdef SWIGPYTHON +%module(docstring="Python wrapper library for ArNetworking", directors="1") ArNetworkingPy +#else +# ifdef SWIGJAVA +%module(docstring="Java wrapper library for ArNetworking", directors="1") ArNetworkingJava +# else +%module(docstring="Wrapper library for ArNetworking", directors="1") ArNetworking +# endif +#endif + +#ifdef SWIGIMPORTED +#warning Imported ArNetworking wrapper +#endif + +%feature("autodoc", "1"); +/* +%feature("directors", "1");*/ /* Enable on all classes. */ + +%{ +#include +#include "Aria.h" +#include "ArNetworking.h" +#include "../include/wrapper_ExtraClasses.h" +%} +%warnfilter(451) ArUtil; + + +/* Import all of Aria's wrapper classes */ +#ifndef SWIG_IMPORTED_ARIA +#warning ArNetworking importing ARIA wrapper configuration... +%import ../include/wrapper.i +#define SWIG_IMPORTED_ARIA 1 +#endif + + +/* In Java, we need to import the Aria package's namespace */ +%typemap(javaimports) SWIGTYPE %{import com.mobilerobots.Aria.*;%} +%pragma(java) jniclassimports=%{import com.mobilerobots.Aria.*; %} +%pragma(java) moduleimports=%{import com.mobilerobots.Aria.*; %} + + +/* In Java, we need to override how SWIG defines some methods in the wrappers, + * to be public not protected (the defaut javabody typemap is defined in + * java.swg) so that other packages such as ArNetworking and ARNL can access them: + */ +%typemap(javabody) SWIGTYPE %{ + private long swigCPtr; + protected boolean swigCMemOwn; + + /* for internal use by swig only */ + public $javaclassname(long cPtr, boolean cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = cPtr; + } + + /* for internal use by swig only */ + public static long getCPtr($javaclassname obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } +%} + +%typemap(javabody_derived) SWIGTYPE %{ + private long swigCPtr; + + /* for internal use by swig only */ + public $javaclassname(long cPtr, boolean cMemoryOwn) { + super($imclassname.SWIG$javaclassnameUpcast(cPtr), cMemoryOwn); + swigCPtr = cPtr; + } + + /* for internal use by swig only */ + public static long getCPtr($javaclassname obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } +%} + + +%typemap(javabody) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [], SWIGTYPE (CLASS::*) %{ + private long swigCPtr; + + /* for internal use by swig only */ + public $javaclassname(long cPtr, boolean bFutureUse) { + swigCPtr = cPtr; + } + + protected $javaclassname() { + swigCPtr = 0; + } + + /* for internal use by swig only */ + public static long getCPtr($javaclassname obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } +%} + + + +/* In Python, use typemaps to convert functions to functors: */ +#ifdef SWIGPYTHON +%{ + #include "../include/wrapper_Functors.h" + + class ArPyFunctor_ServerData : + public ArFunctor2 + { + protected: + PyObject *pyFunction; + public: + ArPyFunctor_ServerData(PyObject* _f) : + pyFunction(_f), + ArFunctor2() + { + Py_INCREF(pyFunction); + } + + ~ArPyFunctor_ServerData() { + Py_DECREF(pyFunction); + } + + virtual void invoke() { + Py_FatalError("ArPyFunctor_ServerData (for ) invoked with no arguments!"); + } + + virtual void invoke(ArServerClient *cli) { + Py_FatalError("ArPyFunctor_ServerData must be invoked with exactly 2 arguments (ArServerClient*, ArNetPacket*), 1 given."); + } + + virtual void invoke(ArServerClient *cli, ArNetPacket *pkt) + { + PyObject *args = PyTuple_New(2); + PyObject *cliObj = SWIG_Python_NewPointerObj(cli, SWIGTYPE_p_ArServerClient, 0); + PyObject *pktObj = SWIG_Python_NewPointerObj(pkt, SWIGTYPE_p_ArNetPacket, 0); + PyTuple_SetItem(args, 0, cliObj); + PyTuple_SetItem(args, 1, pktObj); + PyObject *r = PyObject_CallObject(pyFunction, args); + if(!r) + { + fputs("** ArPyFunctor_ServerData: Error calling Python function: ", stderr); + PyErr_Print(); + } + Py_DECREF(args); + } + + virtual const char* getName() { + return (const char*) PyString_AsString(PyObject_Str(pyFunction)); + } + }; + + + class ArPyFunctor_NetPacket: + public ArFunctor1, + ArPyFunctor + { + public: + ArPyFunctor_NetPacket(PyObject* f) : ArFunctor1(), ArPyFunctor(f) + { + } + + virtual void invoke() + { + Py_FatalError("ArPyFonctor_NetPacket (for ) invoked with no arguments!"); + } + + virtual void invoke(ArNetPacket* pkt) + { + PyObject *args = PyTuple_New(1); + PyObject *pktObj = SWIG_Python_NewPointerObj(pkt, SWIGTYPE_p_ArNetPacket, 0); + PyTuple_SetItem(args, 0, pktObj); + PyObject *r = PyObject_CallObject(pyFunction, args); + if(!r) + { + fputs("** ArPyFunctor_NetPacket: Error calling python function: ", stderr); + PyErr_Print(); + } + Py_DECREF(args); + } + + virtual const char* getName() { + return ArPyFunctor::getName(); + } + }; +%} + + +%typemap(in) ArFunctor2* { + $1 = new ArPyFunctor_ServerData($input); // XXX memory leak +} + +%typecheck(SWIG_TYPECHECK_POINTER) ArFunctor2* { + $1 = PyCallable_Check($input); +} + +%typemap(in) ArFunctor1* { + $1 = new ArPyFunctor_NetPacket($input); // XXX memory leak +} + +%typecheck(SWIG_TYPECHECK_POINTER) ArFunctor1* { + $1 = PyCallable_Check($input); +} + + +#endif //SWIGPYTHON + +/* But in Java, just name the functor templates and enable directors so you can subclass them: */ +#ifdef SWIGJAVA +%feature("director") ArFunctor1; +%feature("director") ArFunctor1; +%feature("director") ArFunctor2; +%template(ArFunctor_ServerClient) ArFunctor1; +%template(ArFunctor_NetPacket) ArFunctor1; +%template(ArFunctor_ServerData) ArFunctor2; +#endif + + + +/* include files */ +/* Don't include md5.h */ + +/* base classes */ +%include "ArNetPacket.h" +%include "ArServerBase.h" +%include "ArServerMode.h" + +/* derived classes */ +%include "ArClientArgUtils.h" +%include "ArClientBase.h" +%include "ArClientCommands.h" +%include "ArClientData.h" +%include "ArClientFileUtils.h" +%include "ArClientHandlerConfig.h" +%include "ArClientSimpleConnector.h" +%include "ArHybridForwarderVideo.h" +%include "ArNetPacketReceiverTcp.h" +%include "ArNetPacketReceiverUdp.h" +%include "ArNetPacketSenderTcp.h" +%include "ArServerClient.h" +%include "ArServerClientIdentifier.h" +%include "ArServerClientData.h" +%include "ArServerCommands.h" +%include "ArServerData.h" +#ifndef WIN32 +%include "ArServerFileUtils.h" +#endif +%include "ArServerHandlerCamera.h" +%include "ArServerHandlerCameraCollection.h" +%include "ArServerHandlerCommMonitor.h" +%include "ArServerHandlerCommands.h" +%include "ArServerHandlerConfig.h" +%include "ArServerHandlerMap.h" +%include "ArServerHandlerMapping.h" +%include "ArServerInfoDrawings.h" +%include "ArServerInfoRobot.h" +%include "ArServerInfoSensor.h" +%include "ArServerInfoStrings.h" +%include "ArServerModeDrive.h" +%include "ArServerModeIdle.h" +%include "ArServerModeRatioDrive.h" +%include "ArServerModeStop.h" +%include "ArServerModeWander.h" +%include "ArServerSimpleCommands.h" +%include "ArServerSimpleOpener.h" +%include "ArServerUserInfo.h" + +#include "../include/wrapper_ExtraClasses.h" + +/* The End. */ diff --git a/Legacy/Aria/ArNetworking/javaExamples/Makefile b/Legacy/Aria/ArNetworking/javaExamples/Makefile new file mode 100644 index 0000000..3e9c0ee --- /dev/null +++ b/Legacy/Aria/ArNetworking/javaExamples/Makefile @@ -0,0 +1,48 @@ + +ifdef JAVA_BIN +JAVAC=$(JAVA_BIN)/javac +JAVA=$(JAVA_BIN)/java +else +JAVAC=javac +JAVA=java +endif + +#### Different options for Windows or Linux: +host:=$(shell uname | cut -d _ -f 1) +ifeq ($(host),MINGW32) # host is MINGW32 on Windows: +CLASSPATH_SEP=; +RUNTIME_PATH_VAR=PATH +RUNTIME_LIB_DIR=../../bin +LIB_EXT=dll +LIB_PREFIX= +else +CLASSPATH_SEP=: +RUNTIME_PATH_VAR=LD_LIBRARY_PATH +RUNTIME_LIB_DIR=../../lib +LIB_EXT=so +LIB_PREFIX=lib +endif + + + +all: $(patsubst %.java,%.class,$(wildcard *.java)) + +%.class: %.java ../../java/Aria.jar ../../java/ArNetworking.jar $(RUNTIME_LIB_DIR)/$(LIB_PREFIX)Aria.$(LIB_EXT) $(RUNTIME_LIB_DIR)/$(LIB_PREFIX)ArNetworking.$(LIB_EXT) + @echo $^ + "$(JAVAC)" -classpath "../../java/Aria.jar$(CLASSPATH_SEP)../../java/ArNetworking.jar" $< + +run%: %.class + $(RUNTIME_PATH_VAR)=$$$(RUNTIME_PATH_VAR):$(RUNTIME_LIB_DIR) "$(JAVA)" -cp ../../java/Aria.jar:../../java/ArNetworking.jar:. $* $(ARGS) + +gdb%: %.class + $(RUNTIME_PATH_VAR)=$$$(RUNTIME_PATH_VAR):$(RUNTIME_LIB_DIR) gdb --args "$(JAVA)" -cp ../../java/Aria.jar:../../java/ArNetworking.jar:. $* $(ARGS) + +info: + @echo host=$(host) + @echo "JAVA_BIN=$(JAVA_BIN)" + @echo "JAVAC=$(JAVAC)" + @echo "JAVA=$(JAVA)" + @echo "CLASSPATH_SEP=$(CLASSPATH_SEP)" + @echo "RUNTIME_PATH_VAR=$(RUNTIME_PATH_VAR)" + @echo "RUNTIME_LIB_DIR=$(RUNTIME_LIB_DIR)" + @echo "LIB_EXT=$(LIB_EXT)" diff --git a/Legacy/Aria/ArNetworking/javaExamples/README.txt b/Legacy/Aria/ArNetworking/javaExamples/README.txt new file mode 100644 index 0000000..82c0b98 --- /dev/null +++ b/Legacy/Aria/ArNetworking/javaExamples/README.txt @@ -0,0 +1,71 @@ + + +USING THE JAVA WRAPPER FOR ARNETWORKING + +"Wrapper" libraries for Java have been provided for both Aria and ArNetworking +in Aria's "java" directory ("../java"). This wrapper layer provides a Java API which simply +makes calls into the regular ArNetworking C++ implementation (using JNI). + +To use the ArNetworking Java wrapper you need to download a Java SDK. Sun J2SE JDK +1.6 (Java SE6) was used to build the wrapper. You can download it from: + + http://java.sun.com/javase/downloads + +Find the Java SE Development Kit 6 and click "Download". (Only the JDK +is needed, ARIA does not need Java EE or any other extra Java technologies.) + +The JDK also includes the runtime environment (JRE) that allows you to run +Java programs. If you only need the JRE, it can also +be obtained from . + +Install it on your system, then you should put the bin +directory of the SDK into your PATH environment variable. + +For information about Java on Debian GNU/Linux systems, install the +"java-common" package, and see the Debian Java FAQ in + /usr/share/doc/java-common/debian-java-faq/index.html +Chapter 11 describes how to install the Java 2 SDK from Blackdown using +Apt. + + + +In Windows you must then put the Aria\bin directory into your PATH enviornment +variable so that Java can find the dll needed to run the wrapper (use the System +control panel, or set in in the command shell prior to running java). On Linux, +Aria/lib should be in your LD_LIBRARY_PATH or in /etc/ld.so.conf. + +For an example you should start the simulator, then go into +the javaExamples directory and compile the simple Java +example, and then run it. + +On Windows: + javac -classpath ../../java/Aria.jar;../../java/ArNetworking.jar simple.java + java -cp ../../java/Aria.jar;../../java/ArNetworking.jar;. simple + +On Linux: + javac -classpath ../../java/Aria.jar:../../java/ArNetworking.jar simple.java + java -cp ../../java/Aria.jar:../../java/ArNetworking.jar:. simple + +The difference is the separator in the class path (; vs :). + +The Java wrapper is not as well tested as ArNetworking itself. If you encounter +problems using it, please notify the aria-users mailing list. + + +REBUILDING THE JAVA WRAPPER + +If you want to rebuild the Java wrapper you need to install SWIG: +See You should get at +least version 1.3.17. You then need to set the environment variable +JAVA_INCLUDE to the include directory in your Java SDK, and +JAVA_BIN to the bin directory in your Java SDK. (If you installed +the j2sdk1.4 from Blackdown on Debian, JAVA_INCLUDE should be +/usr/lib/j2se/1.4/include). + +In Linux, set your path so that swig is in the path then run +'make java' in the Aria directory, then again in the ArNetworking directory. + +In Windows with Visual Studio .NET, open java/ArNetworkingJava.vcproj, select +Tools menu -> Options -> Projects -> VC++ Directories and add your SWIG +directory. Then you should just be able to build the library. + diff --git a/Legacy/Aria/ArNetworking/javaExamples/customClientExample.java b/Legacy/Aria/ArNetworking/javaExamples/customClientExample.java new file mode 100644 index 0000000..e0e3111 --- /dev/null +++ b/Legacy/Aria/ArNetworking/javaExamples/customClientExample.java @@ -0,0 +1,76 @@ + +import com.mobilerobots.Aria.*; +import com.mobilerobots.ArNetworking.*; + +class ResponseCallback extends ArFunctor_NetPacket +{ + public void invoke(ArNetPacket packet) + { + System.out.println("customClientExample: ResponseCallback: Got a packet from the server with type " + packet.getCommand()); + } +} + +public class customClientExample { + + + /* This loads all the ArNetworking classes (they will be in the global + * namespace) when this class is loaded: */ + static { + try { + System.loadLibrary("AriaJava"); + System.loadLibrary("ArNetworkingJava"); + } catch (UnsatisfiedLinkError e) { + System.err.println("Native code libraries (AriaJava and ArNetworkingJava .so or .DLL) failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e); + System.exit(1); + } + } + + public static void main(String argv[]) + { + Aria.init(); + + ArClientBase client = new ArClientBase(); + ResponseCallback testCB = new ResponseCallback(); + + ArTime startTime = new ArTime(); + startTime.setToNow(); + System.out.println("customClientExample: trying to connect to a server running on the local host at port 7273..."); + if (!client.blockingConnect("localhost", 7273)) + { + System.err.println("Error: Could not connect to server on localhost:7273, exiting."); + System.exit(1); + } + + System.out.println("customClientExample: Connected after " + startTime.mSecSince() + " msec."); + + client.runAsync(); + + System.out.println("\ncustomClientExample: Adding data handler callbacks..."); + client.addHandler("test", testCB); + client.addHandler("test2", testCB); + client.addHandler("test3", testCB); + client.logDataList(); + + System.out.println("\ncustomClientExample: Requesting \"test\" once..."); + client.requestOnce("test"); + + System.out.println("\ncustomClientExample: Requesting \"test2\" with a frequency of 10ms..."); + client.request("test2", 100); + + System.out.println("\ncustomClientExample: Requesting \"test3\" with a frequency of -1 (updates may happen at any time the server sends them) and waiting 5 sec..."); + client.request("test3", -1); + ArUtil.sleep(5000); + + System.out.println("\ncustomClientExample: Changing request frequency of \"test2\" to 300ms and waiting 5 sec"); + client.request("test2", 300); + ArUtil.sleep(5000); + + System.out.println("\ncustomClientExample: Cancelling \"test2\" request."); + client.requestStop("test2"); + + System.out.println("\ncustomClientExample: waiting 10 seconds, then disconnecting..."); + ArUtil.sleep(10000); + client.disconnect(); + ArUtil.sleep(50); + } +} diff --git a/Legacy/Aria/ArNetworking/javaExamples/customServerExample.java b/Legacy/Aria/ArNetworking/javaExamples/customServerExample.java new file mode 100644 index 0000000..0ee3960 --- /dev/null +++ b/Legacy/Aria/ArNetworking/javaExamples/customServerExample.java @@ -0,0 +1,57 @@ + +import com.mobilerobots.Aria.*; +import com.mobilerobots.ArNetworking.*; + +class RequestCallback extends ArFunctor_ServerData +{ + public void invoke(ArServerClient client, ArNetPacket packet) + { + ArNetPacket sending = new ArNetPacket(); + System.out.println("customServerExample: RequestCallback: responding to a request packet with ID " + packet.getCommand()); + client.sendPacketTcp(sending); // just send back an empty packet. + } +} + +public class customServerExample { + + + /* This loads all the ArNetworking classes (they will be in the global + * namespace) when this class is loaded: */ + static { + try { + System.loadLibrary("AriaJava"); + System.loadLibrary("ArNetworkingJava"); + } catch (UnsatisfiedLinkError e) { + System.err.println("Native code libraries (AriaJava and ArNetworkingJava .so or .DLL) failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e); + System.exit(1); + } + } + + + public static void main(String[] argv) + { + Aria.init(); + ArServerBase server = new ArServerBase(); + ArNetPacket packet = new ArNetPacket(); // empty packet to test broadcasting + + RequestCallback testCB = new RequestCallback(); + + server.addData("test", "some wierd test", testCB, "none", "none"); + server.addData("test2", "another wierd test", testCB, "none", "none"); + server.addData("test3", "yet another wierd test", testCB, "none", "none"); + if (!server.open(7273)) + { + System.err.println("customServerExample: Could not open server port 7273"); + System.exit(1); + } + server.runAsync(); + System.out.println("customServerExample: ready for customClientExamples to connect on port 7273; will broadcast \"test3\" packet every 4 seconds as well."); + while (server.getRunningWithLock()) + { + ArUtil.sleep(4000); + server.broadcastPacketTcp(packet, "test3"); + } + Aria.shutdown(); + } +} + diff --git a/Legacy/Aria/ArNetworking/javaExamples/simple.java b/Legacy/Aria/ArNetworking/javaExamples/simple.java new file mode 100644 index 0000000..862c7e8 --- /dev/null +++ b/Legacy/Aria/ArNetworking/javaExamples/simple.java @@ -0,0 +1,88 @@ + +import com.mobilerobots.Aria.*; +import com.mobilerobots.ArNetworking.*; + +public class simple { + + /* This loads all the ArNetworking classes (they will be in the global + * namespace) when this class is loaded: */ + static { + try { + System.loadLibrary("AriaJava"); + System.loadLibrary("ArNetworkingJava"); + } catch (UnsatisfiedLinkError e) { + System.err.println("Native code libraries (AriaJava and ArNetworkingJava .so or .DLL) failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e); + System.exit(1); + } + } + + /* Main program: */ + public static void main(String argv[]) { + System.out.println("Starting Java ArNetworking Test"); + + /* Global Aria class inititalizaton */ + Aria.init(Aria.SigHandleMethod.SIGHANDLE_THREAD, true); + + /* Robot and device objects */ + ArRobot robot = new ArRobot("robot1", true, true, true); + ArSonarDevice sonar = new ArSonarDevice(); + robot.addRangeDevice(sonar); + + /* Make connector and parse arguments from argv */ + ArSimpleConnector conn = new ArSimpleConnector(argv); + if(!Aria.parseArgs()) + { + Aria.logOptions(); + Aria.shutdown(); + System.exit(1); + } + + /* Connect to the robot */ + System.out.println("Connecting to robot..."); + if (!conn.connectRobot(robot)) + { + System.err.println("Could not connect to robot, exiting.\n"); + System.exit(1); + } + + /* Open the sever */ + ArServerBase server = new ArServerBase(); + if(!server.open(7272)) + { + System.err.println("Could not open server on port 7272, exiting."); + System.exit(1); + } + System.out.println("Opened server on port 7272."); + + /* Informational services: */ + ArServerInfoRobot servInfoRobot = new ArServerInfoRobot(server, robot); + ArServerInfoSensor servInfoSensor = new ArServerInfoSensor(server, robot); + ArServerInfoDrawings servInfoDraw = new ArServerInfoDrawings(server); + servInfoDraw.addRobotsRangeDevices(robot); + + /* Control mode services: */ + ArServerModeStop servModeStop = new ArServerModeStop(server, robot); + ArServerModeRatioDrive servModeDrive = new ArServerModeRatioDrive(server, robot); + ArServerModeWander servModeWander = new ArServerModeWander(server, robot); + servModeStop.addAsDefaultMode(); + servModeStop.activate(); + + /* Simple text command service ("custom commands" in MobileEyes): */ + ArServerHandlerCommands commands = new ArServerHandlerCommands(server); + + // Relay microcontroller commands directly: + ArServerSimpleComUC cmdUC = new ArServerSimpleComUC(commands, robot); + + // Log information: + ArServerSimpleComMovementLogging cmdLog = new ArServerSimpleComMovementLogging(commands, robot); + ArServerSimpleComLogRobotConfig cmdConfigLog = new ArServerSimpleComLogRobotConfig(commands, robot); + + + /* Run robot and server threads in the backrgound: */ + System.out.println("Running..."); + robot.enableMotors(); + robot.runAsync(true); + server.runAsync(); + robot.waitForRunExit(); + } +} diff --git a/Legacy/Aria/ArNetworking/pythonExamples/README.txt b/Legacy/Aria/ArNetworking/pythonExamples/README.txt new file mode 100644 index 0000000..85ae1c4 --- /dev/null +++ b/Legacy/Aria/ArNetworking/pythonExamples/README.txt @@ -0,0 +1,22 @@ + +USING THE PYTHON WRAPPER FOR ARNETWORKING + +A "wrapper" module for Python has been provided in ARIA's "python" directory. +This wrapper layer provides a Python API which simply makes calls into the +regular ArNetworking C++ implementation. In general, the Python API mirrors +the C++ API, with some exceptions which are noted in the Reference Manual +for the C++ library. + +The ArNetworking wrapper should be used in conjunction with the ARIA wrapper. +See the README.txt for the ARIA pythonExamples for details. + +To use the wrapper modules, you must add ARIA's python directory to +an environment variable called PYTHONPATH. On Windows, the Aria 'bin' +directory must also be in your PATH variable. + +Note that the Python wrapper API is not as well tested as Aria itself. If +you encounter problems, please notify the aria-users mailing list. Furthermore, +some methods have been omitted or renamed, and you have to do a few things +differently. + + diff --git a/Legacy/Aria/ArNetworking/pythonExamples/customClientExample.py b/Legacy/Aria/ArNetworking/pythonExamples/customClientExample.py new file mode 100644 index 0000000..8c79973 --- /dev/null +++ b/Legacy/Aria/ArNetworking/pythonExamples/customClientExample.py @@ -0,0 +1,66 @@ +from AriaPy import * +from ArNetworkingPy import * +import sys + +def testCB(packet): + print "client: received reply packet with command %d\n" % (packet.getCommand()) + +Aria_init() + +client = ArClientBase() + +startTime = ArTime() +startTime.setToNow() +if not client.blockingConnect("localhost", 7273): + print "Could not connect to server at localhost port 7273, exiting" + Aria_exit(1); +print "client: Took %ld msec to connect\n" % (startTime.mSecSince()) + +client.runAsync() + +client.lock() + +print "Client detected the following data requests on the server:" +client.logDataList() + +print "Adding callback for data requests \"test\", \"test2\", \"test3\"..." +client.addHandler("test", testCB) +client.addHandler("test2", testCB) +client.addHandler("test3", testCB) + + +print "Requesting \"test\" once..." +client.requestOnce("test") + +print "Requesting \"test2\" every 100ms..." +client.request("test2", 100) + +print "Requesting \"test3\" to be sent at server's discrecion..." +client.request("test3", -1) +client.unlock() + +print "Waiting 2 sec..." +ArUtil_sleep(2000) + +print "Changing request frequency of \"test2\" to 300ms..." +client.lock() +client.request("test2", 300) +client.unlock() + +print "Watiing 2 sec..." +ArUtil_sleep(1000) + +print "Stopping request for \"test2\"..." +client.lock() +client.requestStop("test2") +client.unlock() + +print "Waiting 2 sec..." +ArUtil_sleep(2000) + +print "Disconnecting and exiting." +client.lock() +client.disconnect() +client.unlock() +ArUtil_sleep(50) + diff --git a/Legacy/Aria/ArNetworking/pythonExamples/customServerExample.py b/Legacy/Aria/ArNetworking/pythonExamples/customServerExample.py new file mode 100644 index 0000000..f7914b3 --- /dev/null +++ b/Legacy/Aria/ArNetworking/pythonExamples/customServerExample.py @@ -0,0 +1,27 @@ +from AriaPy import * +from ArNetworkingPy import * +import sys + +def requestCallback(client, packet): + replyPacket = ArNetPacket() + replyPacket.strToBuf("Reply"); + print "requestCallback received a packet with command #%d. Sending a reply...\n" % (packet.getCommand()) + client.sendPacketTcp(replyPacket) + +Aria_init() +server = ArServerBase() +packet = ArNetPacket() + +server.addData("test", "some wierd test", requestCallback, "none", "none") +server.addData("test2", "another wierd test", requestCallback, "none", "none") +server.addData("test3", "yet another wierd test", requestCallback, "none", "none") +if not server.open(7273): + print "Error: Could not open server port 7273" + Aria_exit(1) +print "Opened server on port 7273. Connect with customClientExample." +server.runAsync() +while (server.getRunningWithLock()): + ArUtil_sleep(1000) + server.broadcastPacketTcp(packet, "test3") +Aria_exit(0) + diff --git a/Legacy/Aria/ArNetworking/pythonExamples/drawingsExample.py b/Legacy/Aria/ArNetworking/pythonExamples/drawingsExample.py new file mode 100644 index 0000000..eec89e6 --- /dev/null +++ b/Legacy/Aria/ArNetworking/pythonExamples/drawingsExample.py @@ -0,0 +1,204 @@ +from AriaPy import * +from ArNetworkingPy import * +import sys +from math import sin + + +# This is an example server that shows how to draw arbitrary figures in a +# client (e.g. MobileEyes). + + +# These are callbacks that respond to client requests for the drawings' +# geometry data. + + +def exampleHomeDrawingNetCallback(client, requestPkt): + print "exampleHomeDrawingNetCallback" + + reply = ArNetPacket() + + # 7 Vertices + reply.byte4ToBuf(7) + + # Centered on 0,0. + # X: Y: + reply.byte4ToBuf(-500); reply.byte4ToBuf(500); # Vertex 1 + reply.byte4ToBuf(-500); reply.byte4ToBuf(-500); # Vertex 2 + reply.byte4ToBuf(500); reply.byte4ToBuf(-500); # Vertex 3 + reply.byte4ToBuf(500); reply.byte4ToBuf(500); # Vertex 4 + reply.byte4ToBuf(0); reply.byte4ToBuf(1000); # Vertex 5 + reply.byte4ToBuf(-500); reply.byte4ToBuf(500); # Vertex 6 + reply.byte4ToBuf(500); reply.byte4ToBuf(500); # Vertex 7 + + client.sendPacketUdp(reply) + print "exampleHomeDrawingNetCallback Done." + +def exampleDotsDrawingNetCallback(client, requestPkt): + reply = ArNetPacket() + + tik = ArUtil_getTime() % 200 + t = tik / 5.0 + + # Three dots + reply.byte4ToBuf(3) + + # Dot 1: + reply.byte4ToBuf(3000); # X coordinate (mm) + reply.byte4ToBuf((int) (sin(t) * 1000));# Y + + # Dot 2: + reply.byte4ToBuf(3500); # X + reply.byte4ToBuf((int) (sin(t+500) * 1000));# Y + + # Dot 3: + reply.byte4ToBuf(4000); # X + reply.byte4ToBuf((int) (sin(t+1000) * 1000));# Y + + client.sendPacketUdp(reply) + +def exampleXDrawingNetCallback(client, requestPkt): + reply = ArNetPacket() + + # X marks the spot. 2 line segments, so 4 vertices: + reply.byte4ToBuf(4) + + # Segment 1: + reply.byte4ToBuf(-4250); # X1 + reply.byte4ToBuf(250); # Y1 + reply.byte4ToBuf(-3750); # X2 + reply.byte4ToBuf(-250); # Y2 + + # Segment 2: + reply.byte4ToBuf(-4250); # X1 + reply.byte4ToBuf(-250); # Y1 + reply.byte4ToBuf(-3750); # X2 + reply.byte4ToBuf(250); # Y2 + + client.sendPacketUdp(reply) + +def exampleArrowsDrawingNetCallback(client, requestPkt): + # 1 arrow that points at the robot + reply = ArNetPacket() + reply.byte4ToBuf(1) # 1 arrow + reply.byte4ToBuf(0); # Pos. X + reply.byte4ToBuf(700); # Pos. Y + client.sendPacketUdp(reply) + + + + +# Main program: + +Aria_init() +robot = ArRobot() +server = ArServerBase() + +parser = ArArgumentParser(sys.argv) +simpleConnector = ArSimpleConnector(parser) +simpleOpener = ArServerSimpleOpener(parser) + +parser.loadDefaultArguments() + +if not Aria_parseArgs() or not parser.checkHelpAndWarnUnparsed(): + Aria_logOptions() + Aria_exit(1) + + +if not simpleOpener.open(server): + if simpleOpener.wasUserFileBad(): + print "Error: Bad user/password/permissions file." + else: + print "Error: Could not open server port. Use -help to see options." + Aria_exit(1) + + +# Devices +sonarDev = ArSonarDevice() +robot.addRangeDevice(sonarDev) + +irs = ArIRs() +robot.addRangeDevice(irs) + +bumpers = ArBumpers() +robot.addRangeDevice(bumpers) + +sick = ArSick() +robot.addRangeDevice(sick); + + +# attach services to the server +serverInfoRobot = ArServerInfoRobot(server, robot) +serverInfoSensor = ArServerInfoSensor(server, robot) + +# This is the service that provides drawing data to the client. +drawings = ArServerInfoDrawings(server) + +# Convenience function that sets up drawings for all the robot's current +# range devices (using default shape and color info) +drawings.addRobotsRangeDevices(robot) + +# Add our custom drawings + +linedd = ArDrawingData("polyLine", ArColor(255, 0, 0), 2, 49) # shape name, color, size, layer +drawings.addDrawing( linedd, "exampleDrawing_Home", exampleHomeDrawingNetCallback) + +dotsdd = ArDrawingData("polyDots", ArColor(0, 255, 0), 250, 48) +drawings.addDrawing(dotsdd, "exampleDrawing_Dots", exampleDotsDrawingNetCallback) + +segdd = ArDrawingData("polySegments", ArColor(0, 0, 0), 4, 52) +drawings.addDrawing( segdd, "exampleDrawing_XMarksTheSpot", exampleXDrawingNetCallback) + +ardd = ArDrawingData("polyArrows", ArColor(255, 0, 255), 500, 100) +drawings.addDrawing( ardd, "exampleDrawing_Arrows", exampleArrowsDrawingNetCallback) + +# modes for moving the robot +modeStop = ArServerModeStop(server, robot) +modeDrive = ArServerModeDrive(server, robot) +modeRatioDrive = ArServerModeRatioDrive(server, robot) +modeWander = ArServerModeWander(server, robot) +modeStop.addAsDefaultMode() +modeStop.activate() + +# set up some simple commands ("custom commands") +commands = ArServerHandlerCommands(server) +uCCommands = ArServerSimpleComUC(commands, robot) +loggingCommands = ArServerSimpleComMovementLogging(commands, robot) +configCommands = ArServerSimpleComLogRobotConfig(commands, robot) + +# add the commands to enable and disable safe driving to the simple commands +modeDrive.addControlCommands(commands) + + + +# Connect to the robot. +if not simpleConnector.connectRobot(robot): + print "Error: Could not connect to robot... exiting" + Aria_exit(1) + +# set up the laser before handing it to the laser mode +simpleConnector.setupLaser(sick) + +robot.enableMotors() + +# start the robot cycle running in a background thread +robot.runAsync(True) + +# start the laser processing cycle in a background thread +sick.runAsync() + +# connect the laser if it was requested +if not simpleConnector.connectLaser(sick): + print "Error: Could not connect to laser... exiting" + Aria_exit(2) + +# log whatever we wanted to before the runAsync +simpleOpener.checkAndLog() + +# run the server thread in the background +server.runAsync() + +print "Server is now running on port %d..." % (simpleOpener.getPort()) + +robot.waitForRunExit() +Aria_exit(0) + diff --git a/Legacy/Aria/ArNetworking/pythonExamples/simple.py b/Legacy/Aria/ArNetworking/pythonExamples/simple.py new file mode 100644 index 0000000..876ff63 --- /dev/null +++ b/Legacy/Aria/ArNetworking/pythonExamples/simple.py @@ -0,0 +1,77 @@ +from AriaPy import * +from ArNetworkingPy import * +import sys + +# This example demonstrates how to use ArNetworking in Python. + +# Global library initialization, just like the C++ API: +Aria_init() + +# Create a robot object: +robot = ArRobot() + +# make a gyro +gyro = ArAnalogGyro(robot) + +#sonar, must be added to the robot +sonarDev = ArSonarDevice() +#add the sonar to the robot +robot.addRangeDevice(sonarDev) + +# make the core server object: +server = ArServerBase() + +# Create a "simple connector" object and connect to either the simulator +# or the robot. Unlike the C++ API which takes int and char* pointers, +# the Python constructor just takes argv as a list. +print "Connecting..." + +con = ArSimpleConnector(sys.argv) +if (not con.connectRobot(robot)): + print "Could not connect to robot, exiting" + Aria_exit(1) + + +# Open the server on port 7272: +if (not server.open(7272)): + print "Could not open server, exiting" + Aria_exit(1) + +# Create various services and attach them to the core server +serverInfoRobot = ArServerInfoRobot(server, robot) +serverInfoSensor = ArServerInfoSensor(server, robot) +drawings = ArServerInfoDrawings(server) +drawings.addRobotsRangeDevices(robot) + +# ways of moving the robot +modeStop = ArServerModeStop(server, robot) +modeRatioDrive = ArServerModeRatioDrive(server, robot) +modeWander = ArServerModeWander(server, robot) +modeStop.addAsDefaultMode() +modeStop.activate() + +# set up the simple commands ("custom commands" in MobileEyes) +commands = ArServerHandlerCommands(server) +# add the simple commands for the microcontroller +uCCommands = ArServerSimpleComUC(commands, robot) +# add the simple commands for logging +loggingCommands = ArServerSimpleComMovementLogging(commands, robot) +# add the simple commands for the gyro +gyroCommands = ArServerSimpleComGyro(commands, robot, gyro) +# Add the simple command for logging the robot config and orig robot config +configCommands = ArServerSimpleComLogRobotConfig(commands, robot) + + + + +# Run the robot and server threads in the background: +print "Running..." +robot.runAsync(1) + +server.runAsync() + +robot.enableMotors() + +robot.waitForRunExit() + +Aria_exit(0) diff --git a/Legacy/Aria/ArNetworking/src/ArCentralForwarder.cpp b/Legacy/Aria/ArNetworking/src/ArCentralForwarder.cpp new file mode 100644 index 0000000..dbb7e29 --- /dev/null +++ b/Legacy/Aria/ArNetworking/src/ArCentralForwarder.cpp @@ -0,0 +1,923 @@ +#include "Aria.h" +#include "ArExport.h" +#include "ArCentralForwarder.h" + + +AREXPORT ArCentralForwarder::ArCentralForwarder( + ArServerBase *mainServer, ArSocket *socket, + const char *robotName, int port, + std::map *usedPorts, + ArFunctor2 *forwarderServerClientRemovedCB, + const char *enforceProtocolVersion, + ArServerCommands::Type enforceType) : + myReceiveDataFunctor(this, &ArCentralForwarder::receiveData), + myInternalRequestChangedFunctor(this, + &ArCentralForwarder::internalRequestChanged), + myInternalRequestOnceFunctor(this, + &ArCentralForwarder::internalRequestOnce, + NULL, NULL, true), + myRobotServerClientRemovedCB( + this, &ArCentralForwarder::robotServerClientRemoved), + myNetCentralHeartbeatCB(this, &ArCentralForwarder::netCentralHeartbeat), + myClientServerClientRemovedCB( + this, &ArCentralForwarder::clientServerClientRemoved) +{ + myMainServer = mainServer; + mySocket = socket; + myRobotName = robotName; + myStartingPort = port; + myUsedPorts = usedPorts; + myForwarderServerClientRemovedCB = forwarderServerClientRemovedCB; + if (enforceProtocolVersion != NULL) + myEnforceProtocolVersion = enforceProtocolVersion; + else + myEnforceProtocolVersion = ""; + myEnforceType = enforceType; + + myPrefix = "ArCentralForwarder_"; + myPrefix += myRobotName; + myPrefix += ": "; + myServer = NULL; + myClient = NULL; + myPort = 0; + myState = STATE_STARTING; + myBeingReplaced = false; + myRobotHasCentralServerHeartbeat = false; +} + + +AREXPORT ArCentralForwarder::~ArCentralForwarder() +{ + if (myServer != NULL) + { + myServer->close(); + delete myServer; + } + + if (myClient != NULL) + { + if (myClient->isConnected()) + myClient->disconnect(); + delete myClient; + } + + // MPL adding this since it looks like it leaks this + if (mySocket != NULL) + { + delete mySocket; + } + + if (myRequestOnces.begin() != myRequestOnces.end()) + ArUtil::deleteSetPairs(myRequestOnces.begin(), myRequestOnces.end()); + myRequestOnces.clear(); + if (myLastRequest.begin() != myLastRequest.end()) + ArUtil::deleteSetPairs(myLastRequest.begin(), myLastRequest.end()); + myLastRequest.clear(); + if (myLastBroadcast.begin() != myLastBroadcast.end()) + ArUtil::deleteSetPairs(myLastBroadcast.begin(), myLastBroadcast.end()); + myLastBroadcast.clear(); +} + +AREXPORT bool ArCentralForwarder::callOnce( + double heartbeatTimeout, double udpHeartbeatTimeout, + double robotBackupTimeout, double clientBackupTimeout) +{ + if (myBeingReplaced) + { + ArLog::log(ArLog::Normal, "ArCentralForwarder::%s: being replaced by a duplicate, disconnecting", + myRobotName.c_str()); + return false; + } + + if (myState == STATE_CONNECTED) + { + return connectedCallOnce(heartbeatTimeout, udpHeartbeatTimeout, + robotBackupTimeout, clientBackupTimeout); + } + else if (myState == STATE_CONNECTING) + { + return connectingCallOnce(heartbeatTimeout, udpHeartbeatTimeout, + robotBackupTimeout, clientBackupTimeout); + } + else if (myState == STATE_GATHERING) + { + return gatheringCallOnce(heartbeatTimeout, udpHeartbeatTimeout, + robotBackupTimeout, clientBackupTimeout); + } + else if (myState == STATE_STARTING) + { + return startingCallOnce(heartbeatTimeout, udpHeartbeatTimeout, + robotBackupTimeout, clientBackupTimeout); + } + else + { + ArLog::log(ArLog::Normal, "%s in bad state, disconnecting", + myRobotName.c_str()); + return false; + } + +} + +AREXPORT bool ArCentralForwarder::startingCallOnce( + double heartbeatTimeout, double udpHeartbeatTimeout, + double robotBackupTimeout, double clientBackupTimeout) +{ + myClient = new ArClientBase; + myClient->enforceProtocolVersion(myEnforceProtocolVersion.c_str(), false); + myClient->enforceType(myEnforceType, false); + std::string name; + name = "ArForwarderClient_" + myRobotName; + myClient->setRobotName(name.c_str()); + + if (myClient->internalNonBlockingConnectStart("", 0, true, "", "", + mySocket) != + ArClientBase::NON_BLOCKING_CONTINUE) + { + ArLog::log(ArLog::Normal, + "%sCould not start connect to switching client %s from %s", + myPrefix.c_str(), myRobotName.c_str(), + mySocket->getIPString()); + return false; + } + myState = STATE_CONNECTING; + myLastTcpHeartbeat.setToNow(); + myLastUdpHeartbeat.setToNow(); + return callOnce(heartbeatTimeout, udpHeartbeatTimeout, + robotBackupTimeout, clientBackupTimeout); +} + +AREXPORT bool ArCentralForwarder::connectingCallOnce( + double heartbeatTimeout, double udpHeartbeatTimeout, + double robotBackupTimeout, double clientBackupTimeout) +{ + + ArClientBase::NonBlockingConnectReturn ret; + + if ((ret = myClient->internalNonBlockingConnectContinue()) == + ArClientBase::NON_BLOCKING_CONTINUE) + return true; + else if (ret == ArClientBase::NON_BLOCKING_FAILED) + { + ArLog::log(ArLog::Normal, + "%sCould not connect to switching client %s from %s", + myPrefix.c_str(), myRobotName.c_str(), + mySocket->getIPString()); + return false; + } + else if (ret == ArClientBase::NON_BLOCKING_CONNECTED) + { + myState = STATE_GATHERING; + myLastTcpHeartbeat.setToNow(); + myLastUdpHeartbeat.setToNow(); + return callOnce(heartbeatTimeout, udpHeartbeatTimeout, + robotBackupTimeout, clientBackupTimeout); + } + else + { + ArLog::log(ArLog::Normal, "%sIn unknown state connecting to %s", + myPrefix.c_str(), myRobotName.c_str()); + return false; + } +} + +AREXPORT bool ArCentralForwarder::gatheringCallOnce( + double heartbeatTimeout, double udpHeartbeatTimeout, + double robotBackupTimeout, double clientBackupTimeout) +{ + // if we have a heartbeat timeout make sure we've heard the + // heartbeat within that range + if (heartbeatTimeout >= -.00000001 && + myLastTcpHeartbeat.secSince() >= 5 && + myLastTcpHeartbeat.secSince() / 60.0 > heartbeatTimeout) + { + ArLog::log(ArLog::Normal, + "%sHaven't connected in %g minutes, dropping connection", + myPrefix.c_str(), heartbeatTimeout); + return false; + } + + if (!myClient->getReceivedDataList() || + !myClient->getReceivedArgRetList() || + !myClient->getReceivedGroupAndFlagsList()) + { + myClient->loopOnce(); + return true; + } + + ArLog::log(ArLog::Normal, "%Connected to switching client %s from %s", + myPrefix.c_str(), myRobotName.c_str(), mySocket->getIPString()); + //clientBase->logDataList(); + char serverName[1024]; + sprintf(serverName, "ArForwarderServer_%s", myRobotName.c_str()); + myServer = new ArServerBase(false, serverName, false, "", "", + false, true, + false, + false, false); + myServer->enforceProtocolVersion(myEnforceProtocolVersion.c_str()); + // there's no enforce of type here since this is the proxy for MP/ME + // and such (robots don't connect here) + + myServer->addClientRemovedCallback(&myClientServerClientRemovedCB); + + ArTime startedOpening; + startedOpening.setToNow(); + int port; + bool foundPort; + + std::map::iterator usedIt; + // walk through our ports starting at our starting port + for (port = myStartingPort, foundPort = false; + !foundPort && port < 65536; + port++) + { + // if we've used the port in the last 2 minutes then skip it + if ((usedIt = myUsedPorts->find(port)) != myUsedPorts->end() && + (*usedIt).second != NULL && + ((*usedIt).second->getSec() == 0 || + (*usedIt).second->secSince() < 120)) + { + + ArLog::log(ArLog::Verbose, "%sSkipping port %d", myPrefix.c_str(), port); + continue; + } + + // try to open it + if (myServer->open(port, myMainServer->getOpenOnIP())) + { + foundPort = true; + myPort = port; + } + } + + if (!foundPort) + { + ArLog::log(ArLog::Normal, "%s Could not find port", + myPrefix.c_str()); + } + myServer->setUserInfo(myMainServer->getUserInfo()); + + std::map::const_iterator dIt; + ArClientData *clientData; + + myServer->addClientRemovedCallback(&myRobotServerClientRemovedCB); + + myClient->addHandler("centralHeartbeat", &myNetCentralHeartbeatCB); + myClient->request("centralHeartbeat", 1000); + + if (myClient->dataExists("identSetSelfIdentifier")) + { + ArNetPacket sending; + sending.strToBuf("CentralServer"); + myClient->requestOnce("identSetSelfIdentifier", &sending); + } + + myLastTcpHeartbeat.setToNow(); + myLastUdpHeartbeat.setToNow(); + + for (dIt = myClient->getDataMap()->begin(); + dIt != myClient->getDataMap()->end(); + dIt++) + { + clientData = (*dIt).second; + + if (myMainServer->dataHasFlag(clientData->getName(), + "MAIN_SERVER_ONLY")) + { + ArLog::log(ArLog::Normal, + "%sNot forwarding %s since it is MAIN_SERVER_ONLY", + myPrefix.c_str(), clientData->getName()); + continue; + } + else if (clientData->hasDataFlag("DO_NOT_FORWARD")) + { + ArLog::log(ArLog::Normal, + "%sNot forwarding %s since it is DO_NOT_FORWARD", + myPrefix.c_str(), clientData->getName()); + continue; + } + else if (clientData->hasDataFlag("RETURN_NONE")) + { + myReturnTypes[clientData->getCommand()] = RETURN_NONE; + } + else if (clientData->hasDataFlag("RETURN_SINGLE")) + { + myReturnTypes[clientData->getCommand()] = RETURN_SINGLE; + myRequestOnces[clientData->getCommand()] = + new std::list; + } + else if (clientData->hasDataFlag("RETURN_VIDEO")) + { + ArLog::log(ArLog::Normal, + "%sForwarding %s that is RETURN_VIDEO", + myPrefix.c_str(), clientData->getName()); + myReturnTypes[clientData->getCommand()] = RETURN_VIDEO; + myRequestOnces[clientData->getCommand()] = + new std::list; + } + else if (clientData->hasDataFlag("RETURN_VIDEO_OPTIM")) + { + ArLog::log(ArLog::Normal, + "%sForwarding %s that is RETURN_VIDEO_OPTIM", + myPrefix.c_str(), clientData->getName()); + myReturnTypes[clientData->getCommand()] = RETURN_VIDEO_OPTIM; + myRequestOnces[clientData->getCommand()] = + new std::list; + } + else if (clientData->hasDataFlag("RETURN_UNTIL_EMPTY")) + { + myReturnTypes[clientData->getCommand()] = RETURN_UNTIL_EMPTY; + myRequestOnces[clientData->getCommand()] = + new std::list; + + } + else if (clientData->hasDataFlag("RETURN_COMPLEX")) + { + ArLog::log(ArLog::Normal, + "%sNot forwarding %s since it is a complex return", + myPrefix.c_str(), clientData->getName()); + continue; + } + else + { + ArLog::log(ArLog::Normal, + "%sNot forwarding %s since it is an unknown return (data flags %s)", + myPrefix.c_str(), clientData->getName(), + clientData->getDataFlagsString()); + continue; + } + + setLastRequest(clientData->getCommand()); + setLastBroadcast(clientData->getCommand()); + + myServer->addDataAdvanced( + clientData->getName(), clientData->getDescription(), + NULL, clientData->getArgumentDescription(), + clientData->getReturnDescription(), clientData->getCommandGroup(), + clientData->getDataFlagsString(), clientData->getCommand(), + &myInternalRequestChangedFunctor, + &myInternalRequestOnceFunctor); + + myClient->addHandler(clientData->getName(), &myReceiveDataFunctor); + } + if (myClient->dataExists("centralServerHeartbeat")) + { + ArNetPacket sending; + myRobotHasCentralServerHeartbeat = true; + myLastSentCentralServerHeartbeat.setToNow(); + myClient->requestOnce("centralServerHeartbeat", &sending, true); + myClient->requestOnceUdp("centralServerHeartbeat", &sending, true); + } + myState = STATE_CONNECTED; + return callOnce(heartbeatTimeout, udpHeartbeatTimeout, + robotBackupTimeout, clientBackupTimeout); +} + +AREXPORT bool ArCentralForwarder::connectedCallOnce( + double heartbeatTimeout, double udpHeartbeatTimeout, + double robotBackupTimeout, double clientBackupTimeout) +{ + if (!myClient->isConnected()) + { + ArLog::log(ArLog::Normal, "%sLost connection to robot", + myPrefix.c_str()); + return false; + } + + myClient->setBackupTimeout(robotBackupTimeout); + myServer->setBackupTimeout(clientBackupTimeout); + + if (myRobotHasCentralServerHeartbeat && + myLastSentCentralServerHeartbeat.mSecSince() >= 1000) + { + ArNetPacket sending; + myLastSentCentralServerHeartbeat.setToNow(); + myClient->requestOnce("centralServerHeartbeat", &sending, true); + myClient->requestOnceUdp("centralServerHeartbeat", &sending, true); + } + + myClient->loopOnce(); + myServer->loopOnce(); + + // if we have a heartbeat timeout make sure we've heard the + // heartbeat within that range + if (heartbeatTimeout >= -.00000001 && + myLastTcpHeartbeat.secSince() >= 5 && + myLastTcpHeartbeat.secSince() / 60.0 >= heartbeatTimeout) + { + ArLog::log(ArLog::Normal, "%sHaven't heard from robot in %g minutes, dropping connection", myPrefix.c_str(), heartbeatTimeout); + return false; + } + + // if we have a heartbeat timeout make sure we've heard the + // heartbeat within that range + if ((!myClient->isTcpOnlyFromServer() || !myClient->isTcpOnlyToServer()) && + udpHeartbeatTimeout >= -.00000001 && + myLastUdpHeartbeat.secSince() >= 5 && + myLastUdpHeartbeat.secSince() / 60.0 >= udpHeartbeatTimeout) + { + ArLog::log(ArLog::Normal, + "%sSwitching to TCP only since haven't gotten UDP in %g minutes", + myPrefix.c_str(), udpHeartbeatTimeout); + myClient->setTcpOnlyFromServer(); + myClient->setTcpOnlyToServer(); + } + + return true; +} + +void ArCentralForwarder::robotServerClientRemoved(ArServerClient *client) +{ + std::map *>::iterator rIt; + std::list *requestList = NULL; + std::list::iterator scIt; + + printf("Client disconnected\n"); + for (rIt = myRequestOnces.begin(); rIt != myRequestOnces.end(); rIt++) + { + requestList = (*rIt).second; + // while we have entries for this client we loop and replace them + // with NULLs + bool foundOne = true; + while (foundOne) + { + foundOne = false; + // see if we found one + for (scIt = requestList->begin(); + !foundOne && scIt != requestList->end(); + scIt++) + { + if ((*scIt) == client) + { + foundOne = true; + printf("Got...\n"); + requestList->insert(scIt, (ArServerClient*)NULL); + for (scIt = requestList->begin(); + scIt != requestList->end(); + scIt++) + { + if ((*scIt) == client) + { + requestList->erase(scIt); + printf("Removed request for client %p\n", client); + break; + } + } + } + } + } + } +} + +void ArCentralForwarder::clientServerClientRemoved(ArServerClient *client) +{ + if (client->getState() != ArServerClient::STATE_DISCONNECTED) + myForwarderServerClientRemovedCB->invoke(this, client); +} + + + +void ArCentralForwarder::receiveData(ArNetPacket *packet) +{ + ReturnType returnType; + std::list::iterator it; + ArServerClient *client; + + // chop off the old footer + //packet->setLength(packet->getLength() - ArNetPacket::FOOTER_LENGTH); + packet->setAddedFooter(true); + + /* + if (strcmp(myClient->getName(packet->getCommand(), true), + "getPictureCam1") == 0) + printf("Got getPictureCam1...\n"); + */ + returnType = getReturnType(packet->getCommand()); + //printf("Got a packet in for %s %d\n", myClient->getName(packet->getCommand(), true), packet->getCommand()); + + // this part is seeing if it came from a request_once, if so we + // don't service anything else (so we take care of those things that + // only happen once better then the ones that are mixing... but that + // should be okay) + checkRequestOnces(packet->getCommand()); + if ((returnType == RETURN_SINGLE || returnType == RETURN_UNTIL_EMPTY) && + (it = myRequestOnces[packet->getCommand()]->begin()) != + myRequestOnces[packet->getCommand()]->end()) + { + //if (returnType == RETURN_UNTIL_EMPTY) + //printf("Got a packet for %s with length %d %d\n", myClient->getName(packet->getCommand(), true), packet->getDataLength(), packet->getLength()); + + client = (*it); + if (client != NULL) + { + if (packet->getPacketSource() == ArNetPacket::TCP) + client->sendPacketTcp(packet); + else if (packet->getPacketSource() == ArNetPacket::UDP) + client->sendPacketUdp(packet); + else + { + client->sendPacketTcp(packet); + ArLog::log(ArLog::Normal, + "%sDon't know what type of packet %s is (%d)", + myPrefix.c_str(), + myClient->getName(packet->getCommand(), true), + packet->getPacketSource()); + } + } + if ((returnType == RETURN_UNTIL_EMPTY && packet->getDataLength() == 0) || + returnType == RETURN_SINGLE) + { + //if (returnType == RETURN_UNTIL_EMPTY) + //printf("Got final packet for for %s\n", myClient->getName(packet->getCommand(), true)); + myRequestOnces[packet->getCommand()]->pop_front(); + } + } + else if (returnType == RETURN_VIDEO) + { + // what we do here is send it to the ones that have requested it + // but aren't listening for the broadcast... then we broadcast it + // to everyone whose listening... this should ensure that everyone + // just gets the packet once as often as we see it... + + while ((it = myRequestOnces[packet->getCommand()]->begin()) != + myRequestOnces[packet->getCommand()]->end()) + { + //printf("Sent a single return_single_and_broadcast for %s\n", myClient->getName(packet->getCommand(), true)); + client = (*it); + if (client != NULL && client->getFrequency(packet->getCommand()) == -2) + { + if (packet->getPacketSource() == ArNetPacket::TCP) + client->sendPacketTcp(packet); + else if (packet->getPacketSource() == ArNetPacket::UDP) + client->sendPacketUdp(packet); + else + { + client->sendPacketTcp(packet); + ArLog::log(ArLog::Normal, + "%sDon't know what type of packet %s is (%d)", + myPrefix.c_str(), + myClient->getName(packet->getCommand(), true), + packet->getPacketSource()); + } + } + myRequestOnces[packet->getCommand()]->pop_front(); + } + //printf("Broadcast return_single_and_broadcast for %s\n", myClient->getName(packet->getCommand(), true)); + myLastBroadcast[packet->getCommand()]->setToNow(); + if (packet->getPacketSource() == ArNetPacket::TCP) + { + myServer->broadcastPacketTcpByCommand(packet, packet->getCommand()); + } + else if (packet->getPacketSource() == ArNetPacket::UDP) + { + myServer->broadcastPacketUdpByCommand(packet, packet->getCommand()); + } + else + { + myServer->broadcastPacketTcpByCommand(packet, packet->getCommand()); + ArLog::log(ArLog::Normal, + "%sDon't know what type of packet %s is (%d)", + myPrefix.c_str(), + myClient->getName(packet->getCommand(), true), + packet->getPacketSource()); + } + } + else if (returnType == RETURN_VIDEO_OPTIM) + { + // what we do here is send it to the ones that have requested it + while ((it = myRequestOnces[packet->getCommand()]->begin()) != + myRequestOnces[packet->getCommand()]->end()) + { + client = (*it); + /* + ArLog::log(ArLog::Normal, "%sSent a return_video_optim for %s to %s", + myPrefix.c_str(), + myClient->getName(packet->getCommand(), true), + client->getIPString()); + */ + if (client != NULL) + { + if (packet->getPacketSource() == ArNetPacket::TCP) + client->sendPacketTcp(packet); + else if (packet->getPacketSource() == ArNetPacket::UDP) + client->sendPacketUdp(packet); + else + { + client->sendPacketTcp(packet); + ArLog::log(ArLog::Normal, + "%sDon't know what type of packet %s is (%d)", + myPrefix.c_str(), + myClient->getName(packet->getCommand(), true), + packet->getPacketSource()); + } + } + myRequestOnces[packet->getCommand()]->pop_front(); + } + } + else + { + myLastBroadcast[packet->getCommand()]->setToNow(); + if (packet->getPacketSource() == ArNetPacket::TCP) + { + myServer->broadcastPacketTcpByCommand(packet, packet->getCommand()); + } + else if (packet->getPacketSource() == ArNetPacket::UDP) + { + myServer->broadcastPacketUdpByCommand(packet, packet->getCommand()); + } + else + { + myServer->broadcastPacketTcpByCommand(packet, packet->getCommand()); + ArLog::log(ArLog::Normal, + "%sDon't know what type of packet %s is (%d)", + myPrefix.c_str(), + myClient->getName(packet->getCommand(), true), + packet->getPacketSource()); + } + } + +} + +void ArCentralForwarder::internalRequestChanged(long interval, + unsigned int command) +{ + /* + if (strcmp(myClient->getName(command, true), + "getPictureCam1") == 0) + printf("Changed getPictureCam1 to %d...\n", interval); + */ + if (interval == -2) + { + ArLog::log(ArLog::Verbose, "%sStopping request for %s", + myPrefix.c_str(), myClient->getName(command, true)); + myClient->requestStopByCommand(command); + setLastRequest(command); + } + else + { + ReturnType returnType; + + returnType = getReturnType(command); + if (returnType == RETURN_VIDEO && interval != -1) + { + ArLog::log(ArLog::Verbose, "%sIgnoring a RETURN_VIDEO attempted request of %s at %d interval since RETURN_VIDEOs cannot request at an interval", + myPrefix.c_str(), myClient->getName(command, true), interval); + return; + } + if (returnType == RETURN_VIDEO_OPTIM && interval != -1) + { + ArLog::log(ArLog::Verbose, "%sIgnoring a RETURN_VIDEO_OPTIM attempted request of %s at %d interval since RETURN_VIDEOs cannot request at an interval", + myPrefix.c_str(), myClient->getName(command, true), interval); + return; + } + + ArLog::log(ArLog::Verbose, "%sRequesting %s at interval of %ld", + myPrefix.c_str(), myClient->getName(command, true), interval); + myClient->requestByCommand(command, interval); + setLastRequest(command); + // if the interval is -1 then also requestOnce it so that anyone + // connecting after the first connection can actually get data too + myClient->requestOnceByCommand(command); + } +} + +bool ArCentralForwarder::internalRequestOnce( + ArServerClient *client, ArNetPacket *packet, bool tcp) +{ + ReturnType returnType = RETURN_NONE; + + returnType = getReturnType(packet->getCommand()); + + // chop off the footer + packet->setAddedFooter(true); + /* + if (strcmp(myClient->getName(packet->getCommand(), true), + "getPictureCam1") == 0) + printf("Request once for getPictureCam1...\n"); + */ + // if its video and the last broadcast or request was very recently + // then ignore it so we don't wind up using up our wireless + // bandwidth + // MPL taking this out since it may be causing some problems + /* + if (returnType == RETURN_VIDEO && + (myLastBroadcast[packet->getCommand()]->mSecSince() < 25 || + myLastRequest[packet->getCommand()]->mSecSince() < 25)) + { + ArLog::log(ArLog::Normal, "Ignoring a RETURN_VIDEO of %s since request or broadcast was recent", myClient->getName(packet->getCommand(), true)); + return; + } + */ + // if its a type where we keep track then put it into the list + if (returnType == RETURN_SINGLE || returnType == RETURN_UNTIL_EMPTY || + returnType == RETURN_VIDEO || returnType == RETURN_VIDEO_OPTIM) + { + //if (returnType == RETURN_UNTIL_EMPTY) + //printf("Trying to request once %s\n", myClient->getName(packet->getCommand(), true)); + checkRequestOnces(packet->getCommand()); + myRequestOnces[packet->getCommand()]->push_back(client); + } + + bool ret; + ArLog::log(ArLog::Verbose, "%sRequesting %s once", + myPrefix.c_str(), myClient->getName(packet->getCommand())); + if (tcp) + ret = myClient->requestOnceByCommand(packet->getCommand(), packet); + else + ret = myClient->requestOnceByCommandUdp(packet->getCommand(), packet); + + setLastRequest(packet->getCommand()); + + return ret; +} + + +AREXPORT void ArCentralForwarder::netCentralHeartbeat(ArNetPacket *packet) +{ + if (packet->getPacketSource() == ArNetPacket::TCP) + myLastTcpHeartbeat.setToNow(); + else if (packet->getPacketSource() == ArNetPacket::UDP) + myLastUdpHeartbeat.setToNow(); + else + ArLog::log(ArLog::Normal, + "%sGot unknown packet source for heartbeat packet", + myPrefix.c_str()); +} + +AREXPORT bool ArCentralForwarder::addHandler( + const char *name, ArFunctor1 *functor) +{ + if (myClient != NULL) + { + return myClient->addHandler(name, functor); + } + else + { + ArLog::log(ArLog::Normal, + "ArCentralForwarder::%s::addHandler: Tried to call while client was still NULL", + getRobotName()); + return false; + } +} + +AREXPORT bool ArCentralForwarder::remHandler(const char *name, ArFunctor1 *functor) +{ + if (myClient != NULL) + { + return myClient->remHandler(name, functor); + } + else + { + ArLog::log(ArLog::Normal, + "ArCentralForwarder::%s::remHandler: Tried to call while client was still NULL", + getRobotName()); + return false; + } +} + +AREXPORT bool ArCentralForwarder::request(const char *name, long mSec) +{ + if (myServer != NULL) + { + return myServer->internalSetDefaultFrequency(name, mSec); + + } + else + { + ArLog::log(ArLog::Normal, + "ArCentralForwarder::%s::remHandler: Tried to call while server was still NULL", + getRobotName()); + return false; + } +} + +AREXPORT bool ArCentralForwarder::requestOnce(const char *name, + ArNetPacket *packet, + bool quiet) +{ + if (myClient != NULL) + { + unsigned int commandNum = myClient->findCommandFromName(name); + if (commandNum == 0) + { + if (!quiet) + ArLog::log(ArLog::Normal, + "ArCentralForwarder::%s::requestOnce: Can't find commandNum for %s", + getRobotName(), name); + return false; + } + //return myClient->requestOnce(name, packet, quiet); + if (packet != NULL) + { + packet->setCommand(commandNum); + packet->finalizePacket(); + return internalRequestOnce(NULL, packet, true); + } + else + { + ArNetPacket tempPacket; + tempPacket.setCommand(commandNum); + tempPacket.finalizePacket(); + return internalRequestOnce(NULL, &tempPacket, true); + } + } + else + { + if (!quiet) + ArLog::log(ArLog::Normal, + "ArCentralForwarder::%s::requestOnce: Tried to call (for %s) while client was still NULL", + getRobotName(), name); + return false; + } +} + +AREXPORT bool ArCentralForwarder::requestOnceUdp(const char *name, + ArNetPacket *packet, + bool quiet) +{ + if (myClient != NULL) + { + unsigned int commandNum = myClient->findCommandFromName(name); + if (commandNum == 0) + { + if (!quiet) + ArLog::log(ArLog::Normal, + "ArCentralForwarder::%s::requestOnce: Can't find commandNum for %s", + getRobotName(), name); + return false; + } + //return myClient->requestOnceUdp(name, packet, quiet); + if (packet != NULL) + { + packet->setCommand(commandNum); + packet->finalizePacket(); + return internalRequestOnce(NULL, packet, false); + } + else + { + ArNetPacket tempPacket; + tempPacket.setCommand(commandNum); + tempPacket.finalizePacket(); + return internalRequestOnce(NULL, &tempPacket, false); + } + } + else + { + if (!quiet) + ArLog::log(ArLog::Normal, + "ArCentralForwarder::%s::requestOnce: Tried to call (for %s) while client was still NULL", + getRobotName(), name); + return false; + } +} + +AREXPORT bool ArCentralForwarder::requestOnceWithString(const char *name, const char *str) +{ + ArNetPacket tempPacket; + tempPacket.strToBuf(str); + + return requestOnce(name, &tempPacket); +} + +AREXPORT bool ArCentralForwarder::dataExists(const char *name) +{ + if (myClient != NULL) + { + return myClient->dataExists(name); + } + else + { + ArLog::log(ArLog::Normal, + "ArCentralForwarder::%s::dataExists: Tried to call while client was still NULL", + getRobotName()); + return false; + } +} + +ArCentralForwarder::ReturnType ArCentralForwarder::getReturnType(int command) +{ + if (myReturnTypes.find(command) != myReturnTypes.end()) + return myReturnTypes[command]; + else + return RETURN_NONE; +} + +void ArCentralForwarder::checkRequestOnces(unsigned int command) +{ + if (myRequestOnces.find(command) == myRequestOnces.end()) + myRequestOnces[command] = new std::list; +} + +void ArCentralForwarder::setLastRequest(unsigned int command) +{ + if (myLastRequest.find(command) == myLastRequest.end()) + myLastRequest[command] = new ArTime; + myLastRequest[command]->setToNow(); +} + +void ArCentralForwarder::setLastBroadcast(unsigned int command) +{ + if (myLastBroadcast.find(command) == myLastBroadcast.end()) + myLastBroadcast[command] = new ArTime; + myLastBroadcast[command]->setToNow(); +} diff --git a/Legacy/Aria/ArNetworking/src/ArCentralManager.cpp b/Legacy/Aria/ArNetworking/src/ArCentralManager.cpp new file mode 100644 index 0000000..0806da1 --- /dev/null +++ b/Legacy/Aria/ArNetworking/src/ArCentralManager.cpp @@ -0,0 +1,712 @@ +#include "Aria.h" +#include "ArExport.h" +#include "ArCentralManager.h" + + +ArCentralManager::ArCentralManager(ArServerBase *robotServer, + ArServerBase *clientServer) : + myNetSwitchCB(this, &ArCentralManager::netServerSwitch), + myNetClientListCB(this, &ArCentralManager::netClientList), + myAriaExitCB(this, &ArCentralManager::close), + myProcessFileCB(this, &ArCentralManager::processFile), + myForwarderServerClientRemovedCB( + this, &ArCentralManager::forwarderServerClientRemovedCallback), + myMainServerClientRemovedCB( + this, &ArCentralManager::mainServerClientRemovedCallback) +{ + myMutex.setLogName("ArCentralManager::myCallbackMutex"); + myDataMutex.setLogName("ArCentralManager::myDataMutex"); + setThreadName("ArCentralManager"); + + myRobotServer = robotServer; + myClientServer = clientServer; + + myAriaExitCB.setName("ArCentralManager"); + Aria::addExitCallback(&myAriaExitCB, 25); + + myEnforceType = ArServerCommands::TYPE_UNSPECIFIED; + + myClientBackupTimeout = 2; + Aria::getConfig()->addParam( + ArConfigArg("CentralServerToClientTimeoutInMins", + &myClientBackupTimeout, + "The amount of time the central server can go without sending a packet to the robot successfully (when there are packets to send). A number less than 0 means this won't happen. The time is in minutes but takes doubles (ie .5) (5 seconds is used if the value is positive, but less than that amount)", -1), + "Connection timeouts", ArPriority::DETAILED); + + myRobotBackupTimeout = 2; + Aria::getConfig()->addParam( + ArConfigArg("CentralServerToRobotTimeoutInMins", + &myRobotBackupTimeout, + "The amount of time the central server can go without sending a packet to the robot successfully (when there are packets to send). A number less than 0 means this won't happen. The time is in minutes but takes doubles (ie .5) (5 seconds is used if the value is positive, but less than that amount)", -1), + "Connection timeouts", ArPriority::DETAILED); + + myHeartbeatTimeout = 2; + Aria::getConfig()->addParam( + ArConfigArg("CentralServerFromRobotTimeoutInMins", + &myHeartbeatTimeout, + "The amount of time the central server can go without hearing a robot's heartbeat without disconnecting it. A number less than 0 means that the robots will never timeout. The time is in minutes but takes doubles (ie .5) (5 seconds is used if the value is positive, but less than that amount)", -1), + "Connection timeouts", ArPriority::DETAILED); + + myUdpHeartbeatTimeout = 2; + Aria::getConfig()->addParam( + ArConfigArg("CentralServerFromRobotUdpTimeoutInMins", + &myUdpHeartbeatTimeout, + "The amount of time the central server can go without hearing a robot's udp heartbeat without disconnecting it (this fails it over to tcp only). A number less than 0 means that the robots will never timeout. The time is in minutes but takes doubles (ie .5) (5 seconds is used if the value is positive, but less than that amount)", -1), + "Connection timeouts", ArPriority::DETAILED); + + + myProcessFileCB.setName("ArCentralManager"); + Aria::getConfig()->addProcessFileCB(&myProcessFileCB, -999); + + myRobotServer->addData("switch", "switches the direction of the connection, after this is requested it sends an empty packet denoting acceptance of the switch, then switches this to a client connection", + &myNetSwitchCB, "string: robotName", "empty packet", "RobotInfo", + "RETURN_SINGLE"); + + myRobotServer->addData("centralServerHeartbeat", "Just a data to let the robot's know that this server has the centralServerHeartbeat feature (nothing is actually done with this command)", + NULL, "none", "none", "RobotInfo", + "RETURN_NONE"); + + myClientServer->addData("clientList", "Lists the clients that are connected", + &myNetClientListCB, "none", + "ubyte2: numClients; repeating for [string: hostname (empty means this host); ubyte2: port; string: robot name; string: flags; string: robot ip address]", + "RobotInfo", "RETURN_SINGLE"); + myClientServer->addData("clientAdded", "Broadcast when a client is added", + NULL, "none", + "string: hostname (empty means this host); ubyte2: port; string: robot name; string: flags; string: robot ip address", + "RobotInfo", "RETURN_SINGLE"); + myClientServer->addData("clientRemoved", "Broadcast when a client is removed", + NULL, "none", + "string: hostname (empty means this host); ubyte2: port; string: robot name; string: flags; string: robot ip address", + "RobotInfo", "RETURN_SINGLE"); + + myClientServer = clientServer; + + myClosingConnectionID = 0; + + myMostForwarders = 0; + myMostClients = 0; + + myForwarderServerClientRemovedCB.setName("ArCentralManager"); + + + myMainServerClientRemovedCB.setName("ArCentralManager"); + myClientServer->addClientRemovedCallback(&myMainServerClientRemovedCB); + + runAsync(); +} + +ArCentralManager::~ArCentralManager() +{ +} + +void ArCentralManager::close(void) +{ + std::list::iterator fIt; + ArCentralForwarder *forwarder; + + ArLog::log(ArLog::Normal, "ArCentralManager closing"); + //myDataMutex.lock(); + while ((fIt = myForwarders.begin()) != myForwarders.end()) + { + forwarder = (*fIt); + std::multimap *>::iterator it; + for (it = myForwarderRemovedCBList.begin(); + it != myForwarderRemovedCBList.end(); + it++) + (*it).second->invoke(forwarder); + + myForwarders.pop_front(); + delete forwarder; + + } + //myDataMutex.unlock(); + ArLog::log(ArLog::Normal, "ArCentralManager closed"); +} + +void ArCentralManager::netServerSwitch(ArServerClient *client, ArNetPacket *packet) +{ + char robotName[512]; + std::string uniqueName; + + robotName[0] = '\0'; + + //printf("robotName before '%s'\n", robotName); + + packet->bufToStr(robotName, sizeof(robotName)); + + ArNetPacket sendPacket; + /// acknowledge the switch + client->sendPacketTcp(&sendPacket); + + ArSocket *clientSocket = new ArSocket; + clientSocket->transfer(client->getTcpSocket()); + + client->tcpCallback(); + client->forceDisconnect(true); + + + // make the basis of the unique name + if (robotName[0] != '\0') + uniqueName = robotName; + else + uniqueName = client->getIPString(); + + //printf("Starting with '%s'\n", uniqueName.c_str()); + + myDataMutex.lock(); + // walk through and make the name unique + std::list::iterator fIt; + ArCentralForwarder *forwarder; + /* the old code that made the names unique + bool nameIsUnique = false; + while (!nameIsUnique) + { + nameIsUnique = true; + for (fIt = myForwarders.begin(); + fIt != myForwarders.end() && nameIsUnique; + fIt++) + { + forwarder = (*fIt); + if (strcasecmp(forwarder->getRobotName(), uniqueName.c_str()) == 0) + nameIsUnique = false; + } + if (!nameIsUnique) + uniqueName += "_"; + } + */ + // the new code that drops the duplicates and replaces it with the same name + for (fIt = myForwarders.begin(); fIt != myForwarders.end(); fIt++) + { + forwarder = (*fIt); + if (strcasecmp(forwarder->getRobotName(), uniqueName.c_str()) == 0) + { + ArLog::log(ArLog::Normal, + "ArCentralManager: Will drop old duplicate connection for %s", + uniqueName.c_str()); + forwarder->willReplace(); + } + } + + // remove any pending client duplicates + while (removePendingDuplicateConnections(uniqueName.c_str())); + + // end of new code, though it also had reordering down below in the runthread + + myClientSockets.push_back(clientSocket); + myClientNames.push_back(uniqueName); + + //printf("robotName after '%s'\n", robotName); + // just print out the switch request name if its the same as it came in as + if (strcmp(uniqueName.c_str(), robotName) == 0) + ArLog::log(ArLog::Normal, "Got switch request from %s from %s", + client->getIPString(), uniqueName.c_str()); + // otherwise let them know what the unique name is + if (strcmp(uniqueName.c_str(), robotName) != 0) + ArLog::log(ArLog::Normal, + "Got switch request from %s from %s that started as %s", + client->getIPString(), uniqueName.c_str(), robotName); + //printf("Ended with '%s'\n", uniqueName.c_str()); + myDataMutex.unlock(); +} + +/** + removes pending duplicate connections... has a return since you + must call it until it returns false... this is because of the list + management + */ +bool ArCentralManager::removePendingDuplicateConnections(const char *robotName) +{ + std::list::iterator sIt; + std::list::iterator nIt; + + ArSocket *socket; + std::string checkingName; + + for (sIt = myClientSockets.begin(), nIt = myClientNames.begin(); + sIt != myClientSockets.end() && nIt != myClientNames.end(); + sIt++, nIt++) + { + socket = (*sIt); + checkingName = (*nIt); + + + if (ArUtil::strcasecmp(robotName, checkingName) == 0) + { + ArLog::log(ArLog::Normal, + "ArCentralManager: Removing duplicate pending connection for %s", + robotName); + + myClientSockets.erase(sIt); + myClientNames.erase(nIt); + + // delete the old socket so it closes + delete socket; + + return true; + } + } + + return false; +} + +void ArCentralManager::netClientList(ArServerClient *client, ArNetPacket *packet) +{ + ArNetPacket sendPacket; + std::list::iterator fIt; + ArCentralForwarder *forwarder; + ArTypes::UByte2 sizeLen; + ArTypes::UByte2 realLen; + unsigned int numConnected = 0; + + myDataMutex.lock(); + sizeLen = sendPacket.getLength(); + sendPacket.uByte2ToBuf(0); + for (fIt = myForwarders.begin(); fIt != myForwarders.end(); fIt++) + { + forwarder = (*fIt); + + if (!forwarder->isConnected()) + continue; + + numConnected++; + sendPacket.strToBuf(""); + sendPacket.uByte2ToBuf(forwarder->getPort()); + sendPacket.strToBuf(forwarder->getRobotName()); + sendPacket.strToBuf(""); + sendPacket.strToBuf( + forwarder->getClient()->getTcpSocket()->getIPString()); + } + + realLen = sendPacket.getLength(); + sendPacket.setLength(sizeLen); + sendPacket.uByte2ToBuf(numConnected); + sendPacket.setLength(realLen); + + myDataMutex.unlock(); + client->sendPacketTcp(&sendPacket); +} + +/// This should be its own thread here +void *ArCentralManager::runThread(void *arg) +{ + std::list::iterator sIt; + std::list::iterator nIt; + std::list::iterator fIt; + ArSocket *socket; + std::string robotName; + ArCentralForwarder *forwarder; + + ArNetPacket *packet; + std::list addPackets; + std::list remPackets; + + + threadStarted(); + while (getRunning()) + { + int numForwarders = 0; + int numClients = 0; + + myDataMutex.lock(); + // this is where the original code to add forwarders was before we + // changed the unique behavior to drop old ones... + + + std::list connectedRemoveList; + std::list unconnectedRemoveList; + for (fIt = myForwarders.begin(); fIt != myForwarders.end(); fIt++) + { + forwarder = (*fIt); + + numForwarders++; + if (forwarder->getServer() != NULL) + numClients += forwarder->getServer()->getNumClients(); + bool connected = forwarder->isConnected(); + bool removed = false; + if (!forwarder->callOnce(myHeartbeatTimeout, myUdpHeartbeatTimeout, + myRobotBackupTimeout, myClientBackupTimeout)) + { + if (connected) + { + ArLog::log(ArLog::Normal, "Will remove forwarder from %s", + forwarder->getRobotName()); + connectedRemoveList.push_back(forwarder); + removed = true; + } + else + { + ArLog::log(ArLog::Normal, "Failed to connect to forwarder from %s", + forwarder->getRobotName()); + unconnectedRemoveList.push_back(forwarder); + removed = true; + } + } + if (!connected && !removed && forwarder->isConnected()) + { + ArLog::log(ArLog::Normal, "Adding forwarder %s", + forwarder->getRobotName()); + ArTime *newTime = new ArTime; + newTime->setSec(0); + myUsedPorts[forwarder->getPort()] = newTime; + + std::multimap *>::iterator it; + for (it = myForwarderAddedCBList.begin(); + it != myForwarderAddedCBList.end(); + it++) + { + if ((*it).second->getName() == NULL || + (*it).second->getName()[0] == '\0') + ArLog::log(ArLog::Normal, "Calling unnamed add functor at %d", + -(*it).first); + else + ArLog::log(ArLog::Normal, "Calling %s add functor at %d", + (*it).second->getName(), -(*it).first); + (*it).second->invoke(forwarder); + } + ArLog::log(ArLog::Normal, "Added forwarder %s", + forwarder->getRobotName()); + ArNetPacket *sendPacket = new ArNetPacket; + sendPacket->strToBuf(""); + sendPacket->uByte2ToBuf(forwarder->getPort()); + sendPacket->strToBuf(forwarder->getRobotName()); + sendPacket->strToBuf(""); + sendPacket->strToBuf( + forwarder->getClient()->getTcpSocket()->getIPString()); + addPackets.push_back(sendPacket); + // MPL added this at the same time as the changes for the deadlock that happened down below + //myClientServer->broadcastPacketTcp(&sendPacket, "clientAdded"); + } + } + + while ((fIt = connectedRemoveList.begin()) != connectedRemoveList.end()) + { + forwarder = (*fIt); + + ArLog::log(ArLog::Normal, "Removing forwarder %s", + forwarder->getRobotName()); + std::multimap *>::iterator it; + for (it = myForwarderRemovedCBList.begin(); + it != myForwarderRemovedCBList.end(); + it++) + { + if ((*it).second->getName() == NULL || + (*it).second->getName()[0] == '\0') + ArLog::log(ArLog::Normal, "Calling unnamed remove functor at %d", + -(*it).first); + else + ArLog::log(ArLog::Normal, "Calling %s remove functor at %d", + (*it).second->getName(), -(*it).first); + (*it).second->invoke(forwarder); + } + + ArLog::log(ArLog::Normal, "Called forwarder removed for %s", + forwarder->getRobotName()); + ArNetPacket *sendPacket = new ArNetPacket; + sendPacket->strToBuf(""); + sendPacket->uByte2ToBuf(forwarder->getPort()); + sendPacket->strToBuf(forwarder->getRobotName()); + sendPacket->strToBuf(""); + sendPacket->strToBuf( + forwarder->getClient()->getTcpSocket()->getIPString()); + // MPL making this just push packets into a list to broadcast at the end since this was deadlocking + //myClientServer->broadcastPacketTcp(&sendPacket, "clientRemoved"); + remPackets.push_back(sendPacket); + + if (myUsedPorts.find(forwarder->getPort()) != myUsedPorts.end() && + myUsedPorts[forwarder->getPort()] != NULL) + myUsedPorts[forwarder->getPort()]->setToNow(); + + myForwarders.remove(forwarder); + delete forwarder; + connectedRemoveList.pop_front(); + ArLog::log(ArLog::Normal, "Removed forwarder"); + + } + + while ((fIt = unconnectedRemoveList.begin()) != + unconnectedRemoveList.end()) + { + forwarder = (*fIt); + ArLog::log(ArLog::Normal, "Removing unconnected forwarder %s", + forwarder->getRobotName()); + + if (myUsedPorts.find(forwarder->getPort()) != myUsedPorts.end() && + myUsedPorts[forwarder->getPort()] != NULL) + myUsedPorts[forwarder->getPort()]->setToNow(); + + myForwarders.remove(forwarder); + delete forwarder; + unconnectedRemoveList.pop_front(); + ArLog::log(ArLog::Normal, "Removed unconnected forwarder"); + } + + + // this code was up above just after the lock before we changed + // the behavior for unique names + while ((sIt = myClientSockets.begin()) != myClientSockets.end() && + (nIt = myClientNames.begin()) != myClientNames.end()) + { + socket = (*sIt); + robotName = (*nIt); + + myClientSockets.pop_front(); + myClientNames.pop_front(); + + ArLog::log(ArLog::Normal, + "New forwarder for socket from %s with name %s", + socket->getIPString(), robotName.c_str()); + + forwarder = new ArCentralForwarder(myClientServer, socket, + robotName.c_str(), + myClientServer->getTcpPort() + 1, + &myUsedPorts, + &myForwarderServerClientRemovedCB, + myEnforceProtocolVersion.c_str(), + myEnforceType); + myForwarders.push_back(forwarder); + } + + numClients += myRobotServer->getNumClients(); + if (myRobotServer != myClientServer) + numClients += myClientServer->getNumClients(); + // end of code moved for change in unique behavior + if (numClients > myMostClients) + { + ArLog::log(ArLog::Normal, "CentralManager: New most clients: %d", + numClients); + myMostClients = numClients; + } + + if (numForwarders > myMostForwarders) + myMostForwarders = numForwarders; + + if (numClients > myMostClients) + { + ArLog::log(ArLog::Normal, "CentralManager: New most forwarders: %d", + numForwarders); + myMostForwarders = numForwarders; + } + + myRobotServer->internalSetNumClients(numForwarders + + myClientSockets.size()); + + myDataMutex.unlock(); + + while (addPackets.begin() != addPackets.end()) + { + packet = addPackets.front(); + myClientServer->broadcastPacketTcp(packet, "clientAdded"); + addPackets.pop_front(); + delete packet; + } + + while (remPackets.begin() != remPackets.end()) + { + packet = remPackets.front(); + myClientServer->broadcastPacketTcp(packet, "clientRemoved"); + remPackets.pop_front(); + delete packet; + } + + ArUtil::sleep(1); + + //make this a REALLY long sleep to test the duplicate pending + //connection code + //ArUtil::sleep(20000); + } + + threadFinished(); + return NULL; +} + + +AREXPORT void ArCentralManager::addForwarderAddedCallback( + ArFunctor1 *functor, int priority) +{ + myCallbackMutex.lock(); + myForwarderAddedCBList.insert( + std::pair *>(-priority, + functor)); + myCallbackMutex.unlock(); +} + +AREXPORT void ArCentralManager::remForwarderAddedCallback( + ArFunctor1 *functor) +{ + myCallbackMutex.lock(); + + std::multimap *>::iterator it; + + for (it = myForwarderAddedCBList.begin(); + it != myForwarderAddedCBList.end(); + ++it) + { + if ((*it).second == functor) + { + myForwarderAddedCBList.erase(it); + myCallbackMutex.unlock(); + remForwarderAddedCallback(functor); + return; + } + } + myCallbackMutex.unlock(); +} + +AREXPORT void ArCentralManager::addForwarderRemovedCallback( + ArFunctor1 *functor, int priority) +{ + myCallbackMutex.lock(); + myForwarderRemovedCBList.insert( + std::pair *>(-priority, + functor)); + myCallbackMutex.unlock(); +} + +AREXPORT void ArCentralManager::remForwarderRemovedCallback( + ArFunctor1 *functor) +{ + myCallbackMutex.lock(); + std::multimap *>::iterator it; + + for (it = myForwarderRemovedCBList.begin(); + it != myForwarderRemovedCBList.end(); + ++it) + { + if ((*it).second == functor) + { + myForwarderRemovedCBList.erase(it); + myCallbackMutex.unlock(); + remForwarderRemovedCallback(functor); + return; + } + } + myCallbackMutex.unlock(); +} + +bool ArCentralManager::processFile(void) +{ + // this should be okay if it isn't locked since it takes care of + //thread safety itself and the client server can't go away, and its + //client tcp sender can't either... and if it locks here when the + //config changes from inside of it calling the clients, then its a + //deadlock + + //myDataMutex.lock(); + if (myClientServer != NULL) + myClientServer->setBackupTimeout(myClientBackupTimeout); + //myDataMutex.unlock(); + return true; +} + +AREXPORT void ArCentralManager::forwarderServerClientRemovedCallback( + ArCentralForwarder *forwarder, ArServerClient *client) +{ + // if this matches we're already closing this so don't do/print anything + if (myClosingConnectionID != 0 && + myClosingConnectionID == client->getIdentifier().getConnectionID()) + return; + + ArLog::log(ArLog::Normal, + "Notifying main server of removal of serverClient for %s %s", + forwarder->getRobotName(), client->getIPString()); + + ArNetPacket sendPacket; + sendPacket.strToBuf(""); + sendPacket.uByte2ToBuf(forwarder->getPort()); + sendPacket.strToBuf(forwarder->getRobotName()); + sendPacket.strToBuf(""); + sendPacket.strToBuf( + forwarder->getClient()->getTcpSocket()->getIPString()); + myClientServer->broadcastPacketTcpToMatching(&sendPacket, "clientRemoved", + client->getIdentifier(), true); + myClientServer->broadcastPacketTcpToMatching(&sendPacket, "clientAdded", + client->getIdentifier(), true); +} + +AREXPORT void ArCentralManager::mainServerClientRemovedCallback( + ArServerClient *client) +{ + ArTypes::UByte4 idNum; + if ((idNum = client->getIdentifier().getConnectionID()) == 0) + return; + + myDataMutex.lock(); + myClosingConnectionID = idNum; + ArLog::log(ArLog::Normal, "ArCentralManager: Lost main connection to %s, closing robot connections to it", client->getIPString()); + std::list::iterator fIt; + ArCentralForwarder *forwarder; + for (fIt = myForwarders.begin(); fIt != myForwarders.end(); fIt++) + { + forwarder = (*fIt); + if (forwarder->getServer() != NULL) + forwarder->getServer()->closeConnectionID(myClosingConnectionID); + } + myClosingConnectionID = 0; + myDataMutex.unlock(); +} + + +void ArCentralManager::logConnections(void) +{ + int numServerClients = 0; + ArLog::log(ArLog::Normal, ""); + ArLog::log(ArLog::Normal, ""); + ArLog::log(ArLog::Normal, "Logging connection information:"); + ArLog::log(ArLog::Normal, "Main client server:"); + myClientServer->logConnections("\t"); + ArLog::log(ArLog::Normal, ""); + numServerClients += myClientServer->getNumClients(); + myDataMutex.lock(); + std::list::iterator fIt; + ArCentralForwarder *forwarder; + for (fIt = myForwarders.begin(); fIt != myForwarders.end(); fIt++) + { + forwarder = (*fIt); + if (forwarder->isConnected()) + { + ArLog::log(ArLog::Normal, "Forwarded connection to %s:", + forwarder->getRobotName()); + forwarder->getServer()->logConnections("\t"); + numServerClients += forwarder->getServer()->getNumClients(); + ArLog::log(ArLog::Normal, ""); + } + else + { + ArLog::log(ArLog::Normal, "Connecting forwarded connection to %s:", + forwarder->getRobotName()); + ArLog::log(ArLog::Normal, ""); + } + } + ArLog::log(ArLog::Normal, ""); + ArLog::log(ArLog::Normal, "Forwarders: %d now %d max", + myForwarders.size(), myMostForwarders); + ArLog::log(ArLog::Normal, "Clients: %d now %d max", + numServerClients, myMostClients); + ArLog::log(ArLog::Normal, ""); + ArLog::log(ArLog::Normal, ""); + myDataMutex.unlock(); + +} + +/// Enforces the that the server is using this protocol version +AREXPORT void ArCentralManager::enforceProtocolVersion(const char *protocolVersion) +{ + myDataMutex.lock(); + if (protocolVersion != NULL) + myEnforceProtocolVersion = protocolVersion; + else + myEnforceProtocolVersion = ""; + myDataMutex.unlock(); + ArLog::log(ArLog::Normal, "ArCentralManager: New enforceProtocolVersionSet"); + +} + +AREXPORT void ArCentralManager::enforceType(ArServerCommands::Type type) +{ + myDataMutex.lock(); + myEnforceType = type; + myDataMutex.unlock(); + ArLog::log(ArLog::Normal, "ArCentralManager: New enforce type: %s", + ArServerCommands::toString(type)); + +} diff --git a/Legacy/Aria/ArNetworking/src/ArClientArgUtils.cpp b/Legacy/Aria/ArNetworking/src/ArClientArgUtils.cpp new file mode 100644 index 0000000..d47550d --- /dev/null +++ b/Legacy/Aria/ArNetworking/src/ArClientArgUtils.cpp @@ -0,0 +1,702 @@ + +#include "Aria.h" +#include "ArExport.h" + +#include "ArClientArgUtils.h" + +#include + +#include "ArNetPacket.h" + +//#define ARDEBUG_CLIENTARGUTILS + +#if (defined(_DEBUG) && defined(ARDEBUG_CLIENTARGUTILS)) +#define IFDEBUG(code) {code;} +#else +#define IFDEBUG(code) +#endif + +AREXPORT ArClientArg::ArClientArg(bool isDisplayHintParsed, + ArPriority::Priority lastPriority, + int version) : + myIsDisplayHintParsed(isDisplayHintParsed), + myLastPriority(lastPriority), + myVersion(version), + myBuffer(), + myDisplayBuffer() +{} + +AREXPORT ArClientArg::~ArClientArg() +{} + +AREXPORT bool ArClientArg::isSendableParamType(const ArConfigArg &arg) +{ + switch (arg.getType()) { + case ArConfigArg::INT: + case ArConfigArg::DOUBLE: + case ArConfigArg::BOOL: + case ArConfigArg::LIST: + case ArConfigArg::STRING: + case ArConfigArg::SEPARATOR: + return true; + + default: + return false; + } +} + + +AREXPORT bool ArClientArg::createArg(ArNetPacket *packet, + ArConfigArg &argOut) +{ + if (packet == NULL) { + ArLog::log(ArLog::Verbose, "ArClientArg::createArg() cannot unpack NULL packet"); + return false; + } + + bool isSuccess = true; + + char name[32000]; + char description[32000]; + myDisplayBuffer[0] = '\0'; + + packet->bufToStr(name, sizeof(name)); + packet->bufToStr(description, sizeof(description)); + + + char priorityVal = packet->bufToByte(); + + ArPriority::Priority priority = myLastPriority; + if ((priorityVal >= 0) && (priorityVal <= myLastPriority)) { + priority = (ArPriority::Priority) priorityVal; + } + + char argType = packet->bufToByte(); + + switch (argType) { + + case 'B': + case 'b': // Lower case indicates display information contained in packet... + { + if ((argType == 'B') || (myIsDisplayHintParsed)) { + + bool boolVal = false; + if (packet->bufToByte()) { + boolVal = true; + } + //packet->bufToStr(myDisplayBuffer, BUFFER_LENGTH); + argOut = ArConfigArg(name, boolVal, description); + } + else { + isSuccess = false; + } + } + break; + + case 'I': + case 'i': // Lower case indicates display information contained in packet... + { + if ((argType == 'I') || (myIsDisplayHintParsed)) { + + int intVal = packet->bufToByte4(); + int intMin = packet->bufToByte4(); + int intMax = packet->bufToByte4(); + + argOut = ArConfigArg(name, intVal, description, intMin, intMax); + } + else { + isSuccess = false; + } + + } + break; + + case 'D': + case 'd': // Lower case indicates display information contained in packet... + { + if ((argType == 'D') || (myIsDisplayHintParsed)) { + double doubleVal = packet->bufToDouble(); + double doubleMin = packet->bufToDouble(); + double doubleMax = packet->bufToDouble(); + + if (myVersion >= 2) { + int precision = packet->bufToByte4(); + argOut = ArConfigArg(name, doubleVal, description, doubleMin, doubleMax, precision); + } + else { + argOut = ArConfigArg(name, doubleVal, description, doubleMin, doubleMax, -1); + } + } + else { + isSuccess = false; + } + } + break; + + case 'S': + case 's': // Lower case indicates display information contained in packet... + { + if ((argType == 'S') || (myIsDisplayHintParsed)) { + + packet->bufToStr(myBuffer, BUFFER_LENGTH); + + //packet->bufToStr(myDisplayBuffer, BUFFER_LENGTH); + argOut = ArConfigArg(name, myBuffer, description, 0); + } + else { + isSuccess = false; + } + } + break; + + case 'L': + case 'l': // Lower case indicates display information contained in packet... + { + + if ((argType == 'L') || (myIsDisplayHintParsed)) { + + int childCount = packet->bufToByte4(); + + ArConfigArg listArg(ArConfigArg::LIST, name, description); + ArConfigArg childArg; + + for (int i = 0; ((i < childCount) && (isSuccess)); i++) { + isSuccess = createArg(packet, + childArg); + if (isSuccess) { + listArg.addArg(childArg); + } + } + + if (isSuccess) { + argOut = listArg; + } + } + else { + isSuccess = false; + } + } + break; + + case '.': + { + //if (myIsDisplayHintParsed) { + //packet->bufToStr(myDisplayBuffer, BUFFER_LENGTH); + //} + argOut = ArConfigArg(ArConfigArg::SEPARATOR); + } + break; + + default: + + isSuccess = false; + ArLog::log(ArLog::Terse, "ArClientArg::createArg() unsupported param type %c", + argType); + } + + argOut.setConfigPriority(priority); + if (myIsDisplayHintParsed) { + + if (isSuccess) { + packet->bufToStr(myDisplayBuffer, BUFFER_LENGTH); + } + + IFDEBUG( + if (strlen(myDisplayBuffer) > 0) { + ArLog::log(ArLog::Verbose, "ArClientArg::createArg() arg %s has displayHint = %s", + argOut.getName(), myDisplayBuffer); + } + ); + + argOut.setDisplayHint(myDisplayBuffer); + } + + if (myVersion >= 2) { + if (isSuccess) { + packet->bufToStr(myExtraBuffer, BUFFER_LENGTH); + } + + IFDEBUG( + if (strlen(myExtraBuffer) > 0) { + ArLog::log(ArLog::Verbose, "ArClientArg::createArg() arg %s has extra explanation = %s", + argOut.getName(), myExtraBuffer); + } + ); + + argOut.setExtraExplanation(myExtraBuffer); + } // end if + + if (myVersion >= 2) { + char restartVal = packet->bufToByte(); + ArConfigArg::RestartLevel restart = ArConfigArg::NO_RESTART; + if ((restartVal >= 0) && (restartVal <= ArConfigArg::LAST_RESTART_LEVEL)) { + restart = (ArConfigArg::RestartLevel) restartVal; + argOut.setRestartLevel(restart); + } + } + + return isSuccess; + +} // end method createArg + + +AREXPORT bool ArClientArg::createPacket(const ArConfigArg &arg, + ArNetPacket *packet) +{ + if (packet == NULL) { + ArLog::log(ArLog::Verbose, + "ArClientArg::createPacket() cannot create NULL packet"); + return false; + } + + bool isSuccess = true; + + packet->strToBuf(arg.getName()); + packet->strToBuf(arg.getDescription()); + + ArPriority::Priority priority = arg.getConfigPriority(); + if (priority > myLastPriority) { + priority = myLastPriority; + } + + packet->byteToBuf(priority); + + char argType = '\0'; + + switch (arg.getType()) { + case ArConfigArg::BOOL: + + argType = (myIsDisplayHintParsed ? 'b' : 'B'); + + packet->byteToBuf(argType); + packet->byteToBuf(arg.getBool()); + break; + + case ArConfigArg::INT: + + argType = (myIsDisplayHintParsed ? 'i' : 'I'); + packet->byteToBuf(argType); + + packet->byte4ToBuf(arg.getInt()); + packet->byte4ToBuf(arg.getMinInt()); + packet->byte4ToBuf(arg.getMaxInt()); + + break; + + case ArConfigArg::DOUBLE: + + argType = (myIsDisplayHintParsed ? 'd' : 'D'); + packet->byteToBuf(argType); + + packet->doubleToBuf(arg.getDouble()); + packet->doubleToBuf(arg.getMinDouble()); + packet->doubleToBuf(arg.getMaxDouble()); + if (myVersion >= 2) { + packet->byte4ToBuf(arg.getDoublePrecision()); + } + break; + + case ArConfigArg::STRING: + + argType = (myIsDisplayHintParsed ? 's' : 'S'); + packet->byteToBuf(argType); + + packet->strToBuf(arg.getString()); + + break; + + case ArConfigArg::LIST: + { + argType = (myIsDisplayHintParsed ? 'l' : 'L'); + packet->byteToBuf(argType); + + + + std::list childList = arg.getArgs(); + + int sendableCount = 0; + + for (std::list::const_iterator iter1 = childList.begin(); + iter1 != childList.end(); + iter1++) { + if (isSendableParamType(*iter1)) { + sendableCount++; + } + } + + packet->byte4ToBuf(sendableCount); + + for (std::list::const_iterator iter2 = childList.begin(); + ((iter2 != childList.end()) && (isSuccess)); + iter2++) { + if (isSendableParamType(*iter2)) { + if (!createPacket(*iter2, packet)) { + isSuccess = false; + } + } + } // end for each child + } + break; + + case ArConfigArg::SEPARATOR: + + argType = '.'; + packet->byteToBuf(argType); + break; + + default: + + isSuccess = false; + ArLog::log(ArLog::Terse, + "ArClientArg::createPacket() unsupported param type %s", + ArConfigArg::toString(arg.getType())); + + } // end switch type + + if (isSuccess && myIsDisplayHintParsed) { + packet->strToBuf(arg.getDisplayHint()); + } + if (isSuccess && (myVersion >= 2)) { + packet->strToBuf(arg.getExtraExplanation()); + } + if (isSuccess && (myVersion >= 2)) { + packet->byteToBuf(arg.getRestartLevel()); + } + + return isSuccess; + +} // end method createPacket + + + +AREXPORT bool ArClientArg::bufToArgValue(ArNetPacket *packet, + ArConfigArg &arg) +{ + if (packet == NULL) { + return false; + } + + bool isSuccess = true; + + switch (arg.getType()) { + case ArConfigArg::BOOL: + { + bool boolVal = false; + if (packet->bufToByte()) { + boolVal = true; + } + isSuccess = arg.setBool(boolVal); + } + break; + + case ArConfigArg::INT: + { + int intVal = packet->bufToByte4(); + isSuccess = arg.setInt(intVal); + } + break; + + case ArConfigArg::DOUBLE: + { + double doubleVal = packet->bufToDouble(); + isSuccess = arg.setDouble(doubleVal); + } + break; + + case ArConfigArg::STRING: + { + packet->bufToStr(myBuffer, BUFFER_LENGTH); + isSuccess = arg.setString(myBuffer); + } + break; + + case ArConfigArg::LIST: + { + int childCount = packet->bufToByte4(); + + if (childCount > 0) { + + int copiedCount = 0; + + for (size_t c = 0; ((isSuccess) && (c < arg.getArgCount())); c++) { + + ArConfigArg *childArg = arg.getArg(c); + if (childArg == NULL) { + isSuccess = false; + break; + } + if (!isSendableParamType(*childArg)) { + continue; + } + isSuccess = bufToArgValue(packet, + *childArg); + copiedCount++; + + } // end for each arg + + if (copiedCount != childCount) { + ArLog::log(ArLog::Normal, + "Error reading list values, received %i children, copied %i", + childCount, copiedCount); + } + + } // end if children + + } + break; + case ArConfigArg::SEPARATOR: + // There is no value... + break; + + default: + + isSuccess = false; + ArLog::log(ArLog::Terse, "ArClientArg::createPacket() unsupported param type %i", arg.getType()); + + } // end switch type + + return isSuccess; + +} // end method bufToArgValue + + + +AREXPORT bool ArClientArg::argValueToBuf(const ArConfigArg &arg, + ArNetPacket *packet) +{ + if (packet == NULL) { + return false; + } + + bool isSuccess = true; + + switch (arg.getType()) { + case ArConfigArg::BOOL: + + packet->byteToBuf(arg.getBool()); + break; + + case ArConfigArg::INT: + + packet->byte4ToBuf(arg.getInt()); + break; + + case ArConfigArg::DOUBLE: + + packet->doubleToBuf(arg.getDouble()); + break; + + case ArConfigArg::STRING: + + packet->strToBuf(arg.getString()); + break; + + case ArConfigArg::LIST: + { +/**** + packet->byte4ToBuf(arg.getArgCount()); + + std::list childList = arg.getArgs(); + for (std::list::const_iterator iter = childList.begin(); + ((isSuccess) && (iter != childList.end())); + iter++) { + isSuccess = argValueToBuf(*iter, + packet); + } +*****/ + + std::list childList = arg.getArgs(); + + int sendableCount = 0; + + for (std::list::const_iterator iter1 = childList.begin(); + iter1 != childList.end(); + iter1++) { + if (isSendableParamType(*iter1)) { + sendableCount++; + } + } + + packet->byte4ToBuf(sendableCount); + + for (std::list::const_iterator iter2 = childList.begin(); + ((iter2 != childList.end()) && (isSuccess)); + iter2++) { + if (isSendableParamType(*iter2)) { + isSuccess = argValueToBuf(*iter2, + packet); + // if (!createPacket(*iter2, packet)) { + // isSuccess = false; + // } + } + } // end for each child + } + break; + + case ArConfigArg::SEPARATOR: + // There is no value... + break; + + default: + + isSuccess = false; + ArLog::log(ArLog::Terse, "ArClientArg::createPacket() unsupported param type %i", arg.getType()); + + } // end switch type + + return isSuccess; + +} // end method argValueToBuf + + +AREXPORT bool ArClientArg::argTextToBuf(const ArConfigArg &arg, + ArNetPacket *packet) +{ + if (packet == NULL) { + return false; + } + + bool isSuccess = true; + + switch (arg.getType()) { + case ArConfigArg::INT: + snprintf(myBuffer, BUFFER_LENGTH, "%d", arg.getInt()); + break; + case ArConfigArg::DOUBLE: + snprintf(myBuffer, BUFFER_LENGTH, "%g", arg.getDouble()); + break; + case ArConfigArg::BOOL: + snprintf(myBuffer, BUFFER_LENGTH, "%s", + ArUtil::convertBool(arg.getBool())); + break; + + case ArConfigArg::STRING: + snprintf(myBuffer, BUFFER_LENGTH, "%s", arg.getString()); + break; + + case ArConfigArg::LIST: + { + + ArLog::log(ArLog::Terse, + "UNSUPPORTED METHOD ArClientArg::argTextToBuf (LIST)"); + + std::list childList = arg.getArgs(); + + for (std::list::const_iterator iter2 = childList.begin(); + ((iter2 != childList.end()) && (isSuccess)); + iter2++) { + if (isSendableParamType(*iter2)) { + + packet->strToBuf((*iter2).getName()); + + isSuccess = ArClientArg::addArgTextToPacket(*iter2, + packet); + } + } // end for each child + + + int sendableCount = 0; + + // for (std::list::const_iterator iter1 = childList.begin(); +// iter1 != childList.end(); +// iter1++) { +// if (isSendableParamType(*iter1)) { +// sendableCount++; +// } +// } + +// snprintf(myBuffer, BUFFER_LENGTH, "%d", sendableCount); + + } + break; + case ArConfigArg::SEPARATOR: + break; + default: + isSuccess = false; + break; + } // end switch type + + if (isSuccess) { + packet->strToBuf(myBuffer); + } + return isSuccess; + +} // end method argTextToBuf + +AREXPORT bool ArClientArg::addArgTextToPacket(const ArConfigArg &arg, + ArNetPacket *packet) +{ + if (packet == NULL) { + return false; + } + + bool isSuccess = true; + + switch (arg.getType()) { + case ArConfigArg::INT: + packet->strToBuf(arg.getName()); + snprintf(myBuffer, BUFFER_LENGTH, "%d", arg.getInt()); + packet->strToBuf(myBuffer); + break; + case ArConfigArg::DOUBLE: + packet->strToBuf(arg.getName()); + snprintf(myBuffer, BUFFER_LENGTH, "%g", arg.getDouble()); + packet->strToBuf(myBuffer); + break; + case ArConfigArg::BOOL: + packet->strToBuf(arg.getName()); + snprintf(myBuffer, BUFFER_LENGTH, "%s", + ArUtil::convertBool(arg.getBool())); + packet->strToBuf(myBuffer); + break; + + case ArConfigArg::STRING: + packet->strToBuf(arg.getName()); + snprintf(myBuffer, BUFFER_LENGTH, "%s", arg.getString()); + packet->strToBuf(myBuffer); + break; + + case ArConfigArg::LIST: + { + /* snprintf(myBuffer, BUFFER_LENGTH, "%s %s", + ArConfigArg::LIST_BEGIN_TAG, + arg.getName());*/ + + packet->strToBuf(ArConfigArg::LIST_BEGIN_TAG); + packet->strToBuf(arg.getName()); + + std::list childList = arg.getArgs(); + + for (std::list::const_iterator iter2 = childList.begin(); + ((iter2 != childList.end()) && (isSuccess)); + iter2++) { + if (isSendableParamType(*iter2)) { + + // packet->strToBuf((*iter2).getName()); + + isSuccess = ArClientArg::addArgTextToPacket(*iter2, + packet); + } + } // end for each child + + //snprintf(myBuffer, BUFFER_LENGTH, "%s %s", + // ArConfigArg::LIST_END_TAG, + // arg.getName()); + //packet->strToBuf(myBuffer); + + packet->strToBuf(ArConfigArg::LIST_END_TAG); + packet->strToBuf(arg.getName()); + + } + break; + case ArConfigArg::SEPARATOR: + break; + default: + isSuccess = false; + break; + } // end switch type + + return isSuccess; + +} // end method addArgTextToPacket + diff --git a/Legacy/Aria/ArNetworking/src/ArClientBase.cpp b/Legacy/Aria/ArNetworking/src/ArClientBase.cpp new file mode 100644 index 0000000..d04195a --- /dev/null +++ b/Legacy/Aria/ArNetworking/src/ArClientBase.cpp @@ -0,0 +1,2332 @@ + +#include "Aria.h" +#include "ArExport.h" +#include "ArClientBase.h" +#include "ArServerCommands.h" +#include "ArClientCommands.h" +#include "md5.h" + +//#define ARDEBUG_CLIENTBASE + +#if (defined(_DEBUG) && defined(ARDEBUG_CLIENTBASE)) +#define IFDEBUG(code) {code;} +#else +#define IFDEBUG(code) +#endif + +AREXPORT ArClientBase::ArClientBase() : + myLogPrefix(""), + myProcessPacketCB(this, &ArClientBase::processPacket, NULL, true), + myProcessPacketUdpCB(this, &ArClientBase::processPacketUdp) + +{ + myDataMutex.setLogName("ArClientBase::myDataMutex"); + myClientMutex.setLogName("ArClientBase::myClientMutex"); + myMapsMutex.setLogName("ArClientBase::myMapsMutex"); + myStateMutex.setLogName("ArClientBase::myStateMutex"); + myCallbackMutex.setLogName("ArClientBase::myCallbackMutex"); + myCycleCallbackMutex.setLogName("ArClientBase::myCycleCallbackMutex"); + myPacketTrackingMutex.setLogName("ArClientBase::myPacketTrackingMutex"); + + setRobotName("ArClientBase"); + setThreadName("ArClientBase"); + myTcpSender.setSocket(&myTcpSocket); + myTcpReceiver.setSocket(&myTcpSocket); + myTcpReceiver.setProcessPacketCB(&myProcessPacketCB); + myUdpReceiver.setSocket(&myUdpSocket); + myUdpReceiver.setProcessPacketCB(&myProcessPacketUdpCB); + + myDebugLogging = false; + myVerboseLogLevel = ArLog::Verbose; + myEnforceType = ArServerCommands::TYPE_UNSPECIFIED; + + myNonBlockingConnectState = NON_BLOCKING_STATE_NONE; + clear(); + + myTcpSender.setDebugLogging(myDebugLogging); +} + +AREXPORT ArClientBase::~ArClientBase() +{ + clear(); +} + +/** + * The robot name is used solely for log messages. + * @param name an optional char * name of the connected robot to be used in + * the log messages + * @param debugLogging a bool set to true if log messages should be written + * at the Normal level, if false, then they are written as Verbose + * @param robotId an optional int which can be appended to the robot name + * in the log messages; if 0, then only the robot name is logged +**/ +AREXPORT void ArClientBase::setRobotName(const char *name, + bool debugLogging, + int robotId) +{ + myDebugLogging = debugLogging; + myRobotName = ((name != NULL) ? name : ""); + + if (myDebugLogging) + myVerboseLogLevel = ArLog::Normal; + else + myVerboseLogLevel = ArLog::Verbose; + + myLogPrefix = ""; + if (!myRobotName.empty() && (robotId != 0)) { + char buf[512]; + snprintf(buf, sizeof(buf), + "%s[%i]: ", myRobotName.c_str(), robotId); + myLogPrefix = buf; + } + if (!myRobotName.empty() && (robotId == 0)) { + myLogPrefix = myRobotName + ": "; + } + myTcpSender.setLoggingPrefix(myLogPrefix.c_str()); + myTcpReceiver.setLoggingPrefix(myLogPrefix.c_str()); +} + +AREXPORT const char *ArClientBase::getRobotName() const +{ + return myRobotName.c_str(); +} + +AREXPORT const char *ArClientBase::getLogPrefix() const +{ + return myLogPrefix.c_str(); +} + +AREXPORT bool ArClientBase::getDebugLogging(void) +{ + return myDebugLogging; +} + + +void ArClientBase::clear(void) +{ + internalSwitchState(STATE_NO_CONNECTION); + + myServerReportedUdpPort = 0; + myUdpConfirmedFrom = false; + myUdpConfirmedTo = false; + myTcpOnlyTo = false; + myTcpOnlyFrom = false; + myTimeoutTime = 10; + myQuiet = false; + myLastPacketReceived.setToNow(); + + myIsRunningAsync = false; + myDisconnectSoon = false; + myIsStartedDisconnect = false; + myIsStopped = false; + + myRejected = 0; + myRejectedString[0] = '\0'; + + myReceivedDataList = false; + myReceivedArgRetList = false; + myReceivedGroupAndFlagsList = false; + + //resetTracking(); + + myNameIntMap.clear(); + ArUtil::deleteSetPairs(myIntDataMap.begin(), myIntDataMap.end()); + myIntDataMap.clear(); + + /// MPL adding this since these look leaked + ArUtil::deleteSetPairs(myTrackingSentMap.begin(), + myTrackingSentMap.end()); + myTrackingSentMap.clear(); + + ArUtil::deleteSetPairs(myTrackingReceivedMap.begin(), + myTrackingReceivedMap.end()); + myTrackingReceivedMap.clear(); + +} + +/** + cycleCallbacks are called every cycle, and are in no particular + order, since all they should do is send packets, never any + processing + + You cannot add a cycle callback from within a cycle or it will deadlock + @param functor callback to add + +**/ +AREXPORT void ArClientBase::addCycleCallback(ArFunctor *functor) +{ + myCycleCallbackMutex.lock(); + myCycleCallbacks.push_front(functor); + myCycleCallbackMutex.unlock(); +} + +/** + cycleCallbacks are called every cycle, and are in no particular + order, since all they should do is send packets, never any + processing + You cannot remove a cycle callback from within a cycle or it will deadlock + @param functor callback to remove +**/ +AREXPORT void ArClientBase::remCycleCallback(ArFunctor *functor) +{ + myCycleCallbackMutex.lock(); + myCycleCallbacks.remove(functor); + myCycleCallbackMutex.unlock(); +} + + +/** + @param sec This value controls how long the client will give to + connect, it is the argument in number of seconds... if <= 0 then no + timeout will take place. +**/ +AREXPORT void ArClientBase::setConnectTimeoutTime(int sec) +{ + myDataMutex.lock(); + if (sec < 0) + myTimeoutTime = 0; + else + myTimeoutTime = sec; + myDataMutex.unlock(); +} + +/** + @return This value controls how long the client will give to + connect, it is the argument in number of seconds... if <= 0 then no + timeout will take place. +**/ +AREXPORT int ArClientBase::getConnectTimeoutTime(void) +{ + return myTimeoutTime; +} + +/** + @param host the host to connect to + + @param port the port to connect on + + @param log whether to log our connection information using ArLog or not. + Keeping the default value of true is recommended (disabling logging + is usually only for internal and unusual uses). + This setting also applies to logging disconnections and some other I/O events + as well. + + @param user user name, or NULL for none. + @param password password (cleartext), or NULL for none. + @param openOnIP address of the local network interface to use for the outgoing connection, or NULL for any/all. + **/ +AREXPORT bool ArClientBase::blockingConnect(const char *host, int port, + bool log, const char *user, + const char *password, + const char *openOnIP) +{ + return internalBlockingConnect(host, port, log, user, password, NULL, + openOnIP); +} + +AREXPORT bool ArClientBase::internalBlockingConnect( + const char *host, int port, bool log, const char *user, + const char *password, ArSocket *tcpSocket, const char *openOnIP) +{ + NonBlockingConnectReturn ret; + + if ((ret = internalNonBlockingConnectStart( + host, port, log, user, password, tcpSocket, openOnIP)) != + NON_BLOCKING_CONTINUE) + return false; + + while ((ret = internalNonBlockingConnectContinue()) == NON_BLOCKING_CONTINUE) + ArUtil::sleep(1); + + if (ret == NON_BLOCKING_CONNECTED) + return true; + else + return false; +} + +AREXPORT ArClientBase::NonBlockingConnectReturn +ArClientBase::internalNonBlockingConnectStart( + const char *host, int port, bool log, const char *user, + const char *password, ArSocket *tcpSocket, const char *openOnIP) +{ + ArNetPacket packet; + + myDataMutex.lock(); + if (myState == STATE_LOST_CONNECTION) + { + ArLog::log(ArLog::Normal, + "%sTrying a connection on a client that'd lost connection.", + myLogPrefix.c_str()); + clear(); + } + + myDataMutex.unlock(); + + if (myState != STATE_NO_CONNECTION && + myState != STATE_FAILED_CONNECTION && + myState != STATE_REJECTED) + { + if (!myQuiet || myDebugLogging) + ArLog::log(ArLog::Terse, + "%sConnection already established or being connected.", + myLogPrefix.c_str()); + return NON_BLOCKING_FAILED; + } + + if (myDebugLogging) + ArLog::log(ArLog::Normal, "%s0", myLogPrefix.c_str()); + myDataMutex.lock(); + // MPL added this here since the no connection state is gotten to by + // a normal disconnect, and won't have had its data cleared + clear(); + myStartedConnection.setToNow(); + + myHost = host; + myQuiet = !log; + myTcpReceiver.setQuiet(myQuiet); + if (user != NULL) + myUser = user; + else + myUser = ""; + if (password != NULL) + myPassword = password; + else + myPassword = ""; + + myDataMutex.unlock(); + if (tcpSocket != NULL) + { + myDataMutex.lock(); + myTcpSocket.transfer(tcpSocket); + internalStartUdp(); + myDataMutex.unlock(); + internalSwitchState(STATE_OPENED_SOCKET); + + } + else + { + if (myDebugLogging) + ArLog::log(ArLog::Normal, "%s1", myLogPrefix.c_str()); + loopOnce(); + if (myDebugLogging) + ArLog::log(ArLog::Normal, "%s1.1", myLogPrefix.c_str()); + myDataMutex.lock(); + if (myDebugLogging) + ArLog::log(ArLog::Normal, "%s1.2", myLogPrefix.c_str()); + if (internalConnect(host, port, log, openOnIP)) + { + myDataMutex.unlock(); + if (myDebugLogging) + ArLog::log(ArLog::Normal, "%s2", myLogPrefix.c_str()); + //break; + } + else + { + myTcpSocket.close(); + myUdpSocket.close(); + internalSwitchState(STATE_FAILED_CONNECTION); + myDataMutex.unlock(); + if (myDebugLogging) + ArLog::log(ArLog::Normal, "%s3", myLogPrefix.c_str()); + + return NON_BLOCKING_FAILED; + } + //} + } + myNonBlockingConnectState = NON_BLOCKING_STATE_TCP; + return NON_BLOCKING_CONTINUE; +} + + +AREXPORT ArClientBase::NonBlockingConnectReturn +ArClientBase::internalNonBlockingConnectContinue(void) +{ + ArNetPacket packet; + + if (myNonBlockingConnectState == NON_BLOCKING_STATE_TCP) + { + if (myDebugLogging) + ArLog::log(ArLog::Normal, "%s5", myLogPrefix.c_str()); + loopOnce(); + + if (myState == STATE_REJECTED || myState == STATE_NO_CONNECTION || + myState == STATE_LOST_CONNECTION) + { + myTcpSocket.close(); + myUdpSocket.close(); + myNonBlockingConnectState = NON_BLOCKING_STATE_NONE; + return NON_BLOCKING_FAILED; + } + if (myState == STATE_CONNECTED) + { + myStartedUdpConnection.setToNow(); + myNonBlockingConnectState = NON_BLOCKING_STATE_UDP; + return internalNonBlockingConnectContinue(); + } + + if (myDebugLogging) + ArLog::log(ArLog::Normal, "%s6 (%d)", myLogPrefix.c_str(), myState); + if (myTimeoutTime > 0 && + myStartedConnection.mSecSince() > myTimeoutTime * 1000.0) + { + if (myDebugLogging) + ArLog::log(ArLog::Normal, "%s7", myLogPrefix.c_str()); + if (!myQuiet || myDebugLogging) + ArLog::log(ArLog::Terse, + "%sConnection timed out.", myLogPrefix.c_str()); + internalSwitchState(STATE_FAILED_CONNECTION); + //myState = STATE_NO_CONNECTION; + myTcpSocket.close(); + myUdpSocket.close(); + myNonBlockingConnectState = NON_BLOCKING_STATE_NONE; + return NON_BLOCKING_FAILED; + } + return NON_BLOCKING_CONTINUE; + } + else if (myNonBlockingConnectState == NON_BLOCKING_STATE_UDP) + { + if (myDebugLogging) + ArLog::log(ArLog::Normal, "%s8", myLogPrefix.c_str()); + loopOnce(); + + if (myState != STATE_CONNECTED) + { + if (myDebugLogging) + ArLog::log(ArLog::Normal, "%s9", myLogPrefix.c_str()); + myTcpSocket.close(); + myUdpSocket.close(); + myNonBlockingConnectState = NON_BLOCKING_STATE_NONE; + return NON_BLOCKING_FAILED; + } + + if ((myUdpConfirmedFrom || myTcpOnlyFrom) && + (myUdpConfirmedTo || myTcpOnlyTo)) + { + if (myDebugLogging) + ArLog::log(ArLog::Normal, "%s10", myLogPrefix.c_str()); + myNonBlockingConnectState = NON_BLOCKING_STATE_NONE; + return NON_BLOCKING_CONNECTED; + } + + if (myDebugLogging) + ArLog::log(ArLog::Normal, "%s11", myLogPrefix.c_str()); + // see if we didn't get udp from + if (myStartedUdpConnection.mSecSince() > myTimeoutTime * .66 * 1000.0 && + !myUdpConfirmedFrom && !myTcpOnlyFrom) + { + packet.empty(); + packet.setCommand(ArClientCommands::TCP_ONLY); + sendPacketTcp(&packet); + myDataMutex.lock(); + myTcpOnlyFrom = true; + myDataMutex.unlock(); + if (!myQuiet || myDebugLogging) + ArLog::log(ArLog::Normal, + "%sDidn't get confirmation of UDP from server, switching to TCP.", + myLogPrefix.c_str()); + } + // see if we haven't confirmed udp to + if (myStartedUdpConnection.mSecSince() > myTimeoutTime * .66 * 1000.0 && + !myUdpConfirmedTo && !myTcpOnlyTo) + { + packet.empty(); + myDataMutex.lock(); + myTcpOnlyTo = true; + myDataMutex.unlock(); + if (!myQuiet || myDebugLogging) + ArLog::log(ArLog::Normal, + "%sDidn't get confirmation of UDP to server, switching to TCP.", + myLogPrefix.c_str()); + } + if (myTimeoutTime > 0 && + myStartedUdpConnection.mSecSince() > myTimeoutTime * 1000.0) + { + if (!myQuiet || myDebugLogging) + ArLog::log(ArLog::Terse, "%sConnection timed out (2).", + myLogPrefix.c_str()); + ArLog::log( + myVerboseLogLevel, "%sTimeout %d startedMSecSince %d startedUdpWaitMSecSince %d udpFrom %d udpTo %d tcpOnlyFrom %d tcpOnlyTo %d", + myLogPrefix.c_str(), + myTimeoutTime, myStartedConnection.mSecSince(), + myStartedUdpConnection.mSecSince(), myUdpConfirmedFrom, + myUdpConfirmedTo, myTcpOnlyFrom, myTcpOnlyTo); + //myState = STATE_NO_CONNECTION; + internalSwitchState(STATE_FAILED_CONNECTION); + } + return NON_BLOCKING_CONTINUE; + } + else if (myNonBlockingConnectState == NON_BLOCKING_STATE_NONE) + { + ArLog::log(ArLog::Normal, "Non blocking connect called when it wasn't started"); + return NON_BLOCKING_FAILED; + } + else + { + ArLog::log(ArLog::Normal, "Non blocking connect called when in unknown state"); + return NON_BLOCKING_FAILED; + } +} + +bool ArClientBase::internalConnect(const char *host, int port, bool obsolete, + const char *openOnIP) +{ + if (myDebugLogging) + ArLog::log(ArLog::Normal, "%sa", myLogPrefix.c_str()); + // if we connect tcp then connect up the udp + if (myTcpSocket.connect(host, port, ArSocket::TCP, openOnIP)) + { + if (myDebugLogging) + ArLog::log(ArLog::Normal, "%sb", myLogPrefix.c_str()); + if (!myTcpSocket.setNonBlock()) + { + ArLog::log(ArLog::Terse, + "%sFailed to set TCP socket nonblock, could not connect", + myLogPrefix.c_str()); + return false; + } + if (myDebugLogging) + ArLog::log(ArLog::Normal, "%sc", myLogPrefix.c_str()); + internalStartUdp(); + if (myDebugLogging) + ArLog::log(ArLog::Normal, "%sd", myLogPrefix.c_str()); + if (!myQuiet || myDebugLogging) + ArLog::log(myVerboseLogLevel, + "%sOpened client connection to %s on tcp port %d with my udp port of %d", + myLogPrefix.c_str(), host, port, myUdpPort); + // we can't tell if udp connected or not (because its udp) so just + // say we're good + internalSwitchState(STATE_OPENED_SOCKET); + if (myDebugLogging) + ArLog::log(ArLog::Normal, "%se", myLogPrefix.c_str()); + return true; + } + else + { + if (!myQuiet || myDebugLogging) + ArLog::log(ArLog::Terse, + "%sconnect: Failed to open TCP socket", + myLogPrefix.c_str()); + internalSwitchState(STATE_FAILED_CONNECTION); + return false; + } +} + +void ArClientBase::internalStartUdp(void) +{ + // fire up the udp + if (!myUdpSocket.create(ArSocket::UDP) || + !myUdpSocket.findValidPort(10000) || + !myUdpSocket.setNonBlock()) + { + myUdpSocket.setLinger(0); + if (!myQuiet || myDebugLogging) + ArLog::log(ArLog::Terse, + "%sconnect: Failed to open udp socket, forcing TCP", + myLogPrefix.c_str()); + //internalSwitchState(STATE_FAILED_CONNECTION); + //return false; + myTcpOnlyTo = true; + myTcpOnlyFrom = true; + } + myUdpSinValid = false; + myUdpSin.sin_family=AF_INET; + myUdpSin.sin_addr = *myTcpSocket.inAddr(); + myUdpPort = myUdpSocket.netToHostOrder(myUdpSocket.inPort()); +} + +AREXPORT void ArClientBase::disconnectSoon(void) +{ + myDisconnectSoon = true; +} + +AREXPORT bool ArClientBase::disconnect(void) +{ + bool ret = startNonBlockingDisconnect(); + + ArUtil::sleep(10); + + finishNonBlockingDisconnect(); + + return ret; +} + +AREXPORT bool ArClientBase::startNonBlockingDisconnect() +{ + if (!myQuiet || myDebugLogging) + ArLog::log(ArLog::Normal, "%sDisconnected from server.", + myLogPrefix.c_str()); + + bool ret = false; + ArNetPacket packet; + + packet.setCommand(ArClientCommands::SHUTDOWN); + ret = sendPacketTcp(&packet); + myTcpSender.sendData(); + + return ret; +} + +AREXPORT void ArClientBase::finishNonBlockingDisconnect() +{ + myTcpSocket.close(); + myUdpSocket.close(); + myState = STATE_NO_CONNECTION; +} + + + +AREXPORT bool ArClientBase::setupPacket(ArNetPacket *packet) +{ + if (myState == STATE_NO_CONNECTION || myState == STATE_FAILED_CONNECTION || + myState == STATE_LOST_CONNECTION || myState == STATE_REJECTED) + return false; + + if (packet->getLength() > ArNetPacket::MAX_LENGTH) + { + ArLog::log(ArLog::Terse, + "%s: setupPacket packet for command %s packet is bad at %d", + myLogPrefix.c_str(), getName(packet->getCommand()), + packet->getLength()); + return false; + } + + packet->finalizePacket(); + return true; +} + +AREXPORT bool ArClientBase::sendPacketTcp(ArNetPacket *packet) +{ + if (!setupPacket(packet)) + { + return false; + } + else + { + trackPacketSent(packet, true); + myTcpSender.sendPacket(packet, myLogPrefix.c_str()); + return true; + } +} + +AREXPORT bool ArClientBase::sendPacketUdp(ArNetPacket *packet) +{ + if (!setupPacket(packet)) + { + return false; + } + else + { + trackPacketSent(packet, false); + if (myUdpSocket.sendTo(packet->getBuf(), packet->getLength(), &myUdpSin) + == packet->getLength()) + { + return true; + } + else + { + return false; + } + } +} + +AREXPORT void ArClientBase::loopOnce(void) +{ + std::list::iterator it; + if (myState != STATE_NO_CONNECTION && myState != STATE_FAILED_CONNECTION && + myState != STATE_LOST_CONNECTION && myState != STATE_REJECTED) + { + if (myDisconnectSoon) + { + if (myIsRunningAsync) { + startNonBlockingDisconnect(); + + ArUtil::sleep(100); + + finishNonBlockingDisconnect(); + } + else { + if (!myIsStartedDisconnect) { + + myIsStartedDisconnect = true; + myStartedShutdown.setToNow(); + startNonBlockingDisconnect(); + } + else if (myStartedShutdown.mSecSince() > 100) { + finishNonBlockingDisconnect(); + } + } + return; + } + // if we couldn't receive tcp data fail + if (!myTcpReceiver.readData()) + { + if (!myQuiet || myDebugLogging) + ArLog::log(ArLog::Normal, + "%sLost connection to server (couldn't recv).", + myLogPrefix.c_str()); + myTcpSocket.close(); + myUdpSocket.close(); + internalSwitchState(STATE_LOST_CONNECTION); + stopRunning(); + myCallbackMutex.lock(); + for (it = myDisconnectOnErrorCBList.begin(); + it != myDisconnectOnErrorCBList.end(); + ++it) + (*it)->invoke(); + myCallbackMutex.unlock(); + + } + // if we can't receive UDP just make an error log + else if (!myTcpOnlyFrom && !myUdpReceiver.readData()) + { + if (!myQuiet || myDebugLogging) + ArLog::log(ArLog::Normal, "%sUDP Troubles, continuing", + myLogPrefix.c_str()); + } + if (!myTcpSender.sendData()) + { + if (!myQuiet || myDebugLogging) + ArLog::log(ArLog::Normal, + "%sLost connection to server (couldn't send).", + myLogPrefix.c_str()); + myTcpSocket.close(); + myUdpSocket.close(); + internalSwitchState(STATE_LOST_CONNECTION); + stopRunning(); + myCallbackMutex.lock(); + for (it = myDisconnectOnErrorCBList.begin(); + it != myDisconnectOnErrorCBList.end(); + ++it) + (*it)->invoke(); + myCallbackMutex.unlock(); + } + } + myCycleCallbackMutex.lock(); + for (it = myCycleCallbacks.begin(); it != myCycleCallbacks.end(); ++it) + (*it)->invoke(); + myCycleCallbackMutex.unlock(); + +} + +AREXPORT void ArClientBase::run(void) +{ + runInThisThread(); +} + +AREXPORT void ArClientBase::runAsync(void) +{ + myIsRunningAsync = true; + create(true, false); +} + +AREXPORT void *ArClientBase::runThread(void *arg) +{ + threadStarted(); + while (myRunning) + { + loopOnce(); + ArUtil::sleep(1); + } + threadFinished(); + return NULL; +} + +AREXPORT void ArClientBase::stopRunning(void) +{ + ArASyncTask::stopRunning(); + myIsStopped = true; +} + +AREXPORT bool ArClientBase::isStopped() +{ + return myIsStopped; +} + + +AREXPORT void ArClientBase::processPacket(ArNetPacket *packet, bool tcp) +{ + ArNetPacket retPacket; + std::list::iterator it; + + myDataMutex.lock(); + myLastPacketReceived.setToNow(); + myDataMutex.unlock(); + + if (myDebugLogging && packet->getCommand() <= 255) + { + ArLog::log(ArLog::Normal, "%sGot command %d", + myLogPrefix.c_str(), packet->getCommand()); + } + + // See if we should close our connection + if (packet->getCommand() == ArServerCommands::SHUTDOWN) + { + if (!myQuiet || myDebugLogging) + ArLog::log(ArLog::Normal, + "%sServer shutting down and closed connection.", + myLogPrefix.c_str()); + stopRunning(); + disconnect(); + internalSwitchState(STATE_LOST_CONNECTION); + + myCallbackMutex.lock(); + for (it = myServerShutdownCBList.begin(); + it != myServerShutdownCBList.end(); + ++it) + (*it)->invoke(); + myCallbackMutex.unlock(); + } + else if (myState == STATE_CONNECTED) { + + // Some of the following cases are duplicated in the remainder of the + // if-else-if stmt below. (These are mostly error conditions.) This + // is a result of moving the connected state to the top of the big long + // if-else-if stmt since it is the most common scenario. Should probably + // re-examine the redundancies and improve their handling someday.... + switch (packet->getCommand()) { + case ArServerCommands::INTRODUCTION: + { + if (!myQuiet || myDebugLogging) + ArLog::log(ArLog::Terse, + "%sIntroduction received when not in STATE_OPENED_SOCKET", + myLogPrefix.c_str()); + return; + } + case ArServerCommands::CONNECTED: + { + ArLog::log(ArLog::Terse, + "%sConnected packet received not during STATE_EXCHANGED_INTROS", + myLogPrefix.c_str()); + return; + } + case ArServerCommands::REJECTED: + { + ArLog::log(ArLog::Terse, + "%sRejected packet received after connected", + myLogPrefix.c_str()); + return; + } + + case ArServerCommands::LIST: + case ArServerCommands::LISTSINGLE: + case ArServerCommands::LISTARGRET: + case ArServerCommands::LISTARGRETSINGLE: + case ArServerCommands::LISTGROUPANDFLAGS: + case ArServerCommands::LISTGROUPANDFLAGSSINGLE: + { + myMapsMutex.lock(); + buildList(packet); + myMapsMutex.unlock(); + return; + } + case ArServerCommands::UDP_CONFIRMATION: + { + if (!myQuiet || myDebugLogging) + ArLog::log(myVerboseLogLevel, + "%sClients udp connection to server confirmed.", + myLogPrefix.c_str()); + myDataMutex.lock(); + myUdpConfirmedTo = true; + myDataMutex.unlock(); + return; + } + case ArServerCommands::UDP_INTRODUCTION: + { + ArLog::log(ArLog::Terse, + "%sClient got udp introduction over tcp...", + myLogPrefix.c_str()); + return; + } + case ArServerCommands::TCP_ONLY: + { + if (!myQuiet || myDebugLogging) + ArLog::log(ArLog::Normal, "%sClient told to only use tcp.", + myLogPrefix.c_str()); + myDataMutex.lock(); + myTcpOnlyTo = true; + myDataMutex.unlock(); + return; + } + default: + { + std::map::iterator it; + ArClientData *clientData = NULL; + // see if we have the command + myMapsMutex.lock(); + if ((it = myIntDataMap.find(packet->getCommand())) != myIntDataMap.end()) { + clientData = (*it).second; + myMapsMutex.unlock(); + } + else { // command not found + + myMapsMutex.unlock(); + ArLog::log(ArLog::Terse, + "%sGot packet for %d which doesn't exist, packet was %d long", + myLogPrefix.c_str(), packet->getCommand(), packet->getLength()); + packet->log(); + + ArLog::log(ArLog::Terse, "%sPacket: ", myLogPrefix.c_str()); + for (int ijk = 0; ijk < packet->getLength(); ijk++) + ArLog::log(ArLog::Terse, " %d ", + (unsigned char) packet->getBuf()[ijk]); + } + + if (clientData == NULL) + { + ArLog::log(ArLog::Terse, + "%sNull client data for command %d", + myLogPrefix.c_str(), packet->getCommand()); + return; + } + + clientData->lockFunctorList(); + if (clientData->getFunctorList()->begin() == + clientData->getFunctorList()->end()) + { + ArLog::log(myVerboseLogLevel, + "%sNo functor to handle command %d", + myLogPrefix.c_str(), packet->getCommand()); + clientData->unlockFunctorList(); + return; + } + else + { + std::list *>::const_iterator it; + ArFunctor1 *functor = NULL; + + // PS (with KMC help) - make a copy so that we can remove from the list + std::list *> copiedList = *(clientData->getFunctorList()); + + for (it = copiedList.begin(); + it != copiedList.end(); + it++) + //for (it = clientData->getFunctorList()->begin(); + // it != clientData->getFunctorList()->end(); + // it++) + { + packet->resetRead(); + functor = (*it); + functor->invoke(packet); + } + clientData->unlockFunctorList(); + trackPacketReceived(packet, tcp); + + } + + } // end default + return; + + } // end switch command + } + /// see if we've opened the socket and this is an intro + else if (myState == STATE_OPENED_SOCKET && + packet->getCommand() == ArServerCommands::INTRODUCTION) + { + + char buf[512]; + char passwordKey[2048]; + char enforceProtocolVersion[256]; + + myDataMutex.lock(); + // first read the data from the packet + packet->bufToStr(buf, 512); + myServerReportedUdpPort = packet->bufToUByte2(); + + if (!myQuiet || myDebugLogging) + { + if (myServerReportedUdpPort == 0) + ArLog::log(myVerboseLogLevel, "%sConnection to version %s", + myLogPrefix.c_str(), + buf); + else + ArLog::log(myVerboseLogLevel, + "%sConnection to version %s with udp port %u", + myLogPrefix.c_str(), + buf, myServerReportedUdpPort); + } + if (myServerReportedUdpPort == 0) + { + myTcpOnlyTo = true; + myTcpOnlyFrom = true; + } + // set our expected port (its okay if its otherwise) + myUdpSin.sin_port = ArSocket::hostToNetOrder(myServerReportedUdpPort); + // get the keys + myAuthKey = packet->bufToUByte4(); + myIntroKey = packet->bufToUByte4(); + packet->bufToStr(passwordKey, sizeof(passwordKey)); + packet->bufToStr(enforceProtocolVersion, sizeof(enforceProtocolVersion)); + if (!myEnforceProtocolVersion.empty() && + strcasecmp(enforceProtocolVersion, + myEnforceProtocolVersion.c_str()) != 0) + { + myRejected = 3; + strcpy(myRejectedString, "Client rejecting server, since server protocol version does not match"); + ArLog::log(ArLog::Normal, + "%sClient rejecting server, since server protocol version does not match", + myLogPrefix.c_str()); + internalSwitchState(STATE_REJECTED); + return; + } + + // introduce ourself normally via tcp + retPacket.empty(); + retPacket.setCommand(ArClientCommands::INTRODUCTION); + retPacket.uByte2ToBuf(myUdpPort); + retPacket.strToBuf(myUser.c_str()); + // old simple cleartext way + //retPacket.strToBuf(myPassword.c_str()); + md5_state_t md5State; + unsigned char md5Digest[16]; + + md5_init(&md5State); + md5_append(&md5State, (unsigned char *)myServerKey.c_str(), + myServerKey.size()); + md5_append(&md5State, (unsigned char *)passwordKey, strlen(passwordKey)); + md5_append(&md5State, (unsigned char *)myPassword.c_str(), + myPassword.size()); + md5_finish(&md5State, md5Digest); + + retPacket.dataToBuf((const char *)md5Digest, 16); + retPacket.strToBuf(myEnforceProtocolVersion.c_str()); + retPacket.byteToBuf(myEnforceType); + + sendPacketTcp(&retPacket); + + myPassword = "%s"; + bool tcpOnlyFrom = myTcpOnlyFrom; + myDataMutex.unlock(); + if (tcpOnlyFrom) + { + retPacket.empty(); + retPacket.setCommand(ArClientCommands::TCP_ONLY); + sendPacketTcp(&retPacket); + } + internalSwitchState(STATE_EXCHANGED_INTROS); + } + // if we're not at opened socket and got an intro somethings horribly wrong + else if (myState != STATE_OPENED_SOCKET && + packet->getCommand() == ArServerCommands::INTRODUCTION) + { + if (!myQuiet || myDebugLogging) + ArLog::log(ArLog::Terse, + "%sIntroduction received when not in STATE_OPENED_SOCKET", + myLogPrefix.c_str()); + return; + } + // if we're at opened socket and received something other than intro + // then somethings horribly wrong + else if (myState == STATE_OPENED_SOCKET && + packet->getCommand() != ArServerCommands::INTRODUCTION) + { + if (!myQuiet || myDebugLogging) + ArLog::log(ArLog::Terse, + "%sPacket other than introduction received when in STATE_OPENED_SOCKET", + myLogPrefix.c_str()); + return; + } + // if we've exchanged intros and are waiting for connection or rejection + else if (myState == STATE_EXCHANGED_INTROS && + packet->getCommand() == ArServerCommands::CONNECTED) + { + if (!myQuiet || myDebugLogging) + { + if (myTcpOnlyTo && myTcpOnlyFrom) + ArLog::log(ArLog::Terse, + "%sClient now connected to server (tcp only).", + myLogPrefix.c_str()); + else + ArLog::log(ArLog::Terse, + "%sClient now connected to server.", myLogPrefix.c_str()); + } + internalSwitchState(STATE_WAITING_LIST); + // introduce ourself via udp + retPacket.empty(); + retPacket.setCommand(ArClientCommands::UDP_INTRODUCTION); + myDataMutex.lock(); + retPacket.uByte4ToBuf(myAuthKey); + myDataMutex.unlock(); + sendPacketUdp(&retPacket); + return; + } + // if we've received a connected and aren't at exchanging intros + else if (packet->getCommand() == ArServerCommands::CONNECTED) + { + ArLog::log(ArLog::Terse, + "%sConnected packet received not during STATE_EXCHANGED_INTROS", + myLogPrefix.c_str()); + return; + } + // if we're exchanging intros and were rejected + else if (myState != STATE_CONNECTED && + packet->getCommand() == ArServerCommands::REJECTED) + { + myRejected = packet->bufToByte2(); + packet->bufToStr(myRejectedString, sizeof(myRejectedString)); + if (!myQuiet || myDebugLogging) + { + if (myRejected == 1) + ArLog::log(ArLog::Normal, + "%sServer rejected connection because of bad user/password", + myLogPrefix.c_str()); + else if (myRejected == 2) + ArLog::log(ArLog::Normal, + "%sServer rejected connection since it is using the centralserver at %s", + myLogPrefix.c_str(), myRejectedString); + else if (myRejected == 3) + ArLog::log(ArLog::Normal, + "%sServer rejected for bad reason (3 should be from client side... it reported '%s')", + myLogPrefix.c_str(), myRejectedString); + else if (myRejected == 4) + ArLog::log(ArLog::Normal, + "%sServer rejected client because client using wrong protocol version.", + myLogPrefix.c_str()); + + else + ArLog::log(ArLog::Normal, + "%sServer rejected connection for unknown reason %d '%s'", + myLogPrefix.c_str(), myRejected, myRejectedString); + } + + internalSwitchState(STATE_REJECTED); + return; + } + // if we received rejected and aren't at exchanging intros + else if (packet->getCommand() == ArServerCommands::REJECTED) + { + ArLog::log(ArLog::Terse, + "%sRejected packet received after connected", + myLogPrefix.c_str()); + return; + } + // if we're waiting for our list and get it we're connected + else if (myState == STATE_WAITING_LIST && + packet->getCommand() == ArServerCommands::LIST) + { + internalSwitchState(STATE_CONNECTED); + myDataMutex.lock(); + md5_state_t md5State; + + md5_init(&md5State); + md5_append(&md5State, (unsigned char *)&myAuthKey, sizeof(myAuthKey)); + md5_append(&md5State, (unsigned char *)&myIntroKey, sizeof(myIntroKey)); + long rand = ArMath::random(); + md5_append(&md5State, (unsigned char *)&rand, sizeof(rand)); + unsigned int time = ArUtil::getTime(); + md5_append(&md5State, (unsigned char *)&time, sizeof(time)); + + md5_finish(&md5State, myClientKey); + myDataMutex.unlock(); + myMapsMutex.lock(); + buildList(packet); + myMapsMutex.unlock(); + return; + } + // see if we got any lists when not waiting for them + else if (packet->getCommand() == ArServerCommands::LIST || + packet->getCommand() == ArServerCommands::LISTSINGLE || + packet->getCommand() == ArServerCommands::LISTARGRET || + packet->getCommand() == ArServerCommands::LISTARGRETSINGLE || + packet->getCommand() == ArServerCommands::LISTGROUPANDFLAGS || + packet->getCommand() == ArServerCommands::LISTGROUPANDFLAGSSINGLE) + { + myMapsMutex.lock(); + buildList(packet); + myMapsMutex.unlock(); + return; + } + // if we're in exhanged intros and receive a packet not for that state + else if (myState == STATE_EXCHANGED_INTROS && + packet->getCommand() != ArServerCommands::CONNECTED && + packet->getCommand() != ArServerCommands::REJECTED) + { + ArLog::log(ArLog::Terse, + "%sIn STATE_EXCHANGE_INTROS and received something other than connected or rejected (%d).", myLogPrefix.c_str(), packet->getCommand()); + return; + } + + /*** KMC Moved into switch statement above + // if we're connected and got a udp confirmed packet then everything is good + else if (myState == STATE_CONNECTED && + packet->getCommand() == ArServerCommands::UDP_CONFIRMATION) + { + if (!myQuiet || myDebugLogging) + ArLog::log(myVerboseLogLevel, + "%sClients udp connection to server confirmed.", + myLogPrefix.c_str()); + myDataMutex.lock(); + myUdpConfirmedTo = true; + myDataMutex.unlock(); + return; + } + ***/ + + // if we're not connected and got a udp confirmation it means + // something is wrong + else if (packet->getCommand() == ArServerCommands::UDP_CONFIRMATION) + { + ArLog::log(ArLog::Terse, + "ArClientBase: Udp Confirmation received when not in STATE_CONNECTED"); + return; + } + else if (packet->getCommand() == ArServerCommands::UDP_INTRODUCTION) + { + ArLog::log(ArLog::Terse, + "ArClientBase: Udp Introduction received over tcp... when not in STATE_CONNECTED"); + return; + } + /*** KMC Moved into switch statement above + // if we're connected and got a tcp only packet then everything is good + else if (myState == STATE_CONNECTED && + packet->getCommand() == ArServerCommands::TCP_ONLY) + { + if (!myQuiet || myDebugLogging) + ArLog::log(ArLog::Normal, "%sClient told to only use tcp.", + myLogPrefix.c_str()); + myDataMutex.lock(); + myTcpOnlyTo = true; + myDataMutex.unlock(); + return; + } + **/ + + /*** KMC Moved into switch statement above + // if none of the above were triggered its just a normal packet + else if (myState == STATE_CONNECTED) + { + std::map::iterator it; + ArClientData *clientData = NULL; + // see if we have the command + myMapsMutex.lock(); + if ((it = myIntDataMap.find(packet->getCommand())) != myIntDataMap.end()) { + clientData = (*it).second; + myMapsMutex.unlock(); + } + else { // command not found + + myMapsMutex.unlock(); + ArLog::log(ArLog::Terse, + "%sGot packet for %d which doesn't exist, packet was %d long", + myLogPrefix.c_str(), packet->getCommand(), packet->getLength()); + packet->log(); + + ArLog::log(ArLog::Terse, "%sPacket: ", myLogPrefix.c_str()); + for (int ijk = 0; ijk < packet->getLength(); ijk++) + ArLog::log(ArLog::Terse, " %d ", + (unsigned char) packet->getBuf()[ijk]); + } + + if (clientData == NULL) + { + ArLog::log(ArLog::Terse, + "%sNull client data for command %d", + myLogPrefix.c_str(), packet->getCommand()); + return; + } + + clientData->lockFunctorList(); + if (clientData->getFunctorList()->begin() == + clientData->getFunctorList()->end()) + { + ArLog::log(myVerboseLogLevel, + "%sNo functor to handle command %d", + myLogPrefix.c_str(), packet->getCommand()); + clientData->unlockFunctorList(); + return; + } + else + { + std::list *>::const_iterator it; + ArFunctor1 *functor = NULL; + + for (it = clientData->getFunctorList()->begin(); + it != clientData->getFunctorList()->end(); + it++) + { + packet->resetRead(); + functor = (*it); + functor->invoke(packet); + } + clientData->unlockFunctorList(); + trackPacketReceived(packet, tcp); + + } + } + ****/ + + else + { + //packet->bufToStr(&str); + //packet->printHex(); + ArLog::log(myVerboseLogLevel, + "%sBogus packet of %u command %d long (probably after close)", + myLogPrefix.c_str(), packet->getCommand(), + packet->getLength()); + } + //sendPacketTcp(packet); + +} + +void ArClientBase::buildList(ArNetPacket *packet) +{ + ArClientData *clientData; + unsigned int listLen; + unsigned int i; + unsigned int command; + char name[512]; + char description[512]; + char argDesc[512]; + char retDesc[512]; + char commandGroup[512]; + char dataFlags[512]; + + // if its a single list snag it and run + if (packet->getCommand() == ArServerCommands::LISTSINGLE) + { + command = packet->bufToUByte2(); + packet->bufToStr(name, sizeof(name)); + packet->bufToStr(description, sizeof(description)); + clientData = new ArClientData(name, description, command, NULL); + ArLog::log(myVerboseLogLevel, + "%sNew entry number %d for data %s with description %s", + myLogPrefix.c_str(), command, name, description); + if (myIntDataMap.find(command) != myIntDataMap.end()) + ArLog::log(ArLog::Normal, + "%sIs already an entry for number %d as data %d\n, overwriting", + myLogPrefix.c_str(), command, + myIntDataMap[command]->getName()); + myNameIntMap[name] = command; + myIntDataMap[command] = clientData; + return; + } + else if (packet->getCommand() == ArServerCommands::LIST) + { + myReceivedDataList = true; + listLen = packet->bufToUByte2(); + // otherwise loop and read them all + for (i = 0; i < listLen; i++) + { + command = packet->bufToUByte2(); + packet->bufToStr(name, sizeof(name)); + packet->bufToStr(description, sizeof(description)); + clientData = new ArClientData(name, description, command, NULL); + ArLog::log(myVerboseLogLevel, + "%sNew entry number %d for data %s with description %s", + myLogPrefix.c_str(), command, name, description); + if (myIntDataMap.find(command) != myIntDataMap.end() && + strcmp(myIntDataMap[command]->getName(), name)) + ArLog::log(ArLog::Normal, + "%sIs already an entry for number %d as data %d\n, overwriting", + myLogPrefix.c_str(), command, + myIntDataMap[command]->getName()); + myNameIntMap[name] = command; + myIntDataMap[command] = clientData; + } + return; + } + // if its a single list snag it and run + else if (packet->getCommand() == ArServerCommands::LISTARGRETSINGLE) + { + command = packet->bufToUByte2(); + clientData = myIntDataMap[command]; + if (clientData == NULL) + { + ArLog::log(ArLog::Normal, + "%sbuildList: Unknown command %s %d", + myLogPrefix.c_str(), getName(packet->getCommand(), true), + packet->getCommand()); + return; + } + packet->bufToStr(argDesc, sizeof(argDesc)); + packet->bufToStr(retDesc, sizeof(retDesc)); + clientData->setArgRetDescs(argDesc, retDesc); + return; + } + else if (packet->getCommand() == ArServerCommands::LISTARGRET) + { + myReceivedArgRetList = true; + listLen = packet->bufToUByte2(); + // otherwise loop and read them all + for (i = 0; i < listLen; i++) + { + command = packet->bufToUByte2(); + clientData = myIntDataMap[command]; + if (clientData == NULL) + { + ArLog::log(ArLog::Normal, + "%sbuildList: Unknown command %s %d", myLogPrefix.c_str(), + getName(packet->getCommand(), true), packet->getCommand()); + // KMC Need to do something here because otherwise it blows up on + // the setArgRetDescs call below... + return; + } + packet->bufToStr(argDesc, sizeof(argDesc)); + packet->bufToStr(retDesc, sizeof(retDesc)); + clientData->setArgRetDescs(argDesc, retDesc); + } + return; + } + // if its a single list snag it and run + else if (packet->getCommand() == ArServerCommands::LISTGROUPANDFLAGSSINGLE) + { + command = packet->bufToUByte2(); + clientData = myIntDataMap[command]; + if (clientData == NULL) + { + ArLog::log(ArLog::Normal, + "%sbuildList: Unknown command %s %d", + myLogPrefix.c_str(), getName(packet->getCommand(), true), + packet->getCommand()); + return; + } + packet->bufToStr(commandGroup, sizeof(commandGroup)); + packet->bufToStr(dataFlags, sizeof(dataFlags)); + clientData->setCommandGroup(commandGroup); + clientData->addDataFlags(dataFlags); + return; + } + else if (packet->getCommand() == ArServerCommands::LISTGROUPANDFLAGS) + { + myReceivedGroupAndFlagsList = true; + listLen = packet->bufToUByte2(); + // otherwise loop and read them all + for (i = 0; i < listLen; i++) + { + command = packet->bufToUByte2(); + clientData = myIntDataMap[command]; + if (clientData == NULL) + { + ArLog::log(ArLog::Normal, + "%sbuildList: Unknown command %s %d", myLogPrefix.c_str(), + getName(packet->getCommand(), true), packet->getCommand()); + // KMC Need to do something here because otherwise it blows up on + // the setArgRetDescs call below... + return; + } + packet->bufToStr(commandGroup, sizeof(commandGroup)); + packet->bufToStr(dataFlags, sizeof(dataFlags)); + clientData->setCommandGroup(commandGroup); + clientData->addDataFlags(dataFlags); + } + return; + } + else + { + ArLog::log(ArLog::Terse, + "%sbuildList: Unhandled packet type %s %d", + myLogPrefix.c_str(), getName(packet->getCommand(), true), + packet->getCommand()); + } +} + +AREXPORT void ArClientBase::processPacketUdp(ArNetPacket *packet, + struct sockaddr_in *sin) +{ + unsigned char *bytes = (unsigned char *)&sin->sin_addr.s_addr; + long introKey; + ArNetPacket retPacket; + + myDataMutex.lock(); + myLastPacketReceived.setToNow(); + // see if its an intro packet and we're connected (or could be but + // not yet know it) + if ((myState == STATE_CONNECTED || myState == STATE_EXCHANGED_INTROS || + myState == STATE_WAITING_LIST) && + packet->getCommand() == ArServerCommands::UDP_INTRODUCTION) + { + // see if we've already confirmed the UDP + if (myUdpConfirmedFrom) + { + myDataMutex.unlock(); + return; + } + introKey = packet->bufToByte4(); + if (myIntroKey != introKey) + { + ArLog::log(ArLog::Terse, + "%sUdp introduction packet received with wrong introKey", + myLogPrefix.c_str()); + myDataMutex.unlock(); + return; + } + if (myServerReportedUdpPort != ArSocket::netToHostOrder(sin->sin_port)) + ArLog::log(myVerboseLogLevel, + "%sPorts don't match, said from server %d and given was %d", + myLogPrefix.c_str(), myServerReportedUdpPort, + ArSocket::netToHostOrder(sin->sin_port)); + myUdpSin.sin_port = sin->sin_port; + myUdpConfirmedFrom = true; + // now confirm to the server we got the UDP packet + retPacket.empty(); + retPacket.setCommand(ArClientCommands::UDP_CONFIRMATION); + if (!myQuiet || myDebugLogging) + ArLog::log(ArLog::Normal, "%sServer connected to us on udp port %d", + myLogPrefix.c_str(), + ArSocket::netToHostOrder(myUdpSin.sin_port)); + myDataMutex.unlock(); + sendPacketTcp(&retPacket); + return; + } + // if we receive an intro packet but aren't connected + else if (packet->getCommand() == ArServerCommands::UDP_INTRODUCTION) + { + ArLog::log(ArLog::Terse, + "%sUdp introduction packet received while not connected", + myLogPrefix.c_str()); + myDataMutex.unlock(); + return; + } + // if its not an intro, make sure it matchs our server + else if (myUdpSin.sin_port == sin->sin_port && + myUdpSin.sin_addr.s_addr == sin->sin_addr.s_addr) + { + // TODO make this reject them if they're not in the user area + myDataMutex.unlock(); + processPacket(packet, false); + myDataMutex.lock(); + } + // if it doesn't warn about it + else + { + ArLog::log(ArLog::Normal, "%sBogus UDP packet from %d.%d.%d.%d %d", + myLogPrefix.c_str(), bytes[0], bytes[1], bytes[2], bytes[3], + ArSocket::netToHostOrder(sin->sin_port)); + } + myDataMutex.unlock(); +} + +void ArClientBase::internalSwitchState(ClientState state) +{ + myState = state; + myStateStarted.setToNow(); +} + +/** + This adds a functor that will be called with a packet whenever a + packet for that name arrives + + Note that if you try and add a handler for a specific piece of data + from within a handler for that specific piece of data you'll + deadlock. + + @param name the name of the data to use with this functor + + @param functor the functor to call with the packet when data with + this name arrives + + @return false is returned if this name doesn't exist in the data + + @pynote Pass a function taking one argument for @arg functor + @javanote Use a subclass of ArFunctor_NetPacket for the @arg functor object. +**/ +AREXPORT bool ArClientBase::addHandler(const char *name, + ArFunctor1 *functor) +{ + if (name == NULL) { + ArLog::log(ArLog::Normal, "%saddHandler: Cannot add NULL name", + myLogPrefix.c_str()); + return false; + } + ArClientData *clientData; + // see if we have this data + myMapsMutex.lock(); + if (myNameIntMap.find(name) == myNameIntMap.end()) + { + ArLog::log(ArLog::Normal, + "%saddHandler: There is no data by the name \"%s\" to handle", + myLogPrefix.c_str(), name); + myMapsMutex.unlock(); + return false; + } + // since we have the data get the pointer to it + clientData = myIntDataMap[myNameIntMap[name]]; + myMapsMutex.unlock(); + + // make sure nothings gone wrong + if (clientData == NULL) + { + ArLog::log(ArLog::Normal, + "%saddHandler: There was no clientData for data \"%s\"", + myLogPrefix.c_str(), name); + return false; + } + clientData->lockFunctorList(); + // see if it already has a functor + if (clientData->getFunctorList()->begin() != + clientData->getFunctorList()->end()) + { + ArLog::log(myVerboseLogLevel, + "%saddHandler: There is already a functor for data \"%s\", adding anyways", + myLogPrefix.c_str(), name); + //return false; + } + // addthe functor + clientData->addFunctor(functor); + clientData->unlockFunctorList(); + return true; +} + +/** + This removes a functor from being called with a packet whenever a + packet for that name arrives + + Note that if you try and remove a handler for a specific piece of + data from within a handler for that specific piece of data you'll + deadlock. + + @param name the name of the data to use with this functor + + @param functor the functor to call with the packet when data with + this name arrives + + @return false is returned if this name doesn't exist in the data +**/ + +AREXPORT bool ArClientBase::remHandler(const char *name, + ArFunctor1 *functor) +{ + ArClientData *clientData; + myMapsMutex.lock(); + // see if we have this client data + if (myNameIntMap.find(name) == myNameIntMap.end()) + { + ArLog::log(ArLog::Normal, + "%sremHandler: There is no data \"%s\"", + myLogPrefix.c_str(), name); + myMapsMutex.unlock(); + return false; + } + if ((clientData = myIntDataMap[myNameIntMap[name]]) == NULL) + { + ArLog::log(ArLog::Normal, "%sremHandler: There was no client data for data \"%s\"", myLogPrefix.c_str(), name); + myMapsMutex.unlock(); + return false; + } + myMapsMutex.unlock(); + // set the functor to NULL + clientData->lockFunctorList(); + clientData->remFunctor(functor); + clientData->unlockFunctorList(); + return true; +} + + +/** + @param name the name of the data to find the command of + + @return 0 if there is no command of that name, the command number + otherwise +**/ +AREXPORT unsigned int ArClientBase::findCommandFromName(const char *name) +{ + std::map::iterator it; + unsigned int ret; + + myMapsMutex.lock(); + if ((it = myNameIntMap.find(name)) == myNameIntMap.end()) + { + ArLog::log(ArLog::Normal, + "%sFinding command for \"%s\" but no data with that name exists", + myLogPrefix.c_str(), name); + myMapsMutex.unlock(); + return 0; + } + ret = (*it).second; + myMapsMutex.unlock(); + return ret; +} + +/** + This requests data from the server for the given name, at a given + interval, optionally passing along data with the request. + + @param name the name of the data to request from the server + + @param mSec request interval: the number of milliseconds we want a refresh on this + data, if this number is 0 then the server will send the information + as often as it is available; if -1, then the server will send the + information only when it changes (for broadcast type packets) + + @param packet a packet to use for the request, may contain data to use as +parameters or arguments along with the request. + **/ +AREXPORT bool ArClientBase::request(const char *name, long mSec, + ArNetPacket *packet) +{ + ArLog::log(myVerboseLogLevel, + "%sRequesting data for \"%s\"", + myLogPrefix.c_str(), name); + return requestByCommand(findCommandFromName(name), mSec, packet); +} + +/** + This requests data from the server for the given name, at mSec + milliseconds interval, optionally passing along data for the + request. + + @param command the command number of the data to request + + @param mSec the number of milliseconds we want a refresh on this + data, if this number is 0 then the server will send the information + as often as it is available; if -1, then the server will send the + information only when it changes (for broadcast type packets) + + @param packet the packet that contains the data to use as argument + **/ +AREXPORT bool ArClientBase::requestByCommand(unsigned int command, + long mSec, ArNetPacket *packet) +{ + ArNetPacket sending; + + sending.setCommand(ArClientCommands::REQUEST); + sending.uByte2ToBuf(command); + sending.byte4ToBuf(mSec); + if (packet != NULL) + { + packet->resetRead(); + sending.dataToBuf(&packet->getBuf()[packet->getReadLength()], + packet->getLength() - packet->getReadLength()); + } + return sendPacketTcp(&sending); +} + + +/** + @param name the name to stop sending +**/ +AREXPORT bool ArClientBase::requestStop(const char *name) +{ + ArLog::log(myVerboseLogLevel, + "%sRequesting stop data for \"%s\"", + myLogPrefix.c_str(), name); + return requestStopByCommand(findCommandFromName(name)); +} + +/** + @param command the command number to stop +**/ +AREXPORT bool ArClientBase::requestStopByCommand(unsigned int command) +{ + ArNetPacket sending; + sending.setCommand(ArClientCommands::REQUESTSTOP); + sending.uByte2ToBuf(command); + return sendPacketTcp(&sending); +} + + +/** + This requests the data from the server, but only once... this is + useful for things like video data that you don't want to clog up + the bandwidth with... its also useful for things like sending + commands + + @param name the name of the data to request + @param packet the packet that contains the data to use as argument + @param quiet a bool set to true to override the verbose logging of this + method (generally for repeating requests); default is false to log. +**/ +AREXPORT bool ArClientBase::requestOnce(const char *name, + ArNetPacket *packet, + bool quiet) +{ + if (!quiet) + ArLog::log(myVerboseLogLevel, + "%sRequesting data once for \"%s\"", myLogPrefix.c_str(), name); + return requestOnceByCommand(findCommandFromName(name), packet); +} + +/** + Send one request over UDP. For example, use this method for + certain kinds of data where constant streaming would be undesirable + (e.g. video images that might saturate the network), or for sending + a simple command. + Note that since the request is sent using UDP, you cannot + assume it will get there or that you will get a response. + + @param name the name of the data to request + @param packet the packet that contains the data to use as argument + @param quiet If true, suppress verbose-level log message +**/ +AREXPORT bool ArClientBase::requestOnceUdp( + const char *name, ArNetPacket *packet, bool quiet) +{ + if (!quiet) + ArLog::log(myVerboseLogLevel, + "%sRequesting data once (UDP) for \"%s\"", + myLogPrefix.c_str(), name); + return requestOnceByCommandUdp(findCommandFromName(name), packet); +} + +/** + This requests the data from the server, but only once... this is + useful for things like video data that you don't want to clog up + the bandwidth with... its also useful for things like sending + commands + + @param command the command number to request + @param packet the packet that contains the data to use as argument +**/ +AREXPORT bool ArClientBase::requestOnceByCommand(unsigned int command, + ArNetPacket *packet) +{ + if (packet != NULL) + { + packet->setCommand(command); + return sendPacketTcp(packet); + } + else + { + ArNetPacket tempPacket; + tempPacket.setCommand(command); + return sendPacketTcp(&tempPacket); + } +} + +/** + This requests the data from the server, but only once... this is + useful for things like video data that you don't want to clog up + the bandwidth with... its also useful for things like sending + commands + + @param command the command number to request + @param packet the packet that contains the data to use as argument +**/ +AREXPORT bool ArClientBase::requestOnceByCommandUdp(unsigned int command, + ArNetPacket *packet) +{ + if (packet != NULL) + { + packet->setCommand(command); + if (!myTcpOnlyTo) + return sendPacketUdp(packet); + else + return sendPacketTcp(packet); + } + else + { + ArNetPacket tempPacket; + tempPacket.setCommand(command); + if (!myTcpOnlyTo) + return sendPacketUdp(&tempPacket); + else + return sendPacketTcp(&tempPacket); + } +} + +/** + This requests the data from the server, but only once... this is + useful for things like video data that you don't want to clog up + the bandwidth with... its also useful for things like sending + commands + + @param name the name of the data to request + @param str a string to send as the packet argument +**/ +AREXPORT bool ArClientBase::requestOnceWithString(const char *name, + const char *str) +{ + std::map::iterator it; + + myMapsMutex.lock(); + if ((it = myNameIntMap.find(name)) == myNameIntMap.end()) + { + ArLog::log(ArLog::Normal, + "%sRequesting data for \"%s\" but no data with that name exists", + myLogPrefix.c_str(), name); + myMapsMutex.unlock(); + return false; + } + myMapsMutex.unlock(); + ArLog::log(myVerboseLogLevel, + "%sRequesting data once for \"%s\"", + myLogPrefix.c_str(), name); + + ArNetPacket tempPacket; + tempPacket.strToBuf(str); + tempPacket.setCommand((*it).second); + return sendPacketTcp(&tempPacket); +} + +/** + @param name the name to stop sending +**/ +AREXPORT bool ArClientBase::dataExists(const char *name) +{ + bool ret; + myMapsMutex.lock(); + ret = (myNameIntMap.find(name) != myNameIntMap.end()); + myMapsMutex.unlock(); + return ret; +} + +AREXPORT void ArClientBase::logDataList(void) +{ + std::map::iterator it; + ArClientData *clientData; + + myMapsMutex.lock(); + ArLog::log(ArLog::Terse, ""); + ArLog::log(ArLog::Terse, "%sAvailable data:", myLogPrefix.c_str()); + for (it = myIntDataMap.begin(); it != myIntDataMap.end(); it++) + { + clientData = (*it).second; + ArLog::log(ArLog::Terse, ""); + ArLog::log(myVerboseLogLevel, "Number %d, %d functors", + clientData->getCommand(), + clientData->getFunctorList()->size()); + ArLog::log(ArLog::Terse, "Data: %s", clientData->getName()); + ArLog::log(ArLog::Terse, "\tDescription: %s", + clientData->getDescription()); + ArLog::log(ArLog::Terse, "\tArgument: %s", + clientData->getArgumentDescription()); + ArLog::log(ArLog::Terse, "\tReturn: %s", + clientData->getReturnDescription()); + ArLog::log(ArLog::Terse, "\tCommandGroup: %s", + clientData->getCommandGroup()); + ArLog::log(ArLog::Terse, "\tDataFlags: %s", + clientData->getDataFlagsString()); + + } + myMapsMutex.unlock(); +} + +/** + @param functor functor created from ArFunctorC which refers to the + function to call. + @param position whether to place the functor first or last + @see remDisconnectOnErrorCB + **/ + +AREXPORT void ArClientBase::addDisconnectOnErrorCB(ArFunctor *functor, + ArListPos::Pos position) +{ + myCallbackMutex.lock(); + if (position == ArListPos::FIRST) + myDisconnectOnErrorCBList.push_front(functor); + else if (position == ArListPos::LAST) + myDisconnectOnErrorCBList.push_back(functor); + else + ArLog::log(ArLog::Terse, + "%saddDisconnectOnErrorCB: Invalid position", + myLogPrefix.c_str()); + myCallbackMutex.unlock(); +} + +/** + @param functor the functor to remove from the list of connect callbacks + @see addDisconnectOnErrorCB +**/ +AREXPORT void ArClientBase::remDisconnectOnErrorCB(ArFunctor *functor) +{ + myCallbackMutex.lock(); + myDisconnectOnErrorCBList.remove(functor); + myCallbackMutex.unlock(); +} + +/** + @param functor functor created from ArFunctorC which refers to the + function to call. + @param position whether to place the functor first or last + @see remServerShutdownCB + **/ + +AREXPORT void ArClientBase::addServerShutdownCB(ArFunctor *functor, + ArListPos::Pos position) +{ + myCallbackMutex.lock(); + if (position == ArListPos::FIRST) + myServerShutdownCBList.push_front(functor); + else if (position == ArListPos::LAST) + myServerShutdownCBList.push_back(functor); + else + ArLog::log(ArLog::Terse, + "%saddServerShutdownCB: Invalid position", myLogPrefix.c_str()); + myCallbackMutex.unlock(); +} + +/** + @param functor the functor to remove from the list of connect callbacks + @see addServerShutdownCB +**/ +AREXPORT void ArClientBase::remServerShutdownCB(ArFunctor *functor) +{ + myCallbackMutex.lock(); + myServerShutdownCBList.remove(functor); + myCallbackMutex.unlock(); +} + +AREXPORT void ArClientBase::setTcpOnlyFromServer(void) +{ + ArNetPacket packet; + + packet.setCommand(ArClientCommands::TCP_ONLY); + sendPacketTcp(&packet); + myDataMutex.lock(); + myTcpOnlyFrom = true; + myDataMutex.unlock(); +} + +AREXPORT void ArClientBase::setTcpOnlyToServer(void) +{ + myDataMutex.lock(); + myTcpOnlyTo = true; + myDataMutex.unlock(); +} + +AREXPORT bool ArClientBase::isTcpOnlyFromServer(void) +{ + bool ret; + myDataMutex.lock(); + ret = myTcpOnlyFrom; + myDataMutex.unlock(); + return ret; +} + +AREXPORT bool ArClientBase::isTcpOnlyToServer(void) +{ + bool ret; + myDataMutex.lock(); + ret = myTcpOnlyTo; + myDataMutex.unlock(); + return ret; +} + + +AREXPORT ArTime ArClientBase::getLastPacketReceived(void) +{ + ArTime ret; + myDataMutex.lock(); + ret = myLastPacketReceived; + myDataMutex.unlock(); + return ret; +} + +/** + Sets up the backup timeout, if there are packets to send to the + server and they haven't been sent for longer than this then the + connection is closed. Less than 0 means this won't happen. If + this is positive but less than 5 seconds then 5 seconds is used. +**/ +AREXPORT void ArClientBase::setBackupTimeout(double timeoutInMins) +{ + myBackupTimeout = timeoutInMins; + myTcpSender.setBackupTimeout(myBackupTimeout); +} + +AREXPORT const char *ArClientBase::getName(ArNetPacket *packet, + bool internalCall) +{ + return getName(packet->getCommand(), internalCall); +} + +AREXPORT const char *ArClientBase::getName(unsigned int command, + bool internalCall) +{ + const char *ret; + if (!internalCall) + myMapsMutex.lock(); + std::map::iterator it; + if ((it = myIntDataMap.find(command)) == myIntDataMap.end()) + ret = NULL; + else + ret = (*it).second->getName(); + if (!internalCall) + myMapsMutex.unlock(); + return ret; +} + +AREXPORT void ArClientBase::setServerKey(const char *serverKey, bool log) +{ + myDataMutex.lock(); + myServerKey = serverKey; + myDataMutex.unlock(); + if (log) + ArLog::log(ArLog::Normal, "%sNew server key set", myLogPrefix.c_str()); +} + + +AREXPORT void ArClientBase::enforceProtocolVersion(const char *protocolVersion, + bool log) +{ + myDataMutex.lock(); + if (protocolVersion != NULL) + myEnforceProtocolVersion = protocolVersion; + else + myEnforceProtocolVersion = ""; + myDataMutex.unlock(); + if (log) + ArLog::log(ArLog::Normal, "%sNew enforceProtocolVersionSet", myLogPrefix.c_str()); +} + +AREXPORT void ArClientBase::enforceType(ArServerCommands::Type type, + bool log) +{ + myDataMutex.lock(); + myEnforceType = type; + myDataMutex.unlock(); + if (log) + ArLog::log(ArLog::Normal, "%sNew enforce type: %s", + myLogPrefix.c_str(), ArServerCommands::toString(type)); + +} + +/** + NOTE that this is only valid AFTER the client is connected +**/ +AREXPORT void ArClientBase::getClientKey(unsigned char key[CLIENT_KEY_LENGTH]) +{ + memcpy(key, myClientKey, CLIENT_KEY_LENGTH); +} + +AREXPORT const char *ArClientBase::getHost(void) +{ + const char *ret; + myDataMutex.lock(); + ret = myHost.c_str(); + myDataMutex.unlock(); + return ret; +} + +void ArClientBase::trackPacketSent(ArNetPacket *packet, bool tcp) +{ + myPacketTrackingMutex.lock(); + if (myTrackingSentMap.find(packet->getCommand()) == myTrackingSentMap.end()) + myTrackingSentMap[packet->getCommand()] = new Tracker; + + if (tcp) + { + myTrackingSentMap[packet->getCommand()]->myPacketsTcp++; + myTrackingSentMap[packet->getCommand()]->myBytesTcp += packet->getLength(); + } + else + { + myTrackingSentMap[packet->getCommand()]->myPacketsUdp++; + myTrackingSentMap[packet->getCommand()]->myBytesUdp += packet->getLength(); + } + myPacketTrackingMutex.unlock(); +} + +void ArClientBase::trackPacketReceived(ArNetPacket *packet, + bool tcp) +{ + myPacketTrackingMutex.lock(); + if (myTrackingReceivedMap.find(packet->getCommand()) == + myTrackingReceivedMap.end()) + myTrackingReceivedMap[packet->getCommand()] = new Tracker; + + if (tcp) + { + myTrackingReceivedMap[packet->getCommand()]->myPacketsTcp++; + myTrackingReceivedMap[packet->getCommand()]->myBytesTcp += + packet->getLength(); + } + else + { + myTrackingReceivedMap[packet->getCommand()]->myPacketsUdp++; + myTrackingReceivedMap[packet->getCommand()]->myBytesUdp += + packet->getLength(); + } + myPacketTrackingMutex.unlock(); +} + +AREXPORT void ArClientBase::logTracking(bool terse) +{ + myDataMutex.lock(); + myPacketTrackingMutex.lock(); + std::map::iterator it; + + unsigned int command; + Tracker *tracker = NULL; + long seconds; + + seconds = myTrackingStarted.secSince(); + if (seconds == 0) + seconds = 1; + + const char *namePtr; + char name[512]; + + long packetsReceivedTcp = 0; + long bytesReceivedTcp = 0; + long packetsReceivedUdp = 0; + long bytesReceivedUdp = 0; + + ArLog::log(ArLog::Terse, ""); + ArLog::log(ArLog::Terse, "%sReceived tracking (active %d seconds):", + myLogPrefix.c_str(), seconds); + for (it = myTrackingReceivedMap.begin(); it != myTrackingReceivedMap.end(); it++) + { + command = (*it).first; + tracker = (*it).second; + + packetsReceivedTcp += tracker->myPacketsTcp; + bytesReceivedTcp += tracker->myBytesTcp; + packetsReceivedUdp += tracker->myPacketsUdp; + bytesReceivedUdp += tracker->myBytesUdp; + + if ((namePtr = getName(command, true)) != NULL && namePtr[0] != '\0') + snprintf(name, sizeof(name), "%s", namePtr); + // if we're command 255 or less and there's no name its probably + // one of the server commands we don't really need to track + else if (command <= 255) + continue; + // we should know what the name of everything other then the + // server command is, but print if we don't, just in case + else + snprintf(name, sizeof(name), "#%d", command); + + if (terse) + { + ArLog::log(ArLog::Terse, + "%35s %7ld pkts %10ld B %7ld B/sec", + name, tracker->myPacketsTcp + tracker->myPacketsUdp, + tracker->myBytesTcp + tracker->myBytesUdp, + ((tracker->myBytesTcp + tracker->myBytesUdp)/ + seconds)); + } + else + { + ArLog::log(ArLog::Terse, + "%35s %7ld tcp pkts %10ld tcp B %7ld tcp B/S %7ld udp pkts %10ld udp B %7ld udp B/s ", + name, tracker->myPacketsTcp, tracker->myBytesTcp, + tracker->myBytesTcp/seconds, + tracker->myPacketsUdp, tracker->myBytesUdp, + tracker->myBytesUdp/seconds); + } + } + + ArLog::log(ArLog::Terse, ""); + if (terse) + { + ArLog::log(ArLog::Terse, "%-35s %7ld pkts %10ld B %7ld B/sec", + "Total Received", packetsReceivedTcp + packetsReceivedUdp, + bytesReceivedTcp + bytesReceivedUdp, + (bytesReceivedTcp + bytesReceivedUdp) / seconds); + } + else + { + ArLog::log(ArLog::Terse, "%-35s %7ld tcp pkts %10ld tcp B %7ld tcp B/S %7ld udp pkts %10ld udp B %7ld udp B/sec", + "Total Received", packetsReceivedTcp, bytesReceivedTcp, + bytesReceivedTcp/seconds, packetsReceivedUdp, bytesReceivedUdp, + bytesReceivedUdp/seconds); + ArLog::log(ArLog::Terse, "%-35s %7ld tcp rcvs %10ld tcp B %7ld tcp B/S %7ld udp rcvs %10ld udp B %7ld udp B/sec", + "Low level Sockets Received", myTcpSocket.getRecvs(), + myTcpSocket.getBytesRecvd(), + myTcpSocket.getBytesRecvd()/seconds, myUdpSocket.getRecvs(), + myUdpSocket.getBytesRecvd(), + myUdpSocket.getBytesRecvd()/seconds); + } + + long packetsSentTcp = 0; + long bytesSentTcp = 0; + long packetsSentUdp = 0; + long bytesSentUdp = 0; + + ArLog::log(ArLog::Terse, ""); + ArLog::log(ArLog::Terse, "%sSent tracking (active %d seconds):", + myLogPrefix.c_str(), seconds); + for (it = myTrackingSentMap.begin(); it != myTrackingSentMap.end(); it++) + { + command = (*it).first; + tracker = (*it).second; + + packetsSentTcp += tracker->myPacketsTcp; + bytesSentTcp += tracker->myBytesTcp; + packetsSentUdp += tracker->myPacketsUdp; + bytesSentUdp += tracker->myBytesUdp; + + if ((namePtr = getName(command, true)) != NULL && namePtr[0] != '\0') + snprintf(name, sizeof(name), "%s", namePtr); + // if we're command 255 or less and there's no name its probably + // one of the server commands we don't really need to track + else if (command <= 255) + continue; + // we should know what the name of everything other then the + // server command is, but print if we don't, just in case + else + snprintf(name, sizeof(name), "#%d", command); + + if (terse) + { + ArLog::log(ArLog::Terse, + "%35s %7ld pkts %10ld B %7ld B/sec", + name, tracker->myPacketsTcp + tracker->myPacketsUdp, + tracker->myBytesTcp + tracker->myBytesUdp, + ((tracker->myBytesTcp + tracker->myBytesUdp)/ + seconds)); + } + else + { + ArLog::log(ArLog::Terse, + "%35s %7ld tcp pkts %10ld tcp B %7ld tcp B/S %7ld udp pkts %10ld udp B %7ld udp B/s ", + name, tracker->myPacketsTcp, tracker->myBytesTcp, + tracker->myBytesTcp/seconds, + tracker->myPacketsUdp, tracker->myBytesUdp, + tracker->myBytesUdp/seconds); + } + } + + ArLog::log(ArLog::Terse, ""); + if (terse) + { + ArLog::log(ArLog::Terse, "%-35s %7ld pkts %10ld B %7ld B/sec", + "Total Sent", packetsSentTcp + packetsSentUdp, + bytesSentTcp + bytesSentUdp, + (bytesSentTcp + bytesSentUdp) / seconds); + ArLog::log(ArLog::Terse, ""); + ArLog::log(ArLog::Terse, "%-35s %7ld pkts %10ld B %7ld B/sec", + "Total Sent and Received", + (packetsSentTcp + packetsSentUdp + + packetsReceivedTcp + packetsReceivedUdp), + (bytesSentTcp + bytesSentUdp + + bytesReceivedTcp + bytesReceivedUdp), + (bytesSentTcp + bytesSentUdp + + bytesReceivedTcp + bytesReceivedUdp) / seconds); + } + else + { + ArLog::log(ArLog::Terse, "%-35s %7ld tcp pkts %10ld tcp B %7ld tcp B/S %7ld udp pkts %10ld udp B %7ld udp B/sec", + "Total Sent", packetsSentTcp, bytesSentTcp, bytesSentTcp / seconds, + packetsSentUdp, bytesSentUdp, bytesSentUdp / seconds); + ArLog::log(ArLog::Terse, "%-35s %7ld tcp snds %10ld tcp B %7ld tcp B/S %7ld udp pkts %10ld udp B %7ld udp B/sec", + "Low level Sockets Sent", myTcpSocket.getSends(), + myTcpSocket.getBytesSent(), + myTcpSocket.getBytesSent() / seconds, myUdpSocket.getSends(), + myUdpSocket.getBytesSent(), + myUdpSocket.getBytesSent() / seconds); + + ArLog::log(ArLog::Terse, ""); + ArLog::log(ArLog::Terse, "%-35s %7ld tcp pkts %10ld tcp B %7ld tcp B/S %7ld udp pkts %10ld udp B %7ld udp B/sec", + "Total Sent and Received", packetsSentTcp = packetsReceivedTcp, + bytesSentTcp + bytesReceivedTcp, + (bytesSentTcp + bytesReceivedTcp) / seconds, + packetsSentUdp + packetsReceivedUdp, + bytesSentUdp + bytesReceivedUdp, + (bytesSentUdp + bytesReceivedUdp) / seconds); + } + ArLog::log(ArLog::Terse, ""); + myPacketTrackingMutex.unlock(); + myDataMutex.unlock(); +} + + +AREXPORT void ArClientBase::resetTracking(void) +{ + myPacketTrackingMutex.lock(); + + std::map::iterator it; + + myTrackingStarted.setToNow(); + + for (it = myTrackingSentMap.begin(); it != myTrackingSentMap.end(); it++) + (*it).second->reset(); + + for (it = myTrackingReceivedMap.begin(); + it != myTrackingReceivedMap.end(); + it++) + (*it).second->reset(); + + myTcpSocket.resetTracking(); + myUdpSocket.resetTracking(); + myPacketTrackingMutex.unlock(); +} diff --git a/Legacy/Aria/ArNetworking/src/ArClientData.cpp b/Legacy/Aria/ArNetworking/src/ArClientData.cpp new file mode 100644 index 0000000..21bc8b7 --- /dev/null +++ b/Legacy/Aria/ArNetworking/src/ArClientData.cpp @@ -0,0 +1,53 @@ +#include "Aria.h" +#include "ArExport.h" +#include "ArClientData.h" +#include "ArNetPacket.h" + +AREXPORT ArClientData::ArClientData( + const char *name, const char *description, unsigned int command, + ArFunctor1 *functor) : + myDataFlagsBuilder(512, '|') +{ + myDataMutex.setLogName("ArClientData::myDataMutex"); + myMutex.setLogName("ArClientData::myMutex"); + myName = name; + myDescription = description; + myCommand = command; + if (functor != NULL) + addFunctor(functor); +} + +AREXPORT ArClientData::~ArClientData() +{ + +} + +AREXPORT bool ArClientData::hasDataFlag(const char *dataFlag) +{ + myDataMutex.lock(); + size_t i; + for (i = 0; i < myDataFlagsBuilder.getArgc(); i++) + { + if (strcmp(myDataFlagsBuilder.getArg(i), dataFlag) == 0) + { + myDataMutex.unlock(); + return true; + } + } + + myDataMutex.unlock(); + return false; +} + + + +/// Sets the data flags +AREXPORT void ArClientData::addDataFlags(const char *dataFlags) +{ + if (dataFlags != NULL) + { + myDataMutex.lock(); + myDataFlagsBuilder.add(dataFlags); + myDataMutex.unlock(); + } +} diff --git a/Legacy/Aria/ArNetworking/src/ArClientFileUtils.cpp b/Legacy/Aria/ArNetworking/src/ArClientFileUtils.cpp new file mode 100644 index 0000000..db1e2e5 --- /dev/null +++ b/Legacy/Aria/ArNetworking/src/ArClientFileUtils.cpp @@ -0,0 +1,1416 @@ +#include "Aria.h" +#include "ArExport.h" +#include "ArClientFileUtils.h" + + +AREXPORT ArClientFileLister::ArClientFileLister(ArClientBase *client) : + myGetDirListingCB(this, &ArClientFileLister::netGetDirListing), + myGetDirListingMultiplePacketsCB( + this, + &ArClientFileLister::netGetDirListingMultiplePackets) +{ + myDataMutex.setLogName("ArClientFileLister::myDataMutex"); + myCallbackMutex.setLogName("ArClientFileLister::myCallbackMutex"); + myClient = client; + + if (myClient->dataExists("getDirListingMultiplePackets")) + { + ArLog::log(ArLog::Verbose, "ArClientFileLister: Using getDirListingMultiplePackets (new)"); + myClient->addHandler("getDirListingMultiplePackets", + &myGetDirListingMultiplePacketsCB); + } + else + { + ArLog::log(ArLog::Verbose, "ArClientFileLister: Using getDirListing (old)"); + myClient->addHandler("getDirListing", &myGetDirListingCB); + } + myCurrentDir[0] = '\0'; + myWaitingForDir[0] = '\0'; + myLastDirMatched = false; + myNewDirListing = false; +} + +AREXPORT ArClientFileLister::~ArClientFileLister() +{ + +} + +AREXPORT bool ArClientFileLister::isAvailable(void) +{ + return (myClient->dataExists("getDirListingMultiplePackets") || + myClient->dataExists("getDirListing")); +} + +void ArClientFileLister::getDirListing(const char *dir) +{ + if (myClient->dataExists("getDirListingMultiplePackets")) + { + myClient->requestOnceWithString("getDirListingMultiplePackets", dir); + myLastDirMatched = false; + myNewDirListing = true; + } + else + { + myClient->requestOnceWithString("getDirListing", dir); + } + +} + +AREXPORT void ArClientFileLister::changeToTopDir(void) +{ + myDataMutex.lock(); + myCurrentDir[0] = '\0'; + myWaitingForDir[0] = '\0'; + myDataMutex.unlock(); + //myClient->requestOnceWithString("getDirListing", ""); + getDirListing(""); + +} + +AREXPORT void ArClientFileLister::changeToDir(const char *dir) +{ + myDataMutex.lock(); + strcpy(myWaitingForDir, myCurrentDir); + if (myWaitingForDir[0] != '\0') + ArUtil::appendSlash(myWaitingForDir, sizeof(myWaitingForDir)); + strncat(myWaitingForDir, dir, + sizeof(myWaitingForDir) - strlen(myWaitingForDir)); + myLastRequested.setToNow(); + //printf("Getting %s\n", myWaitingForDir); + std::string waitingFor = myWaitingForDir; + myDataMutex.unlock(); + //myClient->requestOnceWithString("getDirListing", waitingFor.c_str()); + getDirListing(waitingFor.c_str()); +} + +AREXPORT void ArClientFileLister::changeToAbsDir(const char *dir) +{ + myDataMutex.lock(); + strncpy(myWaitingForDir, dir, sizeof(myWaitingForDir)); + myLastRequested.setToNow(); + //printf("Getting %s\n", myWaitingForDir); + std::string waitingFor = myWaitingForDir; + myDataMutex.unlock(); + //myClient->requestOnceWithString("getDirListing", waitingFor.c_str()); + getDirListing(waitingFor.c_str()); +} + +AREXPORT void ArClientFileLister::upOneDir() +{ + char *str; + myDataMutex.lock(); + + if ( ((str = strrchr(myCurrentDir, '/')) == NULL) && + ((str = strrchr(myCurrentDir, '\\')) == NULL) ) { + myDataMutex.unlock(); + return changeToTopDir(); + } // end if first level down + + strcpy(myWaitingForDir, myCurrentDir); + if (myWaitingForDir[0] != '\0') + { + ArUtil::appendSlash(myWaitingForDir, sizeof(myWaitingForDir)); + // chop off the last couple slashes (ie last directory) + if ((str = strrchr(myWaitingForDir, '/')) != NULL || + (str = strrchr(myWaitingForDir, '\\')) != NULL) + *str = '\0'; + if ((str = strrchr(myWaitingForDir, '/')) != NULL || + (str = strrchr(myWaitingForDir, '\\')) != NULL) { + *str = '\0'; + } + else { + myDataMutex.unlock(); + return changeToTopDir(); + } + } + myLastRequested.setToNow(); + std::string waitingFor = myWaitingForDir; + myDataMutex.unlock(); + //printf("Getting %s\n", myWaitingForDir); + //myClient->requestOnceWithString("getDirListing", waitingFor.c_str()); + getDirListing(waitingFor.c_str()); + +} + +AREXPORT const char *ArClientFileLister::getCurrentDir(void) const +{ + return myCurrentDir; +} + +AREXPORT const char *ArClientFileLister::getWaitingForDir(void) const +{ + return myWaitingForDir; +} + + +AREXPORT void ArClientFileLister::netGetDirListing(ArNetPacket *packet) +{ + char name[2048]; + char directory[2048]; + time_t atime; + time_t mtime; + ArTypes::UByte4 size = 0; + unsigned int num = 0; + unsigned int ret = 0; + unsigned int i = 0; + +// printf("Got packet...\n"); + myDataMutex.lock(); + ret = packet->bufToUByte2(); + if (ret != 0) + { + ArLog::log(ArLog::Normal, + "ArClientFileLister: Bad return for getDirListing of %d", ret); + myDataMutex.unlock(); + callUpdatedCallbacks(ret); + return; + } + packet->bufToStr(directory, sizeof(directory)); + ArLog::log(ArLog::Verbose, + "ArClientFileLister: Got dir listing for %s", directory); + + // if we got it but it wasn't the directory we were waiting for anymore then just skip + if (strcmp(myWaitingForDir, directory) != 0) + { + ArLog::log(ArLog::Normal, + "ArClientFileLister: Got directory '%s' instead of %s (probably fine)", + directory, + myWaitingForDir); + myDataMutex.unlock(); + callUpdatedCallbacks(-1); + return; + } + // dir was good, remember it and get rid of our old stuff + strcpy(myCurrentDir, directory); + + myDirectories.clear(); + myFiles.clear(); + num = packet->bufToUByte2(); + + for (i = 0; i < num; i++) + { + packet->bufToStr(name, sizeof(name)); + atime = packet->bufToUByte4(); + mtime = packet->bufToUByte4(); + size = packet->bufToUByte4(); + myDirectories.push_back(ArClientFileListerItem(name, atime, mtime, + size)); + } + num = packet->bufToUByte2(); + for (i = 0; i < num; i++) + { + packet->bufToStr(name, sizeof(name)); + atime = packet->bufToUByte4(); + mtime = packet->bufToUByte4(); + size = packet->bufToUByte4(); + myFiles.push_back(ArClientFileListerItem(name, atime, mtime, + size)); + } + + myDataMutex.unlock(); + callUpdatedCallbacks(0); +} + +AREXPORT void ArClientFileLister::netGetDirListingMultiplePackets( + ArNetPacket *packet) +{ + int type; + char name[2048]; + char directory[2048]; + time_t atime; + time_t mtime; + ArTypes::UByte4 size; + unsigned int num = 0; + + unsigned int ret = 0; + unsigned int i = 0; + + myDataMutex.lock(); + // if the packet is empty we're done with this one... + if (packet->getDataLength() == 0) + { + // if our last dir matched this is the end of a directory listing + if (myLastDirMatched) + { + myNewDirListing = true; + + myDataMutex.unlock(); + callUpdatedCallbacks(0); + } + // otherwise its from something we were ignoring + else + { + myDataMutex.unlock(); + } + return; + } + + ret = packet->bufToUByte2(); + if (ret != 0) + { + ArLog::log(ArLog::Normal, + "ArClientFileLister: Bad return for getDirListing of %d", ret); + myLastDirMatched = false; + myDataMutex.unlock(); + callUpdatedCallbacks(ret); + return; + } + packet->bufToStr(directory, sizeof(directory)); + // see if this is the dir we want + if (strcmp(myWaitingForDir, directory) == 0) + { + myLastDirMatched = true; + } + // if it wasn't the directory we were waiting for anymore then just skip + else + { + ArLog::log(ArLog::Normal, + "ArClientFileLister: Got directory '%s' instead of %s (probably fine)", + directory, + myWaitingForDir); + myLastDirMatched = false; + myDataMutex.unlock(); + callUpdatedCallbacks(-1); + return; + } + + + if (myNewDirListing) + { + // dir was good, remember it and get rid of our old stuff + strcpy(myCurrentDir, directory); + myDirectories.clear(); + myFiles.clear(); + myNewDirListing = false; + + } + /*** + else { + ArLog::log(ArLog::Verbose, + "ArClientFileLister: Continued dir listing (multiple packets) for %s (%s)", + directory, myCurrentDir); + + } + ***/ + + num = packet->bufToUByte2(); + + ArLog::log(ArLog::Verbose, + "ArClientFileLister: Got dir listing (multiple packets) for %s (num = %i)", + directory, num); + + + for (i = 0; i < num; i++) + { + type = packet->bufToByte(); + packet->bufToStr(name, sizeof(name)); + atime = packet->bufToUByte4(); + mtime = packet->bufToUByte4(); + size = packet->bufToUByte4(); + if (type == 1) + myDirectories.push_back(ArClientFileListerItem(name, atime, mtime, + size)); + else if (type == 2) + myFiles.push_back(ArClientFileListerItem(name, atime, mtime, + size)); + else + ArLog::log(ArLog::Normal, + "ArClientFileLister: Got unknown file type (%d) for file %s (ignoring it)", + type, name); + } + + + + myDataMutex.unlock(); +} + +AREXPORT void ArClientFileLister::log(bool withTimes) +{ + myDataMutex.lock(); + ArLog::log(ArLog::Normal, "In Directory '%s'", getCurrentDir()); + ArLog::log(ArLog::Normal, "%d directories:", myDirectories.size()); + logList(&myDirectories, withTimes); + ArLog::log(ArLog::Normal, "%d Files:", myFiles.size()); + logList(&myFiles, withTimes); + myDataMutex.unlock(); +} + +AREXPORT void ArClientFileLister::logList( + std::list *logThis, + bool withTimes) +{ + std::list::const_iterator it; + char buf[128]; + unsigned int i; + time_t itime; + + for (it = logThis->begin(); it != logThis->end(); it++) + { + ArLog::log(ArLog::Normal, "\t%s", (*it).getName()); + if (!withTimes) + continue; + itime = (*it).getLastAccessedTime(); + strcpy(buf, ctime(&itime)); + // chop the new lines off + for (i = 0; i < sizeof(buf); i++) + if (buf[i] == '\r' || buf[i] == '\n') + buf[i] = '\0'; + ArLog::log(ArLog::Normal, "\t\tlastModified:%s", buf); + itime = (*it).getLastModifiedTime(); + strcpy(buf, ctime(&itime)); + // chop the new lines off + for (i = 0; i < sizeof(buf); i++) + if (buf[i] == '\r' || buf[i] == '\n') + buf[i] = '\0'; + ArLog::log(ArLog::Normal, "\t\tlastAccess: %s", buf); + ArLog::log(ArLog::Normal, "\t\tbytes: %d", (*it).getSize()); + } +} + +AREXPORT std::list +ArClientFileLister::getDirectories(void) const +{ + return myDirectories; +} +AREXPORT std::list +ArClientFileLister::getFiles(void) const +{ + return myFiles; +} + + +AREXPORT void ArClientFileLister::addUpdatedCallback(ArFunctor1 *functor, + ArListPos::Pos position) +{ + myCallbackMutex.lock(); + if (position == ArListPos::FIRST) + myUpdatedCallbacks.push_front(functor); + else if (position == ArListPos::LAST) + myUpdatedCallbacks.push_back(functor); + else + ArLog::log(ArLog::Terse, + "ArClientFileListt::addUpdateCallback: Invalid position."); + myCallbackMutex.unlock(); + +} + +AREXPORT void ArClientFileLister::remUpdatedCallback(ArFunctor1 *functor) +{ + myCallbackMutex.lock(); + myUpdatedCallbacks.remove(functor); + myCallbackMutex.unlock(); +} + +AREXPORT void ArClientFileLister::callUpdatedCallbacks(int val) +{ + std::list *>::iterator it; + + myCallbackMutex.lock(); + for (it = myUpdatedCallbacks.begin(); it != myUpdatedCallbacks.end(); it++) + (*it)->invoke(val); + myCallbackMutex.unlock(); +} + +AREXPORT ArTime ArClientFileLister::getLastUpdated(void) +{ + ArTime ret; + myDataMutex.lock(); + ret = myLastUpdated; + myDataMutex.unlock(); + return ret; +} + +AREXPORT ArTime ArClientFileLister::getLastRequested(void) +{ + ArTime ret; + myDataMutex.lock(); + ret = myLastRequested; + myDataMutex.unlock(); + return ret; +} + +// ----------------------------------------------------------------------------- +// ArClientFileToClient +// ----------------------------------------------------------------------------- + +AREXPORT ArClientFileToClient::ArClientFileToClient(ArClientBase *client) : + myDataMutex(), + myCallbackMutex(), + myClient(client), + myIsWaitingForFile(false), + myDirectory(), + myFileName(), + myWholeFileName(), + myClientFileName(), + myFile(NULL), + myLastRequested(), + myLastReceived(), + myFileReceivedCallbacks(), + myGetFileCB(this, &ArClientFileToClient::netGetFile), + myGetFileWithTimestampCB(this, &ArClientFileToClient::netGetFileWithTimestamp) +{ + myDataMutex.setLogName("ArClientFileToClient::myDataMutex"); + myCallbackMutex.setLogName("ArClientFileToClient::myCallbackMutex"); + + if (myClient != NULL) { + myClient->addHandler("getFile", &myGetFileCB); + myClient->addHandler("getFileWithTimestamp", &myGetFileWithTimestampCB); + } +} + +AREXPORT ArClientFileToClient::~ArClientFileToClient() +{ + +} + +AREXPORT bool ArClientFileToClient::isAvailable(void) +{ + return ((myClient != NULL) && + ( myClient->dataExists("getFile") || + myClient->dataExists("getFileWithTimestamp") )); +} +AREXPORT bool ArClientFileToClient::isAvailableSetTimestamp(void) +{ + return ((myClient != NULL) && + (myClient->dataExists("getFileWithTimestamp"))); +} + + +AREXPORT bool ArClientFileToClient::getFileFromDirectory(const char *directory, + const char *fileName, + const char *clientFileName, + bool isSetTimestamp) +{ + myDataMutex.lock(); + if (fileName == NULL || clientFileName == NULL) + { + ArLog::log(ArLog::Terse, + "ArClientFileToClient: NULL fileName ('%s') or clientFileName ('%s')", + fileName, clientFileName); + myDataMutex.unlock(); + return false; + } + if (!isAvailable()) + { + ArLog::log(ArLog::Normal, "ArClientFileToClient::getFileFromDirectory: Tried to get file but the server doesn't support it."); + return false; + } + + if (myIsWaitingForFile) + { + ArLog::log(ArLog::Terse, + "ArClientFileToClient: already busy downloading a file '%s' cannot download '%s'", + myFileName.c_str(), fileName); + myDataMutex.unlock(); + return false; + } + if (directory != NULL) + myDirectory = directory; + else + myDirectory = ""; + myFileName = fileName; + myClientFileName = clientFileName; + + char *dirStr = NULL; + int dirLen; + if (directory != NULL) + { + dirLen = strlen(directory) + 2; + dirStr = new char[dirLen]; + strncpy(dirStr, directory, dirLen); + // make sure it has a slash + ArUtil::appendSlash(dirStr, dirLen); + // and that the slashes go a consistent direction + ArUtil::fixSlashes(dirStr, dirLen); + } + + int fileLen = strlen(fileName) + 1; + char *fileStr = new char[fileLen]; + strncpy(fileStr, fileName, fileLen); + // and that the slashes go a consistent direction + ArUtil::fixSlashes(fileStr, fileLen); + + if (directory == NULL) + myWholeFileName = ""; + else + myWholeFileName = dirStr; + + myWholeFileName += fileStr; + + ArNetPacket sendPacket; + sendPacket.strToBuf(myWholeFileName.c_str()); + sendPacket.uByte2ToBuf(0); + + if (isSetTimestamp && isAvailableSetTimestamp()) { + myClient->requestOnce("getFileWithTimestamp", &sendPacket); + } + else { + myClient->requestOnce("getFile", &sendPacket); + + if (isSetTimestamp) { + ArLog::log(ArLog::Normal, + "File timestamps are not available, using getFile"); + // TODO: Special return value? + } + } + + myIsWaitingForFile = true; + myLastRequested.setToNow(); + if (dirStr != NULL) + delete[] dirStr; + if (fileStr != NULL) + delete[] fileStr; + myDataMutex.unlock(); + return true; +} + +AREXPORT void ArClientFileToClient::netGetFile(ArNetPacket *packet) +{ + doGetFile(packet, false); +} + +AREXPORT void ArClientFileToClient::netGetFileWithTimestamp(ArNetPacket *packet) +{ + doGetFile(packet, true); +} + +AREXPORT void ArClientFileToClient::doGetFile(ArNetPacket *packet, + bool isSetTimestamp) +{ + char fileName[2048]; + // if its just the empty return packet at the end then don't worry about it + if (packet->getDataLength() == 0) + return; + + myDataMutex.lock(); + int ret = packet->bufToUByte2(); + packet->bufToStr(fileName, sizeof(fileName)); + ArUtil::fixSlashes(fileName, sizeof(fileName)); + if (ArUtil::strcasecmp(fileName, myWholeFileName) != 0) + { + ArLog::log(ArLog::Normal, + "Got data for a file ('%s') we don't want (we want '%s') (ret %d)", + fileName, myWholeFileName.c_str(), ret); + myDataMutex.unlock(); + return; + } + + if (ret != 0) + { + if (myFile != NULL) + { + fclose(myFile); + unlink(myClientFileName.c_str()); + myFile = NULL; + } + ArLog::log(ArLog::Normal, "ArClientFileToClient: Bad return %d on file %s", ret, fileName); + myIsWaitingForFile = false; + myLastReceived.setToNow(); + myDataMutex.unlock(); + callFileReceivedCallbacks(ret); + return; + } + + // Otherwise successful get... + + if (myFile == NULL) + { + ArLog::log(ArLog::Verbose, "Getting file %s", myFileName.c_str()); + if ((myFile = ArUtil::fopen(myClientFileName.c_str(), "wb")) == NULL) + { + ArLog::log(ArLog::Normal, "Can't open '%s' to put file into", + myClientFileName.c_str()); + myIsWaitingForFile = false; + myLastReceived.setToNow(); + myDataMutex.unlock(); + callFileReceivedCallbacks(-2); + return; + } + } + + ArTypes::UByte4 numBytes = 0; + char buf[32000]; + // file should be good here, so just write into it + numBytes = packet->bufToUByte4(); + + time_t modTime = -1; + if (isSetTimestamp) { + modTime = packet->bufToByte4(); + } + + if (numBytes == 0) + { + fclose(myFile); + + + if (isSetTimestamp) { + ArUtil::changeFileTimestamp(myClientFileName.c_str(), modTime); + } + + myFile = NULL; + myIsWaitingForFile = false; + ArLog::log(ArLog::Normal, "Received file %s", myFileName.c_str()); + myLastReceived.setToNow(); + myDataMutex.unlock(); + callFileReceivedCallbacks(0); + return; + } + else + { + ArLog::log(ArLog::Verbose, "Got %d bytes of file '%s'", + numBytes, myFileName.c_str()); + packet->bufToData(buf, numBytes); + fwrite(buf, 1, numBytes, myFile); + myDataMutex.unlock(); + } + +} + + + + + + +AREXPORT void ArClientFileToClient::addFileReceivedCallback( + ArFunctor1 *functor, ArListPos::Pos position) +{ + myCallbackMutex.lock(); + if (position == ArListPos::FIRST) + myFileReceivedCallbacks.push_front(functor); + else if (position == ArListPos::LAST) + myFileReceivedCallbacks.push_back(functor); + else + ArLog::log(ArLog::Terse, + "ArClientFileToClient::addUpdateCallback: Invalid position."); + myCallbackMutex.unlock(); +} + +AREXPORT void ArClientFileToClient::remFileReceivedCallback( + ArFunctor1 *functor) +{ + myCallbackMutex.lock(); + myFileReceivedCallbacks.remove(functor); + myCallbackMutex.unlock(); +} + +AREXPORT void ArClientFileToClient::callFileReceivedCallbacks(int val) +{ + std::list *>::iterator it; + myCallbackMutex.lock(); + for (it = myFileReceivedCallbacks.begin(); it != myFileReceivedCallbacks.end(); it++) + (*it)->invoke(val); + myCallbackMutex.unlock(); +} + +AREXPORT const char *ArClientFileToClient::getDirectory(void) +{ + std::string ret; + myDataMutex.lock(); + ret = myDirectory; + myDataMutex.unlock(); + return ret.c_str(); +} + +AREXPORT const char *ArClientFileToClient::getFileName(void) +{ + std::string ret; + myDataMutex.lock(); + ret = myFileName; + myDataMutex.unlock(); + return ret.c_str(); +} + +AREXPORT const char *ArClientFileToClient::getClientFileName(void) +{ + std::string ret; + myDataMutex.lock(); + ret = myClientFileName; + myDataMutex.unlock(); + return ret.c_str(); +} + +AREXPORT void ArClientFileToClient::cancelGet(void) +{ + // Removed the following line because it causes the received packets + // to be dropped, and the file getter remains permanently in the + // waiting for file state. + // myWholeFileName = ""; + // TODO! +} + +AREXPORT bool ArClientFileToClient::isWaitingForFile(void) +{ + bool ret; + myDataMutex.lock(); + ret = myIsWaitingForFile; + myDataMutex.unlock(); + return ret; +} + + +AREXPORT ArTime ArClientFileToClient::getLastReceived(void) +{ + ArTime ret; + myDataMutex.lock(); + ret = myLastReceived; + myDataMutex.unlock(); + return ret; +} + +AREXPORT ArTime ArClientFileToClient::getLastRequested(void) +{ + ArTime ret; + myDataMutex.lock(); + ret = myLastRequested; + myDataMutex.unlock(); + return ret; +} + + +AREXPORT ArClientFileFromClient::ArClientFileFromClient(ArClientBase *client) : + myDataMutex(), + myCallbackMutex(), + myClient(client), + myIsWaitingForReturn(false), + myInterleaved(false), + myTimestamp(false), + myCommandName(), + myDirectory(), + myFileName(), + myWholeFileName(), + myClientFileName(), + myReadyForNextPacket(false), + myFile(), + myLastStartedSend(), + myLastCompletedSend(), + myFileSentCallbacks(), + myPutFileCB(this, &ArClientFileFromClient::netPutFile) +{ + myDataMutex.setLogName("ArClientFileFromClient::myDataMutex"); + myCallbackMutex.setLogName("ArClientFileFromClient::myCallbackMutex"); + + if (myClient != NULL) { + myClient->addHandler("putFile", &myPutFileCB); + myClient->addHandler("putFileInterleaved", &myPutFileCB); + myClient->addHandler("putFileWithTimestamp", &myPutFileCB); + myClient->addHandler("putFileWithTimestampInterleaved", &myPutFileCB); + } +} + + +AREXPORT ArClientFileFromClient::~ArClientFileFromClient() +{ + +} + +AREXPORT bool ArClientFileFromClient::isAvailable(void) +{ + return (myClient->dataExists("putFile") || + myClient->dataExists("putFileInterleaved") || + myClient->dataExists("putFileWithTimestamp") || + myClient->dataExists("putFileWithTimestampInterleaved")); +} + +AREXPORT bool ArClientFileFromClient::isAvailableSetTimestamp() +{ + return((myClient != NULL) && ( myClient->dataExists("putFileWithTimestamp") || myClient->dataExists("putFileWithTimestampInterleaved") ) ); +} + +AREXPORT bool ArClientFileFromClient::isAvailableSlow(void) +{ + return myClient->dataExists("putFileInterleaved"); +} + +AREXPORT bool ArClientFileFromClient::isAvailableFast(void) +{ + return myClient->dataExists("putFile"); +} + +AREXPORT bool ArClientFileFromClient::putFileToDirectory + (const char *directory, + const char *fileName, + const char *clientFileName, + SendSpeed sendSpeed, + bool isSetTimestamp) +{ + bool interleaved; + + myDataMutex.lock(); + if (fileName == NULL || fileName[0] == '\0' || + clientFileName == NULL || clientFileName[0] == '\0') + { + ArLog::log(ArLog::Terse, + "ArClientFileFromClient: NULL or empty fileName ('%s') or clientFileName ('%s')", + fileName, clientFileName); + myDataMutex.unlock(); + return false; + } + if (myIsWaitingForReturn) + { + ArLog::log(ArLog::Terse, + "ArClientFileFromClient: already busy uploading a file '%s' cannot upload '%s'", + myFileName.c_str(), fileName); + myDataMutex.unlock(); + return false; + } + + myCommandName = ""; + + if (!isSetTimestamp) { + + if (myClient->dataExists("putFile") && + (sendSpeed == SPEED_FAST || sendSpeed == SPEED_AUTO)) + { + myInterleaved = false; + myTimestamp = false; + myCommandName = "putFile"; + } + else if (myClient->dataExists("putFileInterleaved") && + (sendSpeed == SPEED_SLOW || sendSpeed == SPEED_AUTO)) + { + myInterleaved = true; + myTimestamp = false; + myReadyForNextPacket = false; + myCommandName = "putFileInterleaved"; + } + } + else { // is set timestamp + + if (myClient->dataExists("putFileWithTimestamp") && + (sendSpeed == SPEED_FAST || sendSpeed == SPEED_AUTO)) + { + myInterleaved = false; + myTimestamp = true; + myCommandName = "putFileWithTimestamp"; + } + else if (myClient->dataExists("putFileWithTimestampInterleaved") && + (sendSpeed == SPEED_SLOW || sendSpeed == SPEED_AUTO)) + { + myInterleaved = true; + myTimestamp = true; + myReadyForNextPacket = false; + myCommandName = "putFileWithTimestampInterleaved"; + } + + } // end else set timestamp + + if (ArUtil::isStrEmpty(myCommandName.c_str())) { + + ArLog::log(ArLog::Normal, "ArClientFileFromClient::putFileToDirectory: Tried to put file but the server doesn't support it (or doesn't support it at the speed requested)."); + myDataMutex.unlock(); + return false; + } + + interleaved = myInterleaved; + + if (directory != NULL) + myDirectory = directory; + else + myDirectory = ""; + myFileName = fileName; + myClientFileName = clientFileName; + + char *dirStr = NULL; + int dirLen; + if (directory != NULL) + { + dirLen = strlen(directory) + 2; + dirStr = new char[dirLen]; + strncpy(dirStr, directory, dirLen); + // make sure it has a slash + ArUtil::appendSlash(dirStr, dirLen); + // and that the slashes go a consistent direction + ArUtil::fixSlashes(dirStr, dirLen); + } + + int fileLen = strlen(fileName) + 1; + char *fileStr = new char[fileLen]; + strncpy(fileStr, fileName, fileLen); + // and that the slashes go a consistent direction + ArUtil::fixSlashes(fileStr, fileLen); + + if (directory == NULL) + myWholeFileName = ""; + else + myWholeFileName = dirStr; + + myWholeFileName += fileStr; + + myIsWaitingForReturn = true; + myLastStartedSend.setToNow(); + if (dirStr != NULL) + delete[] dirStr; + if (fileStr != NULL) + delete[] fileStr; + + ArNetPacket sendPacket; + + FILE *file; + if ((file = ArUtil::fopen(myClientFileName.c_str(), "rb")) == NULL) + { + ArLog::log(ArLog::Normal, + "ArClientFileFromClient::putFile: can't open file '%s'", + clientFileName); + myIsWaitingForReturn = false; + myDataMutex.unlock(); + return false; + } + myDataMutex.unlock(); + // tell the server we're sending + + sendPacket.empty(); + sendPacket.uByte2ToBuf(0); + sendPacket.strToBuf(myWholeFileName.c_str()); + + if (myTimestamp) { + + struct stat fileStat; + time_t timestamp; + + if (stat(myWholeFileName.c_str(), &fileStat) == 0) { + timestamp = fileStat.st_mtime; + } + else { + time(×tamp); + } + + sendPacket.byte4ToBuf(timestamp); + + } // end if timestamp + + myClient->requestOnce(myCommandName.c_str(), &sendPacket); + ArLog::log(ArLog::Normal, "Starting send of file %s", + myWholeFileName.c_str()); + + char buf[30000]; + size_t ret; + + ArTime started; + started.setToNow(); + + // now send the file + while ((ret = fread(buf, 1, sizeof(buf), file)) == sizeof(buf)) + { + // if we're interleaved wait for the next packet + if (interleaved) + { + myDataMutex.lock(); + + // myReadyForNextPacket is set to true when the response is received + // from the server. + while (!myReadyForNextPacket) + { + if (!myIsWaitingForReturn) + { + ArLog::log(ArLog::Normal, + "ArFileFromClient::putFileToDirectory: Put was cancelled or failed."); + myDataMutex.unlock(); + return false; + } + myDataMutex.unlock(); + ArUtil::sleep(1); + + if (started.secSince() > 30) + { + myDataMutex.lock(); + myIsWaitingForReturn = false; + myDataMutex.unlock(); + + ArLog::log(ArLog::Normal, + "ArFileFromClient::putFileToDirectory: No return from client within 30 seconds, failing put."); + return false; + } + myDataMutex.lock(); + + } // end while not ready for next packet + + // Reset the flag so we'll wait for a response during the next loop iteration. + myReadyForNextPacket = false; + + myDataMutex.unlock(); + + } // end if interleaved + + // Reset the time this packet was sent. + started.setToNow(); + + sendPacket.empty(); + sendPacket.uByte2ToBuf(1); + sendPacket.strToBuf(myWholeFileName.c_str()); + sendPacket.uByte4ToBuf(ret); + sendPacket.dataToBuf(buf, ret); + myClient->requestOnce(myCommandName.c_str(), &sendPacket); + //ArLog::log(ArLog::Normal, "Sent packet with %d", ret); + + } // end while more to read... + + if (feof(file)) + { + //printf("end of file\n"); + } + if (ferror(file)) + { + ArLog::log(ArLog::Normal, "ArServerFileFromClient: Error sending file %s", + fileName); + sendPacket.empty(); + sendPacket.uByte2ToBuf(3); + sendPacket.strToBuf(myWholeFileName.c_str()); + myClient->requestOnce(myCommandName.c_str(), &sendPacket); + myDataMutex.lock(); + myIsWaitingForReturn = false; + myDataMutex.unlock(); + return false; + } + + sendPacket.empty(); + sendPacket.uByte2ToBuf(1); + sendPacket.strToBuf(myWholeFileName.c_str()); + sendPacket.uByte4ToBuf(ret); + sendPacket.dataToBuf(buf, ret); + myClient->requestOnce(myCommandName.c_str(), &sendPacket); + //ArLog::log(ArLog::Verbose, "Sent packet with %d", ret); + + + sendPacket.empty(); + sendPacket.uByte2ToBuf(2); + sendPacket.strToBuf(myWholeFileName.c_str()); + myClient->requestOnce(myCommandName.c_str(), &sendPacket); + + if (feof(file)) + { + ArLog::log(ArLog::Normal, "ArServerFileToClient: Sent file %s", fileName); + } + + fclose(file); + return true; +} + +AREXPORT void ArClientFileFromClient::netPutFile(ArNetPacket *packet) +{ + int ret = 0; + bool done = false; + char fileName[2048]; + + myDataMutex.lock(); + if (!myIsWaitingForReturn) + { + myDataMutex.unlock(); + return; + } + ret = packet->bufToUByte2(); + packet->bufToStr(fileName, sizeof(fileName)); + if (myInterleaved && ret == 10) + { + done = false; + myReadyForNextPacket = true; + } + else + { + done = true; + myIsWaitingForReturn = false; + } + myDataMutex.unlock(); + if (done) + callFileSentCallbacks(ret); +} + + +AREXPORT void ArClientFileFromClient::addFileSentCallback( + ArFunctor1 *functor, ArListPos::Pos position) +{ + myCallbackMutex.lock(); + if (position == ArListPos::FIRST) + myFileSentCallbacks.push_front(functor); + else if (position == ArListPos::LAST) + myFileSentCallbacks.push_back(functor); + else + ArLog::log(ArLog::Terse, + "ArClientFileFromClient::addUpdateCallback: Invalid position."); + myCallbackMutex.unlock(); +} + +AREXPORT void ArClientFileFromClient::remFileSentCallback( + ArFunctor1 *functor) +{ + myCallbackMutex.lock(); + myFileSentCallbacks.remove(functor); + myCallbackMutex.unlock(); +} + +AREXPORT void ArClientFileFromClient::callFileSentCallbacks(int val) +{ + std::list *>::iterator it; + myCallbackMutex.lock(); + for (it = myFileSentCallbacks.begin(); it != myFileSentCallbacks.end(); it++) + (*it)->invoke(val); + myCallbackMutex.unlock(); +} + +AREXPORT const char *ArClientFileFromClient::getDirectory(void) +{ + std::string ret; + myDataMutex.lock(); + ret = myDirectory; + myDataMutex.unlock(); + return ret.c_str(); +} + +AREXPORT const char *ArClientFileFromClient::getFileName(void) +{ + std::string ret; + myDataMutex.lock(); + ret = myFileName; + myDataMutex.unlock(); + return ret.c_str(); +} + +AREXPORT const char *ArClientFileFromClient::getClientFileName(void) +{ + std::string ret; + myDataMutex.lock(); + ret = myClientFileName; + myDataMutex.unlock(); + return ret.c_str(); +} + +AREXPORT void ArClientFileFromClient::cancelPut(void) +{ + ArNetPacket sendPacket; + + myDataMutex.lock(); + if (myIsWaitingForReturn) + { + myIsWaitingForReturn = false; + + sendPacket.uByte2ToBuf(3); + sendPacket.strToBuf(myWholeFileName.c_str()); + myClient->requestOnce(myCommandName.c_str(), &sendPacket); + } + myDataMutex.unlock(); +} + +AREXPORT bool ArClientFileFromClient::isWaitingForReturn(void) +{ + bool ret; + myDataMutex.lock(); + ret = myIsWaitingForReturn; + myDataMutex.unlock(); + return ret; +} + +AREXPORT ArTime ArClientFileFromClient::getLastCompletedSend(void) +{ + ArTime ret; + myDataMutex.lock(); + ret = myLastCompletedSend; + myDataMutex.unlock(); + return ret; +} + +AREXPORT ArTime ArClientFileFromClient::getLastStartedSend(void) +{ + ArTime ret; + myDataMutex.lock(); + ret = myLastStartedSend; + myDataMutex.unlock(); + return ret; +} + +AREXPORT ArClientDeleteFileOnServer::ArClientDeleteFileOnServer( + ArClientBase *client) : + myDeleteFileCB(this, &ArClientDeleteFileOnServer::netDeleteFile) +{ + myDataMutex.setLogName("ArClientDeleteFileOnServer::myDataMutex"); + myCallbackMutex.setLogName("ArClientDeleteFileOnServer::myCallbackMutex"); + myClient = client; + myClient->addHandler("deleteFile", &myDeleteFileCB); + myIsWaitingForReturn = false; +} + +AREXPORT ArClientDeleteFileOnServer::~ArClientDeleteFileOnServer() +{ + +} + +AREXPORT bool ArClientDeleteFileOnServer::isAvailable(void) +{ + return myClient->dataExists("deleteFile"); +} + +AREXPORT bool ArClientDeleteFileOnServer::deleteFileFromDirectory( + const char *directory, const char *fileName) +{ + myDataMutex.lock(); + if (fileName == NULL || fileName[0] == '\0') + { + ArLog::log(ArLog::Terse, + "ArClientDeleteFileOnServer: NULL or empty fileName ('%s')", + fileName); + myDataMutex.unlock(); + return false; + } + if (!isAvailable()) + { + ArLog::log(ArLog::Normal, "ArClientDeleteFileOnServer::deleteFileFromDirectory: Tried to delete file but the server doesn't support it."); + return false; + } + + if (myIsWaitingForReturn) + { + ArLog::log(ArLog::Terse, + "ArClientDeleteFileOnServer: already busy deleting a file '%s' cannot delete '%s'", + myFileName.c_str(), fileName); + myDataMutex.unlock(); + return false; + } + if (directory != NULL) + myDirectory = directory; + else + myDirectory = ""; + myFileName = fileName; + + char *dirStr = NULL; + int dirLen; + if (directory != NULL) + { + dirLen = strlen(directory) + 2; + dirStr = new char[dirLen]; + strncpy(dirStr, directory, dirLen); + // make sure it has a slash + ArUtil::appendSlash(dirStr, dirLen); + // and that the slashes go a consistent direction + ArUtil::fixSlashes(dirStr, dirLen); + } + + int fileLen = strlen(fileName) + 1; + char *fileStr = new char[fileLen]; + strncpy(fileStr, fileName, fileLen); + // and that the slashes go a consistent direction + ArUtil::fixSlashes(fileStr, fileLen); + + if (directory == NULL) + myWholeFileName = ""; + else + myWholeFileName = dirStr; + + myWholeFileName += fileStr; + + myIsWaitingForReturn = true; + myLastStartedSend.setToNow(); + if (dirStr != NULL) + delete[] dirStr; + if (fileStr != NULL) + delete[] fileStr; + + ArNetPacket sendPacket; + + myDataMutex.unlock(); + // tell the server to delete it + + sendPacket.empty(); + sendPacket.strToBuf(myWholeFileName.c_str()); + myClient->requestOnce("deleteFile", &sendPacket); + ArLog::log(ArLog::Normal, "Requested delete of file %s", + myWholeFileName.c_str()); + return true; +} + +AREXPORT void ArClientDeleteFileOnServer::netDeleteFile(ArNetPacket *packet) +{ + int ret; + char fileName[2048]; + + myDataMutex.lock(); + if (!myIsWaitingForReturn) + { + myDataMutex.unlock(); + return; + } + ret = packet->bufToUByte2(); + packet->bufToStr(fileName, sizeof(fileName)); + //printf("Ret of '%s' is %d\n", fileName, ret); + myIsWaitingForReturn = 0; + myDataMutex.unlock(); + callFileDeletedCallbacks(ret); +} + + +AREXPORT void ArClientDeleteFileOnServer::addFileDeletedCallback( + ArFunctor1 *functor, ArListPos::Pos position) +{ + myCallbackMutex.lock(); + if (position == ArListPos::FIRST) + myFileDeletedCallbacks.push_front(functor); + else if (position == ArListPos::LAST) + myFileDeletedCallbacks.push_back(functor); + else + ArLog::log(ArLog::Terse, + "ArClientDeleteFileOnServer::addUpdateCallback: Invalid position."); + myCallbackMutex.unlock(); +} + +AREXPORT void ArClientDeleteFileOnServer::remFileDeletedCallback( + ArFunctor1 *functor) +{ + myCallbackMutex.lock(); + myFileDeletedCallbacks.remove(functor); + myCallbackMutex.unlock(); +} + +AREXPORT void ArClientDeleteFileOnServer::callFileDeletedCallbacks(int val) +{ + std::list *>::iterator it; + + myCallbackMutex.lock(); + for (it = myFileDeletedCallbacks.begin(); + it != myFileDeletedCallbacks.end(); + it++) + (*it)->invoke(val); + myCallbackMutex.unlock(); +} + +AREXPORT const char *ArClientDeleteFileOnServer::getDirectory(void) +{ + std::string ret; + myDataMutex.lock(); + ret = myDirectory; + myDataMutex.unlock(); + return ret.c_str(); +} + +AREXPORT const char *ArClientDeleteFileOnServer::getFileName(void) +{ + std::string ret; + myDataMutex.lock(); + ret = myFileName; + myDataMutex.unlock(); + return ret.c_str(); +} + +AREXPORT bool ArClientDeleteFileOnServer::isWaitingForReturn(void) +{ + bool ret; + myDataMutex.lock(); + ret = myIsWaitingForReturn; + myDataMutex.unlock(); + return ret; +} + +AREXPORT ArTime ArClientDeleteFileOnServer::getLastCompletedSend(void) +{ + ArTime ret; + myDataMutex.lock(); + ret = myLastCompletedSend; + myDataMutex.unlock(); + return ret; +} + +AREXPORT ArTime ArClientDeleteFileOnServer::getLastStartedSend(void) +{ + ArTime ret; + myDataMutex.lock(); + ret = myLastStartedSend; + myDataMutex.unlock(); + return ret; +} + diff --git a/Legacy/Aria/ArNetworking/src/ArClientHandlerConfig.cpp b/Legacy/Aria/ArNetworking/src/ArClientHandlerConfig.cpp new file mode 100644 index 0000000..20bb5db --- /dev/null +++ b/Legacy/Aria/ArNetworking/src/ArClientHandlerConfig.cpp @@ -0,0 +1,1139 @@ +#include "Aria.h" +#include "ArExport.h" +#include "ArClientHandlerConfig.h" +#include "ArClientArgUtils.h" + +//#define ARDEBUG_CLIENTHANDLERCONFIG + +#if (defined(_DEBUG) && defined(ARDEBUG_CLIENTHANDLERCONFIG)) +#define IFDEBUG(code) {code;} +#else +#define IFDEBUG(code) +#endif + +/** + @param client the client base to attach to + @param ignoreBounds whether the ArConfig we have should ignore bounds or not, this should only be used for debugging + @param robotName a name or identifier for the robot the server is controlling, used for logging etc. +*/ +AREXPORT ArClientHandlerConfig::ArClientHandlerConfig(ArClientBase *client, + bool ignoreBounds, + const char *robotName, + const char *logPrefix) : + myRobotName((robotName != NULL) ? robotName : ""), + myLogPrefix((logPrefix != NULL) ? logPrefix : ""), + + myGotConfigCBList(), + mySaveConfigSucceededCBList(), + mySaveConfigFailedCBList(), + myGotConfigDefaultsCBList(), + myGotLastEditablePriorityCBList(), + + myClient(client), + + myConfig(NULL, + false, + ignoreBounds), + myDefaultConfig(NULL), + myLastEditablePriority(ArPriority::LAST_PRIORITY), + + myDataMutex(), + myCallbackMutex(), + + myHaveRequestedLastEditablePriority(false), + myHaveGottenLastEditablePriority(false), + myHaveRequestedConfig(false), + myHaveGottenConfig(false), + myHaveRequestedDefaults(false), + myHaveGottenDefaults(false), + myHaveRequestedDefaultCopy(false), + + myIsQuiet(false), + + myHandleGetConfigBySectionsV3CB + (this, &ArClientHandlerConfig::handleGetConfigBySectionsV3), + myHandleGetConfigBySectionsV2CB + (this, &ArClientHandlerConfig::handleGetConfigBySectionsV2), + myHandleGetConfigBySectionsCB + (this, &ArClientHandlerConfig::handleGetConfigBySections), + myHandleGetConfigCB(this, &ArClientHandlerConfig::handleGetConfig), + myHandleSetConfigCB(this, &ArClientHandlerConfig::handleSetConfig), + myHandleSetConfigBySectionsCB(this, &ArClientHandlerConfig::handleSetConfigBySections), + myHandleSetConfigBySectionsV2CB(this, &ArClientHandlerConfig::handleSetConfigBySectionsV2), + myHandleGetConfigDefaultsCB + (this, &ArClientHandlerConfig::handleGetConfigDefaults), + myHandleGetConfigSectionFlagsCB + (this, &ArClientHandlerConfig::handleGetConfigSectionFlags), + myHandleGetLastEditablePriorityCB + (this, &ArClientHandlerConfig::handleGetLastEditablePriority) + +{ + myDataMutex.setLogName("ArClientConfigHandler::myDataMutex"); + myCallbackMutex.setLogName("ArClientConfigHandler::myCallbackMutex"); + + if ((logPrefix == NULL) && !myRobotName.empty()) { + myLogPrefix = myRobotName + ": "; + } + + myConfig.setConfigName("Server", myRobotName.c_str()); + +} + +AREXPORT ArClientHandlerConfig::~ArClientHandlerConfig() +{ + if (myDefaultConfig != NULL) + delete myDefaultConfig; +} + +/** + This requests the config from the server. The handler's internal state is + reset to indicate that the config hasn't been received. + + If the server supports editable priority levels and the client wishes to + receive parameters of ineditable priorities, then the method + requestLastEditablePriority should be called (and completed) before + requestConfigFromServer is called. + **/ +AREXPORT void ArClientHandlerConfig::requestConfigFromServer(void) +{ + char *getConfigPacketName = "getConfigBySectionsV3"; + bool isInsertPriority = true; + bool isInsertRestartLevel = true; + + ArFunctor1C *getConfigCB = &myHandleGetConfigBySectionsV3CB; + + if (!myClient->dataExists(getConfigPacketName)) { + + getConfigPacketName = "getConfigBySectionsV2"; + getConfigCB = &myHandleGetConfigBySectionsV2CB; + + if (!myClient->dataExists(getConfigPacketName)) { + + getConfigPacketName = "getConfigBySections"; + isInsertRestartLevel = false; + + getConfigCB = &myHandleGetConfigBySectionsCB; + + if (!myClient->dataExists(getConfigPacketName)) { + getConfigPacketName = "getConfig"; + isInsertPriority = false; + + getConfigCB = &myHandleGetConfigCB; + + } // end if packet name does not exist + } // end if + + } // end if packet name does not exist + + char *setConfigPacketName = "setConfigBySectionsV2"; + ArFunctor1C *setConfigCB = &myHandleSetConfigBySectionsV2CB; + + if (!myClient->dataExists(setConfigPacketName)) { + + setConfigPacketName = "setConfigBySections"; + + setConfigCB = &myHandleSetConfigBySectionsCB; + + if (!myClient->dataExists(setConfigPacketName)) { + + setConfigPacketName = "setConfig"; + + setConfigCB = &myHandleSetConfigCB; + + } // end if packet name does not exist + + } // end if packet name does not exist + + myDataMutex.lock(); + ArLog::log(ArLog::Normal, "%sRequesting config from server (with %s, save with %s)", + myLogPrefix.c_str(), getConfigPacketName, setConfigPacketName); + myConfig.clearSections(); + myDataMutex.unlock(); + + myClient->remHandler(getConfigPacketName, getConfigCB); + myClient->addHandler(getConfigPacketName, getConfigCB); + + myClient->remHandler(setConfigPacketName, setConfigCB); + myClient->addHandler(setConfigPacketName, setConfigCB); + + if (myClient->dataExists("getConfigDefaults")) { + myClient->remHandler("getConfigDefaults", &myHandleGetConfigDefaultsCB); + myClient->addHandler("getConfigDefaults", &myHandleGetConfigDefaultsCB); + } + + if (myClient->dataExists("getConfigSectionFlags")) + { + myClient->remHandler("getConfigSectionFlags", + &myHandleGetConfigSectionFlagsCB); + myClient->addHandler("getConfigSectionFlags", + &myHandleGetConfigSectionFlagsCB); + myClient->requestOnce("getConfigSectionFlags"); + } + + bool isInsertLastEditablePriority = true; + if (!myClient->dataExists("getLastEditablePriority")) { + isInsertLastEditablePriority = false; + } + else if (!myHaveGottenLastEditablePriority) { + isInsertLastEditablePriority = false; + ArLog::log(ArLog::Terse, + "%sConfig requested but last editable priority not yet received, using old protocol", + myLogPrefix.c_str()); + } // end else if last editable priority not received + + + if (isInsertPriority) { + ArLog::log(ArLog::Verbose, + "%sRequesting that config has last priority %s", + myLogPrefix.c_str(), + ArPriority::getPriorityName(ArPriority::LAST_PRIORITY)); + + ArNetPacket packet; + packet.byteToBuf(ArPriority::LAST_PRIORITY); + + if (isInsertLastEditablePriority) { + ArLog::log(ArLog::Verbose, + "%sRequesting that config has last editable priority %s", + myLogPrefix.c_str(), + ArPriority::getPriorityName(myLastEditablePriority)); + packet.byteToBuf(myLastEditablePriority); + } + + myClient->requestOnce(getConfigPacketName, &packet); + } + else { // don't insert priority + myClient->requestOnce(getConfigPacketName); + } // end else don't insert priority + + myDataMutex.lock(); + myHaveGottenConfig = false; + myDataMutex.unlock(); +} + +AREXPORT void ArClientHandlerConfig::handleGetConfigBySectionsV3(ArNetPacket *packet) +{ + handleGetConfigData(packet, true, 3); +} + +AREXPORT void ArClientHandlerConfig::handleGetConfigBySectionsV2(ArNetPacket *packet) +{ + handleGetConfigData(packet, true, 2); +} + +AREXPORT void ArClientHandlerConfig::handleGetConfigBySections(ArNetPacket *packet) +{ + handleGetConfigData(packet, true, 1); +} + +AREXPORT void ArClientHandlerConfig::handleGetConfig(ArNetPacket *packet) +{ + handleGetConfigData(packet, false, 0); +} + +AREXPORT void ArClientHandlerConfig::handleGetConfigData(ArNetPacket *packet, + bool isMultiplePackets, + int version) +{ + char name[32000]; + char comment[32000]; + char categoryName[512]; + + char type; + std::string section; + + // The multiple packets method also sends display hints with the parameters; + // the old single packet method does not. + ArClientArg clientArg(isMultiplePackets, + ArPriority::LAST_PRIORITY, + version); + bool isEmptyPacket = true; + + myDataMutex.lock(); + + while (packet->getDataReadLength() < packet->getDataLength()) + { + isEmptyPacket = false; + + type = packet->bufToByte(); + + if (type == 'S') + { + packet->bufToStr(name, sizeof(name)); + packet->bufToStr(comment, sizeof(comment)); + + if (version >= 2) { + packet->bufToStr(categoryName, sizeof(categoryName)); + int index = 1; + + if (version >= 3) { + + index = packet->bufToUByte2(); + } + if (index <= 1) { + ArLog::log(ArLog::Verbose, "%sReceiving config section %s, %s...", + myLogPrefix.c_str(), categoryName, name); + + myConfig.addSection(categoryName, name, comment); + } + else { + ArLog::log(ArLog::Verbose, "%sAppending to config section %s, %s (packet %i)...", + myLogPrefix.c_str(), categoryName, name, index); + + } + } + else { + ArLog::log(ArLog::Verbose, "%sReceiving config section %s...", + myLogPrefix.c_str(), name); + myConfig.setSectionComment(name, comment); + } + //printf("%c %s %s\n", type, name, comment); + + + + section = name; + + } + else if (type == 'P') + { + ArConfigArg configArg; + + bool isSuccess = clientArg.createArg(packet, + configArg); + + if (isSuccess) { + myConfig.addParamAsIs(configArg, + section.c_str()); + } + else + { + ArLog::log(ArLog::Terse, "ArClientHandlerConfig unknown param type"); + } + } + else // unrecognized header + { + ArLog::log(ArLog::Terse, "ArClientHandlerConfig unknown type"); + } + + } // end while more to read + + if (!isMultiplePackets || isEmptyPacket) { + + ArLog::log(ArLog::Normal, "%sGot config from server.", myLogPrefix.c_str()); + + // KMC 1/22/13 To only log some of the config, substitute the commented + // lines below for the following config->log statement. + IFDEBUG(myConfig.log()); + /*** + std::list sectionNameList; + sectionNameList.push_back("Data Log Settings"); + IFDEBUG(myConfig.log(false, §ionNameList, myLogPrefix.c_str())); + ****/ + + myHaveGottenConfig = true; + } + + myDataMutex.unlock(); + + + + if (myHaveGottenConfig) { + + myCallbackMutex.lock(); + + for (std::list::iterator it = myGotConfigCBList.begin(); + it != myGotConfigCBList.end(); + it++) { + (*it)->invoke(); + } + myCallbackMutex.unlock(); + + } // end if config received + +} // end method handleGetConfigData + +AREXPORT void ArClientHandlerConfig::handleGetConfigSectionFlags( + ArNetPacket *packet) +{ + int numSections = packet->bufToByte4(); + + int i; + + char section[32000]; + char flags[32000]; + + myDataMutex.lock(); + for (i = 0; i < numSections; i++) + { + packet->bufToStr(section, sizeof(section)); + packet->bufToStr(flags, sizeof(flags)); + myConfig.addSectionFlags(section, flags); + } + myDataMutex.unlock(); +} + +AREXPORT void ArClientHandlerConfig::saveConfigToServer(void) +{ + saveConfigToServer(&myConfig); +} + +AREXPORT void ArClientHandlerConfig::saveConfigToServer( + ArConfig *config, + const std::set *ignoreTheseSections) +{ + //ArConfigArg param; + ArClientArg clientArg; + + bool isMultiplePackets = true; + int version = 2; + char *setConfigPacketName = "setConfigBySectionsV2"; + if (!myClient->dataExists(setConfigPacketName)) { + + setConfigPacketName = "setConfigBySections"; + version = 1; + + if (!myClient->dataExists(setConfigPacketName)) { + version = 0; + isMultiplePackets = false; + setConfigPacketName = "setConfig"; + } + } + + ArNetPacket sending; + ArLog::log(ArLog::Normal, + "%sSaving config to server (with %s)", + myLogPrefix.c_str(), setConfigPacketName); + + + // KMC 1/22/13 To only log some of the config, substitute the commented + // lines below for the following config->log statement. + IFDEBUG(config->log(false, NULL, myLogPrefix.c_str())); + /*** + std::list sectionNameList; + sectionNameList.push_back("Data Log Settings"); + IFDEBUG(config->log(false, §ionNameList, myLogPrefix.c_str())); + ***/ + + + myDataMutex.lock(); + bool isSuccess = true; + std::list *sections = config->getSections(); + for (std::list::iterator sIt = sections->begin(); + (isSuccess && (sIt != sections->end())); + sIt++) + { + ArConfigSection *section = (*sIt); + // if we're ignoring sections and we're ignoring this one, then + // don't send it + if (ignoreTheseSections != NULL && + (ignoreTheseSections->find(section->getName()) != + ignoreTheseSections->end())) + { + ArLog::log(ArLog::Verbose, "Not sending section %s", + section->getName()); + continue; + } + sending.strToBuf("Section"); + sending.strToBuf(section->getName()); + std::list *params = section->getParams(); + + for (std::list::iterator pIt = params->begin(); + pIt != params->end(); + pIt++) + { + ArConfigArg ¶m = (*pIt); + + if (!clientArg.isSendableParamType(param)) { + continue; + } + + clientArg.addArgTextToPacket(param, &sending); + + //sending.strToBuf(param.getName()); + + //clientArg.argTextToBuf(param, &sending); + + } // end for each param + + if (isMultiplePackets) { + + if (!myClient->requestOnce(setConfigPacketName, &sending)) { + + isSuccess = false; + break; + + } + // Empty the packet so that the next section can be sent + sending.empty(); + + } // end if send multiple packets + + } // end for each section + + myDataMutex.unlock(); + + if (isMultiplePackets) { + // Send an empty packet to indicate the end of the config + ArNetPacket emptyPacket; + if (!myClient->requestOnce(setConfigPacketName, &emptyPacket)) { + isSuccess = false; + } + else { + ArLog::log(ArLog::Normal, + "ArClientHandlerConfig sent empty packet"); + } + } + else { + if (!myClient->requestOnce(setConfigPacketName, &sending)) { + isSuccess = false; + } + } + + if (!isSuccess) { + ArLog::log(ArLog::Normal, + "%sclient request to %s failed, invoking callbacks", + myLogPrefix.c_str(), setConfigPacketName); + for (std::list *>::iterator it = mySaveConfigFailedCBList.begin(); + it != mySaveConfigFailedCBList.end(); + it++) { + (*it)->invoke(); + } + } +} + +AREXPORT void ArClientHandlerConfig::handleSetConfig(ArNetPacket *packet) +{ + char buffer[1024]; + packet->bufToStr(buffer, sizeof(buffer)); + + myCallbackMutex.lock(); + if (buffer[0] == '\0') + { + ArLog::log(ArLog::Normal, "%sSaved config to server successfully", myLogPrefix.c_str()); + std::list::iterator it; + for (it = mySaveConfigSucceededCBList.begin(); + it != mySaveConfigSucceededCBList.end(); + it++) + (*it)->invoke(); + } + else + { + ArLog::log(ArLog::Normal, "%sSaving config to server had error: %s", myLogPrefix.c_str(), buffer); + std::list *>::iterator it; + for (it = mySaveConfigFailedCBList.begin(); + it != mySaveConfigFailedCBList.end(); + it++) + (*it)->invoke(buffer); + } + myCallbackMutex.unlock(); +} + +/// Handles the return packet from the setConfig (saveConfigToServer) +AREXPORT void ArClientHandlerConfig::handleSetConfigBySections(ArNetPacket *packet) +{ + char buffer[1024]; + packet->bufToStr(buffer, sizeof(buffer)); + + myCallbackMutex.lock(); + if (buffer[0] == '\0') + { + ArLog::log(ArLog::Normal, "%sSaved config to server successfully", myLogPrefix.c_str()); + std::list::iterator it; + for (it = mySaveConfigSucceededCBList.begin(); + it != mySaveConfigSucceededCBList.end(); + it++) + (*it)->invoke(); + } + else + { + ArLog::log(ArLog::Normal, "%sSaving config to server had error: %s", myLogPrefix.c_str(), buffer); + std::list *>::iterator it; + for (it = mySaveConfigFailedCBList.begin(); + it != mySaveConfigFailedCBList.end(); + it++) + (*it)->invoke(buffer); + } + myCallbackMutex.unlock(); +} + +/// Handles the return packet from the setConfig (saveConfigToServer) +AREXPORT void ArClientHandlerConfig::handleSetConfigBySectionsV2(ArNetPacket *packet) +{ + IFDEBUG(ArLog::log(ArLog::Normal, + "ArClientHandlerConfig::handleSetConfigBySectionsV2()")); + + char sectionBuffer[1024]; + char errorBuffer[1024]; + + packet->bufToStr(sectionBuffer, sizeof(sectionBuffer)); + packet->bufToStr(errorBuffer, sizeof(errorBuffer)); + + if (sectionBuffer[0] == '\0') { + myCallbackMutex.lock(); + if (errorBuffer[0] == '\0') + { + ArLog::log(ArLog::Normal, "%sSaved config to server successfully", myLogPrefix.c_str()); + std::list::iterator it; + for (it = mySaveConfigSucceededCBList.begin(); + it != mySaveConfigSucceededCBList.end(); + it++) + (*it)->invoke(); + } + else + { + ArLog::log(ArLog::Normal, "%sSaving config to server had error: %s", myLogPrefix.c_str(), errorBuffer); + std::list *>::iterator it; + for (it = mySaveConfigFailedCBList.begin(); + it != mySaveConfigFailedCBList.end(); + it++) + (*it)->invoke(errorBuffer); + } + myCallbackMutex.unlock(); + } + else { + myCallbackMutex.lock(); + if (errorBuffer[0] == '\0') + { + ArLog::log(ArLog::Normal, "%sSaved config section %s to server successfully", + myLogPrefix.c_str(), + sectionBuffer); + /*** + std::list::iterator it; + for (it = mySaveConfigSucceededCBList.begin(); + it != mySaveConfigSucceededCBList.end(); + it++) + (*it)->invoke(); + **/ + } + else + { + ArLog::log(ArLog::Normal, "%sSaving config to server had error: %s", myLogPrefix.c_str(), errorBuffer); + std::list *>::iterator it; + for (it = mySaveConfigFailedCBList.begin(); + it != mySaveConfigFailedCBList.end(); + it++) + (*it)->invoke(errorBuffer); + } + myCallbackMutex.unlock(); + } +} + + +AREXPORT void ArClientHandlerConfig::reloadConfigOnServer(void) +{ + myClient->requestOnce("reloadConfig"); +} + +/** + This will get the config, note, it gets the config we're using, so + if you change something while data comes in things will get broken + **/ +AREXPORT ArConfig *ArClientHandlerConfig::getConfig(void) +{ + return &myConfig; +} + +/** + * Returns a pointer to the robot server's default configuration, if + * canRequestDefaults() is true. Note that both requestConfigFromServer() + * and then requestDefaultConfigFromServer() must be called before a + * valid default configuration is available on the client. + * If there is no default configuration, then NULL is returned. +**/ +AREXPORT ArConfig *ArClientHandlerConfig::getDefaultConfig(void) +{ + return myDefaultConfig; +} + +/** + This will get a copy of the config, you can use this with the + safeConfigToServer that takes an argument + **/ +AREXPORT ArConfig ArClientHandlerConfig::getConfigCopy(void) +{ + ArConfig copy; + myDataMutex.lock(); + copy = myConfig; + myDataMutex.unlock(); + return copy; +} + +AREXPORT int ArClientHandlerConfig::lock(void) +{ + return myDataMutex.lock(); +} + +AREXPORT int ArClientHandlerConfig::tryLock(void) +{ + return myDataMutex.tryLock(); +} + +AREXPORT int ArClientHandlerConfig::unlock(void) +{ + return myDataMutex.unlock(); +} + +AREXPORT void ArClientHandlerConfig::setQuiet(bool isQuiet) +{ + myIsQuiet = isQuiet; + myConfig.setQuiet(isQuiet); + if (myDefaultConfig != NULL) { + myDefaultConfig->setQuiet(isQuiet); + } + +} + +AREXPORT bool ArClientHandlerConfig::haveGottenConfig(void) +{ + bool ret; + myDataMutex.lock(); + ret = myHaveGottenConfig; + myDataMutex.unlock(); + return ret; +} + +AREXPORT void ArClientHandlerConfig::addGotConfigCB(ArFunctor *functor, + ArListPos::Pos position) +{ + myCallbackMutex.lock(); + if (position == ArListPos::FIRST) + myGotConfigCBList.push_front(functor); + else if (position == ArListPos::LAST) + myGotConfigCBList.push_back(functor); + else + ArLog::log(ArLog::Terse, + "ArClientHandlerConfig::addGotConfigCB: Invalid position."); + myCallbackMutex.unlock(); +} + +AREXPORT void ArClientHandlerConfig::remGotConfigCB(ArFunctor *functor) +{ + myCallbackMutex.lock(); + myGotConfigCBList.remove(functor); + myCallbackMutex.unlock(); +} + +AREXPORT void ArClientHandlerConfig::addSaveConfigSucceededCB( + ArFunctor *functor, ArListPos::Pos position) +{ + myCallbackMutex.lock(); + if (position == ArListPos::FIRST) + mySaveConfigSucceededCBList.push_front(functor); + else if (position == ArListPos::LAST) + mySaveConfigSucceededCBList.push_back(functor); + else + ArLog::log(ArLog::Terse, + "ArClientHandlerConfig::addSaveConfigSucceededCB: Invalid position."); + myCallbackMutex.unlock(); +} + +AREXPORT void ArClientHandlerConfig::remSaveConfigSucceededCB(ArFunctor *functor) +{ + myCallbackMutex.lock(); + mySaveConfigSucceededCBList.remove(functor); + myCallbackMutex.unlock(); +} + + +AREXPORT void ArClientHandlerConfig::addSaveConfigFailedCB( + ArFunctor1 *functor, ArListPos::Pos position) +{ + myCallbackMutex.lock(); + if (position == ArListPos::FIRST) + mySaveConfigFailedCBList.push_front(functor); + else if (position == ArListPos::LAST) + mySaveConfigFailedCBList.push_back(functor); + else + ArLog::log(ArLog::Terse, + "ArClientHandlerConfig::addSaveConfigFailedCB: Invalid position."); + myCallbackMutex.unlock(); +} + +AREXPORT void ArClientHandlerConfig::remSaveConfigFailedCB(ArFunctor1 *functor) +{ + myCallbackMutex.lock(); + mySaveConfigFailedCBList.remove(functor); + myCallbackMutex.unlock(); +} + + +AREXPORT void ArClientHandlerConfig::addGotConfigDefaultsCB( + ArFunctor *functor, ArListPos::Pos position) +{ + myCallbackMutex.lock(); + if (position == ArListPos::FIRST) + myGotConfigDefaultsCBList.push_front(functor); + else if (position == ArListPos::LAST) + myGotConfigDefaultsCBList.push_back(functor); + else + ArLog::log(ArLog::Terse, + "ArClientHandlerConfig::addGotConfigDefaultsCB: Invalid position."); + myCallbackMutex.unlock(); +} + +AREXPORT void ArClientHandlerConfig::remGotConfigDefaultsCB(ArFunctor *functor) +{ + myCallbackMutex.lock(); + myGotConfigDefaultsCBList.remove(functor); + myCallbackMutex.unlock(); +} + +AREXPORT bool ArClientHandlerConfig::haveRequestedDefaults(void) +{ + bool ret; + myDataMutex.lock(); + ret = myHaveRequestedDefaults || myHaveRequestedDefaultCopy; + myDataMutex.unlock(); + return ret; +} + +AREXPORT bool ArClientHandlerConfig::haveGottenDefaults(void) +{ + bool ret; + myDataMutex.lock(); + ret = myHaveGottenDefaults; + myDataMutex.unlock(); + return ret; +} + +AREXPORT bool ArClientHandlerConfig::canRequestDefaults(void) +{ + return myClient->dataExists("getConfigDefaults"); +} + +AREXPORT bool ArClientHandlerConfig::requestConfigDefaults(void) +{ + if (haveRequestedDefaults()) + { + ArLog::log(ArLog::Normal, + "%sRequestConfigDefaults: Cannot request defaults as there are already some being requested", + myLogPrefix.c_str()); + return false; + } + if (!canRequestDefaults()) + { + ArLog::log(ArLog::Normal, + "%sRequestConfigDefaults: Defaults requested but not available", + myLogPrefix.c_str()); + return false; + } + + ArLog::log(ArLog::Normal, + "%sRequesting config reset to default", + myLogPrefix.c_str()); + + myDataMutex.lock(); + myHaveRequestedDefaults = true; + myHaveGottenDefaults = false; + myHaveRequestedDefaultCopy = false; + myDataMutex.unlock(); + + myClient->requestOnce("getConfigDefaults"); + return true; +} + +AREXPORT bool ArClientHandlerConfig::requestDefaultConfigFromServer(void) +{ + if (haveRequestedDefaults()) + { + ArLog::log(ArLog::Normal, + "%requestDefaultConfigFromServer: Cannot request defaults as there are already some being requested", + myLogPrefix.c_str()); + return false; + } + if (!canRequestDefaults()) + { + ArLog::log(ArLog::Normal, + "%sRequestConfigDefaults: Defaults requested but not available", + myLogPrefix.c_str()); + return false; + } + + + myDataMutex.lock(); + + myHaveRequestedDefaults = false; + myHaveGottenDefaults = false; + myHaveRequestedDefaultCopy = true; + myDataMutex.unlock(); + + myClient->requestOnce("getConfigDefaults"); + return true; +} + +AREXPORT bool ArClientHandlerConfig::requestSectionDefaults( + const char *section) +{ + if (haveRequestedDefaults()) + { + ArLog::log(ArLog::Normal, + "RequestSectionDefaults: Cannot request defaults as there are already some being requested"); + return false; + } + if (!canRequestDefaults()) + { + ArLog::log(ArLog::Normal, + "%sRequestSectionDefaults: Defaults requested but not available", + myLogPrefix.c_str()); + return false; + } + myDataMutex.lock(); + if (myConfig.findSection(section) == NULL) + { + ArLog::log(ArLog::Normal, + "%sRequestSectionDefaults: Section '%s' requested but doesn't exist", + myLogPrefix.c_str(), section); + myDataMutex.unlock(); + return false; + } + + ArLog::log(ArLog::Normal, + "%sRequesting config section %s reset to default", + myLogPrefix.c_str(), + section); + + myHaveRequestedDefaults = true; + myHaveGottenDefaults = false; + myHaveRequestedDefaultCopy = false; + myDataMutex.unlock(); + myClient->requestOnceWithString("getConfigDefaults", section); + return true; +} + + + +AREXPORT void ArClientHandlerConfig::handleGetConfigDefaults( + ArNetPacket *packet) +{ + ArLog::log(ArLog::Normal, "%sreceived default config %s", + myLogPrefix.c_str(), + ((myHaveRequestedDefaultCopy) ? "(copy)" : "(reset)")); + + char param[1024]; + char argument[1024]; + char errorBuffer[1024]; + + myDataMutex.lock(); + + ArConfig *config = NULL; + + // If the config (or a section) is being reset to its default values, + // then we don't want to remove any parameters that are not set -- i.e. + // any parameters that are not contained in the default config. + bool isClearUnsetValues = false; + + if (myHaveRequestedDefaults) { + + config = &myConfig; + } + else if (myHaveRequestedDefaultCopy) { + + // If we have requested a copy of the default configuration, then we + // will want to remove any parameters that haven't been explicitly set. + // (This is because of the next line, which copies the current config + // to the default config.) + isClearUnsetValues = true; + + // The default config is transmitted in an "abbreviated" form -- just + // the section/param names and values. Copy the current config to the + // default before processing the packet so that the parameter types, etc. + // can be preserved. + if (myDefaultConfig == NULL) { + myDefaultConfig = new ArConfig(myConfig); + myDefaultConfig->setConfigName("Default", myRobotName.c_str()); + myDefaultConfig->setQuiet(myIsQuiet); + } + else { + *myDefaultConfig = myConfig; + } + + + config = myDefaultConfig; + } + // if we didn't ask for any of these, then just return since the + // data is for someone else + else + { + myDataMutex.unlock(); + return; + } + + if (config == NULL) { + ArLog::log(ArLog::Normal, + "%serror determining config to populate with default values", + myLogPrefix.c_str()); + myDataMutex.unlock(); + return; + } + + ArArgumentBuilder *builder = NULL; + ArLog::log(ArLog::Normal, "%sGot defaults", myLogPrefix.c_str()); + errorBuffer[0] = '\0'; + + //myDataMutex.lock(); + if (isClearUnsetValues) { + config->clearAllValueSet(); + } + + while (packet->getDataReadLength() < packet->getDataLength()) + { + packet->bufToStr(param, sizeof(param)); + packet->bufToStr(argument, sizeof(argument)); + + + builder = new ArArgumentBuilder; + builder->setQuiet(myIsQuiet); + builder->setExtraString(param); + builder->add(argument); + + if ((strcasecmp(param, "Section") == 0 && + !config->parseSection(builder, errorBuffer, sizeof(errorBuffer))) || + (strcasecmp(param, "Section") != 0 && + !config->parseArgument(builder, errorBuffer, sizeof(errorBuffer)))) + { + ArLog::log(ArLog::Terse, "%shandleGetConfigDefaults: Hideous problem getting defaults, couldn't parse '%s %s'", + myLogPrefix.c_str(), param, argument); + } + else { + IFDEBUG(if (strlen(param) > 0) { + ArLog::log(ArLog::Normal, "%shandleGetConfigDefaults: added default '%s %s'", + myLogPrefix.c_str(), param, argument); } ); + } + delete builder; + builder = NULL; + } + myHaveRequestedDefaults = false; + myHaveRequestedDefaultCopy = false; + myHaveGottenDefaults = true; + + if (isClearUnsetValues) { + config->removeAllUnsetValues(); + } + + IFDEBUG(config->log()); + + myDataMutex.unlock(); + + myCallbackMutex.lock(); + std::list::iterator it; + for (it = myGotConfigDefaultsCBList.begin(); + it != myGotConfigDefaultsCBList.end(); + it++) + (*it)->invoke(); + myCallbackMutex.unlock(); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// Last Editable Priority +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +AREXPORT bool ArClientHandlerConfig::requestLastEditablePriorityFromServer() +{ + if (myClient->dataExists("getLastEditablePriority")) { + + myClient->remHandler("getLastEditablePriority", &myHandleGetLastEditablePriorityCB); + myClient->addHandler("getLastEditablePriority", &myHandleGetLastEditablePriorityCB); + myClient->requestOnce("getLastEditablePriority"); + + myDataMutex.lock(); + myHaveRequestedLastEditablePriority = true; + myHaveGottenLastEditablePriority = false; + myDataMutex.unlock(); + + ArLog::log(ArLog::Normal, "%sRequesting last editable priority", + myLogPrefix.c_str()); + + return true; + } + else { // server does not support last editable priority + + ArLog::log(ArLog::Normal, "%sserver does not support last editable priority", + myLogPrefix.c_str()); + return false; + + } // end else server does not support last editable priority + +} // end method requestLastEditablePriorityFromServer + +AREXPORT bool ArClientHandlerConfig::isLastEditablePriorityAvailable() +{ + if ((myClient != NULL) && + (myClient->dataExists("getLastEditablePriority"))) { + return true; + } + else { + return false; + } +} + +AREXPORT bool ArClientHandlerConfig::haveGottenLastEditablePriority() +{ + myDataMutex.lock(); + bool b = myHaveGottenLastEditablePriority; + myDataMutex.unlock(); + + return b; + +} // end method haveGottenLastEditablePriority + +AREXPORT ArPriority::Priority ArClientHandlerConfig::getLastEditablePriority() +{ + myDataMutex.lock(); + ArPriority::Priority p = myLastEditablePriority; + myDataMutex.unlock(); + + return p; + +} // end method getLastEditablePriority + +AREXPORT void ArClientHandlerConfig::addGotLastEditablePriorityCB + (ArFunctor *functor, + int position) +{ + myGotLastEditablePriorityCBList.addCallback(functor, position); + +} // end method addGotLastEditablePriorityCB + +AREXPORT void ArClientHandlerConfig::remGotLastEditablePriorityCB + (ArFunctor *functor) +{ + myGotLastEditablePriorityCBList.remCallback(functor); + +} // end method remGotLastEditablePriorityCB + + +AREXPORT void ArClientHandlerConfig::handleGetLastEditablePriority + (ArNetPacket *packet) +{ + + if (packet == NULL) { + ArLog::log(ArLog::Normal, "%sreceived null packet for getLastEditablePriority", + myLogPrefix.c_str()); + return; + } + + ArPriority::Priority lastPriority = ArPriority::LAST_PRIORITY; + + int tempPriority = packet->bufToByte(); + if ((tempPriority >= 0) && (tempPriority < ArPriority::PRIORITY_COUNT)) { + lastPriority = (ArPriority::Priority) tempPriority; + } + else { + ArLog::log(ArLog::Terse, "%sReceived invalid last editable priority %i", + myLogPrefix.c_str(), + tempPriority); + } + + ArLog::log(ArLog::Normal, "%sReceived last editable priority %s", + myLogPrefix.c_str(), + ArPriority::getPriorityName(lastPriority)); + + myDataMutex.lock(); + myLastEditablePriority = lastPriority; + myHaveRequestedLastEditablePriority = false; + myHaveGottenLastEditablePriority = true; + + myDataMutex.unlock(); + + myGotLastEditablePriorityCBList.invoke(); + +} // end method handleGetLastEditablePriority diff --git a/Legacy/Aria/ArNetworking/src/ArClientSimpleConnector.cpp b/Legacy/Aria/ArNetworking/src/ArClientSimpleConnector.cpp new file mode 100644 index 0000000..b7f30a3 --- /dev/null +++ b/Legacy/Aria/ArNetworking/src/ArClientSimpleConnector.cpp @@ -0,0 +1,170 @@ +#include "Aria.h" +#include "ArExport.h" +#include "ArClientSimpleConnector.h" + +AREXPORT ArClientSimpleConnector::ArClientSimpleConnector(int *argc, char **argv) : + myParseArgsCB(this, &ArClientSimpleConnector::parseArgs), + myLogOptionsCB(this, &ArClientSimpleConnector::logOptions) +{ + reset(); + myParser = new ArArgumentParser(argc, argv); + myOwnParser = true; + myParseArgsCB.setName("ArClientSimpleConnector"); + Aria::addParseArgsCB(&myParseArgsCB, 75); + myLogOptionsCB.setName("ArClientSimpleConnector"); + Aria::addLogOptionsCB(&myLogOptionsCB, 75); +} + +AREXPORT ArClientSimpleConnector::ArClientSimpleConnector(ArArgumentBuilder *builder) : + myParseArgsCB(this, &ArClientSimpleConnector::parseArgs), + myLogOptionsCB(this, &ArClientSimpleConnector::logOptions) +{ + reset(); + myParser = new ArArgumentParser(builder); + myOwnParser = true; + myParseArgsCB.setName("ArClientSimpleConnector"); + Aria::addParseArgsCB(&myParseArgsCB, 75); + myLogOptionsCB.setName("ArClientSimpleConnector"); + Aria::addLogOptionsCB(&myLogOptionsCB, 75); +} + +AREXPORT ArClientSimpleConnector::ArClientSimpleConnector(ArArgumentParser *parser) : + myParseArgsCB(this, &ArClientSimpleConnector::parseArgs), + myLogOptionsCB(this, &ArClientSimpleConnector::logOptions) +{ + reset(); + myParser = parser; + myOwnParser = false; + myParseArgsCB.setName("ArClientSimpleConnector"); + Aria::addParseArgsCB(&myParseArgsCB, 75); + myLogOptionsCB.setName("ArClientSimpleConnector"); + Aria::addLogOptionsCB(&myLogOptionsCB, 75); +} + +AREXPORT ArClientSimpleConnector::~ArClientSimpleConnector(void) +{ + +} + +void ArClientSimpleConnector::reset(void) +{ + myHost = NULL; + myUser = NULL; + myPassword = NULL; + myServerKey = NULL; + myPort = 7272; + myNoPassword = false; + myLogDataList = false; +} + +AREXPORT bool ArClientSimpleConnector::parseArgs(void) +{ + return parseArgs(myParser); +} + +AREXPORT bool ArClientSimpleConnector::parseArgs(ArArgumentParser *parser) +{ + if (parser->checkArgument("-nopassword") || + parser->checkArgument("-np")) + myNoPassword = true; + + if (parser->checkArgument("-logDataList") || + parser->checkArgument("-ldl")) + myLogDataList = true; + + if (!parser->checkParameterArgumentString("-host", + &myHost) || + !parser->checkParameterArgumentInteger("-port", + &myPort) || + !parser->checkParameterArgumentInteger("-p", + &myPort) || + !parser->checkParameterArgumentString("-user", + &myUser) || + !parser->checkParameterArgumentString("-u", + &myUser) || + !parser->checkParameterArgumentString("-password", + &myPassword) || + !parser->checkParameterArgumentString("-pwd", + &myPassword) || + !parser->checkParameterArgumentString("-setServerKey", + &myServerKey) || + !parser->checkParameterArgumentString("-ssk", + &myServerKey)) + + { + return false; + } + + return true; +} + +AREXPORT void ArClientSimpleConnector::logOptions(void) const +{ + ArLog::log(ArLog::Terse, "Options for ArClientSimpleConnector (see docs for more details):"); + ArLog::log(ArLog::Terse, "-host "); + ArLog::log(ArLog::Terse, "-port "); + ArLog::log(ArLog::Terse, "-p "); + ArLog::log(ArLog::Terse, "-user "); + ArLog::log(ArLog::Terse, "-u "); + ArLog::log(ArLog::Terse, "-password "); + ArLog::log(ArLog::Terse, "-pwd "); + ArLog::log(ArLog::Terse, "-nopassword"); + ArLog::log(ArLog::Terse, "-np"); + ArLog::log(ArLog::Terse, "-logDataList"); + ArLog::log(ArLog::Terse, "-ldl"); +} + +AREXPORT bool ArClientSimpleConnector::connectClient(ArClientBase *client, + bool print) +{ + std::string host; + std::string user; + char password[512]; + password[0] = '\0'; + + if (myServerKey != NULL && myServerKey[0] != '\0') + client->setServerKey(myServerKey); + + if (myUser == NULL) + { + user = ""; + } + else + { + user = myUser; + if (myPassword != NULL) + { + strncpy(password, myPassword, sizeof(password) - 1); + password[sizeof(password) - 1] = '\0'; + } + else if (!myNoPassword) + { + printf("Enter password: "); + fgets(password, sizeof(password) - 1, stdin); + unsigned int i; + unsigned int len; + len = strlen(password); + for (i = 0; i < len; i++) + { + if (password[i] == '\r' || password[i] == '\n') + { + password[i] = '\0'; + break; + } + } + } + } + if (myHost != NULL) + host = myHost; + else + host = "localhost"; + + bool ret; + ret = client->blockingConnect(host.c_str(), myPort, print, user.c_str(), + password); + + if (ret && myLogDataList) + client->logDataList(); + + return ret; +} diff --git a/Legacy/Aria/ArNetworking/src/ArClientSwitchManager.cpp b/Legacy/Aria/ArNetworking/src/ArClientSwitchManager.cpp new file mode 100644 index 0000000..434c1fc --- /dev/null +++ b/Legacy/Aria/ArNetworking/src/ArClientSwitchManager.cpp @@ -0,0 +1,687 @@ +#include "Aria.h" +#include "ArExport.h" +#include "ArClientSwitchManager.h" + +AREXPORT ArClientSwitchManager::ArClientSwitchManager( + ArServerBase *serverBase, ArArgumentParser *parser, + const char *serverDesc, const char *clientSoftwareDesc) : + myParseArgsCB(this, &ArClientSwitchManager::parseArgs), + myLogOptionsCB(this, &ArClientSwitchManager::logOptions), + mySocketClosedCB(this, &ArClientSwitchManager::socketClosed), + mySwitchCB(this, &ArClientSwitchManager::clientSwitch), + myNetCentralHeartbeatCB(this, &ArClientSwitchManager::netCentralHeartbeat), + myNetCentralServerHeartbeatCB(this, + &ArClientSwitchManager::netCentralServerHeartbeat), + myFileUserCB(this, &ArClientSwitchManager::fileUserCallback), + myFilePasswordCB(this, &ArClientSwitchManager::filePasswordCallback), + myFileServerKeyCB(this, &ArClientSwitchManager::fileServerKeyCallback), + myProcessFileCB(this, &ArClientSwitchManager::processFile) +{ + myMutex.setLogName("ArClientSwitchManager::myDataMutex"); + myServer = serverBase; + myParser = parser; + myServerDesc = serverDesc; + myClientSoftwareDesc = clientSoftwareDesc; + + setThreadName("ArClientSwitchManager"); + + mySwitchCB.setName("ArClientSwitchManager"); + + myParseArgsCB.setName("ArClientSwitchManager"); + Aria::addParseArgsCB(&myParseArgsCB, 49); + myLogOptionsCB.setName("ArClientSwitchManager"); + Aria::addLogOptionsCB(&myLogOptionsCB, 49); + + myNetCentralHeartbeatCB.setName("ArClientSwitchManager"); + myServer->addData("centralHeartbeat", + "a packet that is requested and used by the central server to make sure there is still a connection, it should not be used by anyone or anything else, note that this sends a response over tcp and udp at the same time", + &myNetCentralHeartbeatCB, "none", "none", "RobotInfo", + "RETURN_SINGLE"); + + myServer->addData("centralServerHeartbeat", + "a packet that is sent by central server to make sure there is still a connection to the robot, it should not be used by anyone or anything else", + &myNetCentralServerHeartbeatCB, "none", "none", "RobotInfo", + "RETURN_SINGLE"); + + myServerBackupTimeout = 2; + Aria::getConfig()->addParam( + ArConfigArg("RobotToCentralServerTimeoutInMins", + &myServerBackupTimeout, + "The amount of time the robot can go without sending a packet to the central server successfully (when there are packets to send). A number less than 0 means this won't happen. The time is in minutes but takes doubles (ie .5) (5 seconds is used if the value is positive, but less than that amount)", + -1), + "Connection timeouts", ArPriority::DETAILED); + + myServerHeartbeatTimeout = 2; + Aria::getConfig()->addParam( + ArConfigArg("RobotFromCentralServerTimeoutInMins", + &myServerHeartbeatTimeout, + "The amount of time a robot can go without getting the heartbeat from the central server before disconnecting it. A number less than 0 means that the central server will never timeout. The time is in minutes but takes doubles (ie .5) (5 seconds is used if the value is positive, but less than that amount)", -1), + "Connection timeouts", ArPriority::DETAILED); + + myServerUdpHeartbeatTimeout = 2; + Aria::getConfig()->addParam( + ArConfigArg("RobotFromCentralServerUdpTimeoutInMins", + &myServerUdpHeartbeatTimeout, + "The amount of time a robot can go without getting the udp heartbeat from the central server before disconnecting it. A number less than 0 means that the central server will never timeout. The time is in minutes but takes doubles (ie .5) (5 seconds is used if the value is positive, but less than that amount)", -1), + "Connection timeouts", ArPriority::DETAILED); + + + myProcessFileCB.setName("ArClientSwitchManager"); + Aria::getConfig()->addProcessFileCB(&myProcessFileCB, -1000); + + myConfigFirstProcess = true; + myConfigConnectToCentralServer = false; + myConfigCentralServer[0] = '\0'; + myConfigIdentifier[0] = '\0'; + + switchState(IDLE); + myClient = NULL; + myServerClient = NULL; + myCentralServerPort = 5000; + + myFileUserCB.setName("ArClientSwitchManager::user"); + myFileParser.addHandler("user", &myFileUserCB); + myFilePasswordCB.setName("ArClientSwitchManager::password"); + myFileParser.addHandler("password", &myFilePasswordCB); + myFileServerKeyCB.setName("ArClientSwitchManager::serverKey"); + myFileParser.addHandler("serverKey", &myFileServerKeyCB); +} + +AREXPORT ArClientSwitchManager::~ArClientSwitchManager() +{ +} + +AREXPORT bool ArClientSwitchManager::isConnected(void) +{ + return myState == CONNECTED; +} + +AREXPORT void ArClientSwitchManager::switchState(State state) +{ + myState = state; + myStartedState.setToNow(); + //myGaveTimeWarning = false; +} + +AREXPORT bool ArClientSwitchManager::parseArgs(void) +{ + const char *centralServer = NULL; + const char *identifier = NULL; + + if (!myParser->checkParameterArgumentString("-centralServer", + ¢ralServer) || + !myParser->checkParameterArgumentString("-cs", ¢ralServer) || + !myParser->checkParameterArgumentInteger("-centralServerPort", + &myCentralServerPort) || + !myParser->checkParameterArgumentInteger("-csp", + &myCentralServerPort) || + !myParser->checkParameterArgumentString("-identifier", &identifier) || + !myParser->checkParameterArgumentString("-id", &identifier)) + return false; + + + bool wasReallySetOnlyTrue = myParser->getWasReallySetOnlyTrue(); + myParser->setWasReallySetOnlyTrue(true); + + bool wasReallySet = false; + const char *centralServerInfoFile = NULL; + while (myParser->checkParameterArgumentString( + "-centralServerInfoFile", ¢ralServerInfoFile, + &wasReallySet, true) && + wasReallySet) + { + if (centralServerInfoFile != NULL && !parseFile(centralServerInfoFile)) + { + myParser->setWasReallySetOnlyTrue(wasReallySetOnlyTrue); + return false; + } + wasReallySet = false; + } + + myParser->setWasReallySetOnlyTrue(wasReallySetOnlyTrue); + + myDataMutex.lock(); + if (centralServer != NULL && centralServer[0] != '\0') + { + myCentralServer = centralServer; + myState = TRYING_CONNECTION; + } + + if (identifier != NULL && identifier[0] != '\0') + { + myIdentifier = identifier; + } + /* Just don't set it so the server can just set it to the IP + else + { + int nameLen; + char name[512]; + int i; + + nameLen = ArMath::random() % 15 + 1; + for (i = 0; i < nameLen; i++) + name[i] = 'a' + (ArMath::random() % ('z' - 'a')); + name[nameLen] = '\0'; + + myIdentifier = name; + } + */ + myDataMutex.unlock(); + + return true; +} + +AREXPORT void ArClientSwitchManager::logOptions(void) const +{ + ArLog::log(ArLog::Terse, "ArClientSwitchManager options:"); +// ArLog::log(ArLog::Terse, ""); + ArLog::log(ArLog::Terse, "-centralServer "); + ArLog::log(ArLog::Terse, "-cs "); + ArLog::log(ArLog::Terse, "-centralServerPort "); + ArLog::log(ArLog::Terse, "-csp "); + ArLog::log(ArLog::Terse, "-identifier "); + ArLog::log(ArLog::Terse, "-id "); + /* + ArLog::log(ArLog::Terse, "-centralServerUser "); + ArLog::log(ArLog::Terse, "-csu "); + ArLog::log(ArLog::Terse, "-centralServerPassword "); + ArLog::log(ArLog::Terse, "-csp "); + ArLog::log(ArLog::Terse, "-centralServerKey "); + ArLog::log(ArLog::Terse, "-csk "); + */ + ArLog::log(ArLog::Terse, "-centralServerInfoFile "); +} + +AREXPORT void ArClientSwitchManager::clientSwitch(ArNetPacket *packet) +{ + //myDataMutex.lock(); + ArLog::log(ArLog::Normal, "Switch acknowledged, switching"); + + myServerClient = myServer->makeNewServerClientFromSocket( + myClient->getTcpSocket(), true); + myServerClient->getTcpSocket()->setCloseCallback(&mySocketClosedCB); + myServerClient->setBackupTimeout(myServerBackupTimeout); + + ArSocket emptySocket; + myClient->getTcpSocket()->transfer(&emptySocket); + + myLastTcpHeartbeat.setToNow(); + myLastUdpHeartbeat.setToNow(); + switchState(CONNECTED); + + char switchStr[1024]; + sprintf(switchStr, "Recovered connection to %s at %s, now connected.", + myServerDesc.c_str(), myCentralServer.c_str()); + myConnectedCBList.invoke(switchStr); + //myDataMutex.unlock(); +} + +AREXPORT void ArClientSwitchManager::socketClosed(void) +{ + myDataMutex.lock(); + if (myState == CONNECTED) + { + myServerClient = NULL; + ArLog::log(ArLog::Normal, "ArClientSwitchManager: Lost connection to central server"); + switchState(LOST_CONNECTION); + + char failedStr[1024]; + sprintf(failedStr, "Lost connection to %s at %s, restarting connection.", + myServerDesc.c_str(), myCentralServer.c_str()); + myFailedConnectCBList.invoke(failedStr); + + } + myDataMutex.unlock(); +} + +AREXPORT void *ArClientSwitchManager::runThread(void *arg) +{ + threadStarted(); + + while (getRunning()) + { + myDataMutex.lock(); + if (myState == IDLE) + { + } + else if (myState == TRYING_CONNECTION) + { + myLastConnectionAttempt.setToNow(); + ArLog::log(ArLog::Normal, "Trying to connect to central server %s", + myCentralServer.c_str()); + myClient = new ArClientBase; + myClient->setRobotName("ClientSwitch", myDebugLogging); + myClient->setServerKey(myServerKey.c_str(), false); + myClient->enforceProtocolVersion(myEnforceProtocolVersion.c_str(), false); + myClient->enforceType(myEnforceType, false); + myLastTcpHeartbeat.setToNow(); + myLastUdpHeartbeat.setToNow(); + if (!myClient->blockingConnect(myCentralServer.c_str(), + myCentralServerPort, false, + myUser.c_str(), myPassword.c_str(), + myServer->getOpenOnIP())) + { + char failedStr[10000]; + char verboseFailedStr[10000]; + if (myClient->wasRejected()) + { + //ArLog::log(ArLog::Normal, + //"Could not connect to %s because it rejected connection (%d, %s)", + //myCentralServer.c_str(), myClient->getRejected(), myClient->getRejectedString()); + if (myClient->getRejected() == 1) + { + sprintf(verboseFailedStr, + "Could not connect to %s at %s\n\nBad username and password.", + myServerDesc.c_str(), myCentralServer.c_str()); + sprintf(failedStr, + "Could not connect to %s (Bad username and password)", + myCentralServer.c_str()); + } + else if (myClient->getRejected() == 2) + { + sprintf(verboseFailedStr, + "Could not connect to %s at %s\n\nIt rejected this connection because it is not direct.", + myServerDesc.c_str(), myCentralServer.c_str()); + sprintf(failedStr, + "Could not connect to %s (rejected because not a direct connection).", + myCentralServer.c_str()); + } + else if (myClient->getRejected() == 3) + { + sprintf(verboseFailedStr, + "Could not connect to %s at %s\n\nIt is a version not supported by this robot's %s.", + myServerDesc.c_str(), myCentralServer.c_str(), + myClientSoftwareDesc.c_str()); + sprintf(failedStr, + "Could not connect to %s (it is not a version supported by this robot's %s)", + myCentralServer.c_str(), myClientSoftwareDesc.c_str()); + } + else if (myClient->getRejected() == 4) + { + sprintf(verboseFailedStr, + "Could not connect to %s at %s\n\nIt does not support this robot's %s version.", + myServerDesc.c_str(), myCentralServer.c_str(), + myClientSoftwareDesc.c_str()); + sprintf(failedStr, + "Could not connect to %s at %s (It does not support this robot's %s version)", + myServerDesc.c_str(), myCentralServer.c_str(), + myClientSoftwareDesc.c_str()); + } + else if (myClient->getRejected() == 5) + { + sprintf(verboseFailedStr, + "Could not connect to %s at %s\n\nIt's number of licenses has been exceeded.\n\nPlease contact your robot provider for assistance purchasing more licenses.", + myServerDesc.c_str(), myCentralServer.c_str()); + sprintf(failedStr, + "Could not connect to %s (It's number of licenses has been exceeded)", + myCentralServer.c_str()); + } + else if (myClient->getRejected() == 6) + { + sprintf(verboseFailedStr, + "Could not connect to %s at %s\n\nIt does not allow connections from %s robots.\n\nPlease contact your robot administrator for assistance.", + myServerDesc.c_str(), myCentralServer.c_str(), + ArServerCommands::toString(myEnforceType)); + sprintf(failedStr, + "Could not connect to %s (It does not allow connections from %s robots)", + myCentralServer.c_str(), + ArServerCommands::toString(myEnforceType)); + } + else + { + sprintf(verboseFailedStr, + "Could not connect to %s at %s\n\nThe reason is '%s'", + myServerDesc.c_str(), myCentralServer.c_str(), myClient->getRejectedString()); + sprintf(failedStr, + "Could not connect to %s (reason %d '%s')", + myCentralServer.c_str(), myClient->getRejected(), + myClient->getRejectedString()); + } + } + else + { + ArLog::log(ArLog::Verbose, + "Could not connect to %s to switch with, not doing anything", + myCentralServer.c_str()); + sprintf(verboseFailedStr, "Could not connect to %s at %s\n\nIt may not be reachable by the robot.", myServerDesc.c_str(), myCentralServer.c_str()); + sprintf(failedStr, "Could not connect to %s", myCentralServer.c_str()); + } + myClient->getTcpSocket()->close(); + delete myClient; + myClient = NULL; + switchState(LOST_CONNECTION); + ArLog::log(ArLog::Normal, "%s", failedStr); + myFailedConnectCBList.invoke(verboseFailedStr); + myDataMutex.unlock(); + continue; + } + + if (!myClient->dataExists("switch")) + { + ArLog::log(ArLog::Normal, + "ArClientSwitchManager: Connected to central server %s but it isn't a central server, going to idle"); + myClient->disconnect(); + delete myClient; + myClient = NULL; + switchState(LOST_CONNECTION); + + char failedStr[1024]; + sprintf(failedStr, "Connected to %s at %s, but it is inappropriate software, disconnecting.\n\nLikely this robot is pointing at another robot.", + myServerDesc.c_str(), myCentralServer.c_str()); + myFailedConnectCBList.invoke(failedStr); + + myDataMutex.unlock(); + continue; + } + + ArNetPacket sendPacket; + ArLog::log(ArLog::Verbose, "Putting in %s\n", myIdentifier.c_str()); + sendPacket.strToBuf(myIdentifier.c_str()); + + if (myClient->dataExists("centralServerHeartbeat")) + { + ArLog::log(ArLog::Normal, "Requesting switch (have heartbeat)"); + myServerHasHeartbeat = true; + } + else + { + ArLog::log(ArLog::Normal, "Requesting switch (no heartbeat)"); + myServerHasHeartbeat = false; + } + + myClient->addHandler("switch", &mySwitchCB); + myClient->requestOnce("switch", &sendPacket); + switchState(CONNECTING); + } + else if (myState == CONNECTING) + { + /* old behavior that just warned + if (!myGaveTimeWarning && myStartedState.secSince() > 10) + { + ArLog::log(ArLog::Normal, "ArClientSwitchManager: Connecting has taken over 10 seconds, probably a problem"); + myGaveTimeWarning = true; + } + myClient->loopOnce(); + myDataMutex.unlock(); + ArUtil::sleep(1); + continue; + */ + // new behavior that starts over + myClient->loopOnce(); + if (myStartedState.secSince() >= 15 && + myLastTcpHeartbeat.secSince() / 60.0 >= myServerHeartbeatTimeout) + { + + ArLog::log(ArLog::Normal, "ArClientSwitchManager: Connecting to central server has taken %.2f minutes, restarting connection", myStartedState.secSince() / 60.0); // this had / 4.0 for no apparent reason, changed it (11/13/2012 MPL) + /// added this to try and eliminate the occasional duplicates + myClient->getTcpSocket()->close(); + delete myClient; + myClient = NULL; + switchState(LOST_CONNECTION); + + char failedStr[1024]; + sprintf(failedStr, "Connection to %s at %s took over %.2f minutes, restarting connection.", + myServerDesc.c_str(), myCentralServer.c_str(), myStartedState.secSince() / 60.0); + myFailedConnectCBList.invoke(failedStr); + + myDataMutex.unlock(); + continue; + } + myDataMutex.unlock(); + ArUtil::sleep(1); + continue; + } + else if (myState == CONNECTED) + { + if (myClient != NULL) + { + delete myClient; + myClient = NULL; + } + // if we have a heartbeat timeout make sure we've heard the + // heartbeat within that range + if (myServerHasHeartbeat && myServerHeartbeatTimeout >= -.00000001 && + myLastTcpHeartbeat.secSince() >= 5 && + myLastTcpHeartbeat.secSince() / 60.0 >= myServerHeartbeatTimeout) + { + ArLog::log(ArLog::Normal, + "ArClientSwitchManager: Dropping connection since haven't heard from central server in %g minutes", + myServerHeartbeatTimeout); + myServerClient->forceDisconnect(false); + myServerClient = NULL; + switchState(LOST_CONNECTION); + + char failedStr[1024]; + sprintf(failedStr, "Dropping connection to %s at %s since the robot hasn't heard from it in over %g minutes, restarting connection.", + myServerDesc.c_str(), myCentralServer.c_str(), myServerHeartbeatTimeout); + myFailedConnectCBList.invoke(failedStr); + + myDataMutex.unlock(); + continue; + } + else if + (myServerHasHeartbeat && !myServerClient->isTcpOnly() && + myServerUdpHeartbeatTimeout >= -.00000001 && + myLastUdpHeartbeat.secSince() >= 5 && + myLastUdpHeartbeat.secSince() / 60.0 >= myServerUdpHeartbeatTimeout) + { + ArLog::log(ArLog::Normal, "ArClientSwitchManager: Switching to TCP only since gotten UDP from central server in %g minutes", + myServerUdpHeartbeatTimeout); + myServerClient->useTcpOnly(); + } + + } + else if (myState == LOST_CONNECTION) + { + if (myLastConnectionAttempt.secSince() > 10) + { + switchState(TRYING_CONNECTION); + } + } + myDataMutex.unlock(); + ArUtil::sleep(100); + } + threadFinished(); + return NULL; +} + +AREXPORT void ArClientSwitchManager::netCentralHeartbeat( + ArServerClient *client, ArNetPacket *packet) +{ + ArNetPacket sending; + client->sendPacketTcp(&sending); + client->sendPacketUdp(&sending); +} + +AREXPORT void ArClientSwitchManager::netCentralServerHeartbeat( + ArServerClient *client, ArNetPacket *packet) +{ + myDataMutex.lock(); + if (client != myServerClient) + { + ArLog::log(ArLog::Normal, "Got a central server heartbeat packet from someone that isn't the central server %s", client->getIPString()); + myDataMutex.unlock(); + return; + } + if (packet->getPacketSource() == ArNetPacket::TCP) + myLastTcpHeartbeat.setToNow(); + else if (packet->getPacketSource() == ArNetPacket::UDP) + myLastUdpHeartbeat.setToNow(); + else + ArLog::log(ArLog::Normal, + "Got unknown packet source for central server heartbeat packet"); + myDataMutex.unlock(); +} + +AREXPORT bool ArClientSwitchManager::parseFile(const char *fileName) +{ + ArLog::log(ArLog::Normal, "Loading central server user/password from %s", + fileName); + if (!myFileParser.parseFile(fileName)) + { + + ArLog::log(ArLog::Normal, "Failed parsing central server user/password file %s", + fileName); + return false; + } + return true; +} + +bool ArClientSwitchManager::fileUserCallback(ArArgumentBuilder *arg) +{ + if (arg->getArgc() > 1) + { + ArLog::log(ArLog::Normal, "Bad user line: %s %s", + arg->getExtraString(), arg->getFullString()); + return false; + } + if (arg->getArgc() == 0) + myUser = ""; + else + myUser = arg->getArg(0); + return true; +} + + +bool ArClientSwitchManager::filePasswordCallback(ArArgumentBuilder *arg) +{ + if (arg->getArgc() > 1) + { + ArLog::log(ArLog::Normal, "Bad password line: %s %s", + arg->getExtraString(), arg->getFullString()); + return false; + } + if (arg->getArgc() == 0) + myPassword = ""; + else + myPassword = arg->getArg(0); + return true; +} + +bool ArClientSwitchManager::fileServerKeyCallback(ArArgumentBuilder *arg) +{ + if (arg->getArgc() > 1) + { + ArLog::log(ArLog::Normal, "Bad serverKey line: %s %s", + arg->getExtraString(), arg->getFullString()); + return false; + } + if (arg->getArgc() == 0) + myServerKey = ""; + else + myServerKey = arg->getArg(0); + return true; +} + +AREXPORT const char *ArClientSwitchManager::getCentralServerHostName(void) +{ + if (myCentralServer.size() <= 0) + return NULL; + else + return myCentralServer.c_str(); +} + +AREXPORT const char *ArClientSwitchManager::getIdentifier(void) +{ + if (myIdentifier.size() <= 0) + return NULL; + else + return myIdentifier.c_str(); +} + +bool ArClientSwitchManager::processFile(void) +{ + myDataMutex.lock(); + if (myServerClient != NULL) + myServerClient->setBackupTimeout(myServerBackupTimeout); + + // we only process this once, that's fine since changing it causes + // the software to restart + if (myConfigFirstProcess) + { + // if the config wants to connect to the central server and there + // isn't already a central server set, use the one in the config + if (myConfigConnectToCentralServer && + myCentralServer.empty() && myConfigCentralServer[0] != '\0') + { + myCentralServer = myConfigCentralServer; + myState = TRYING_CONNECTION; + } + + // if we have no identifier set, but the config has one, copy it + // over + if (myIdentifier.empty() && myConfigIdentifier[0] != '\0') + { + myIdentifier = myConfigIdentifier; + } + myConfigFirstProcess = false; + } + + myDataMutex.unlock(); + return true; +} + + +AREXPORT void ArClientSwitchManager::addToConfig( + const char *configSection, + const char *connectName, const char *connectDesc, + const char *addressName, const char *addressDesc) +{ + myConfigFirstProcess = true; + + if (myCentralServer.empty()) + { + Aria::getConfig()->addParam( + ArConfigArg(connectName, &myConfigConnectToCentralServer, + connectDesc), + configSection, ArPriority::ADVANCED, "Checkbox", + ArConfigArg::RESTART_SOFTWARE); + + myConfigDisplayHint = "Visible:"; + myConfigDisplayHint += connectName; + myConfigDisplayHint += "=true"; + + Aria::getConfig()->addParam( + ArConfigArg(addressName, myConfigCentralServer, + addressDesc, + sizeof(myConfigCentralServer)), + configSection, ArPriority::ADVANCED, + getConfigDisplayHint(), + ArConfigArg::RESTART_SOFTWARE); + } + + if (myIdentifier.empty()) + { + Aria::getConfig()->addParam( + ArConfigArg("Identifier", myConfigIdentifier, + "The identifier to use for this robot... After initial setup this should not be changed", + sizeof(myConfigIdentifier)), + configSection, ArPriority::CALIBRATION, + getConfigDisplayHint(), + ArConfigArg::RESTART_SOFTWARE); + } +} + + +/// Enforces the that the server is using this protocol version +AREXPORT void ArClientSwitchManager::enforceProtocolVersion(const char *protocolVersion) +{ + myDataMutex.lock(); + if (protocolVersion != NULL) + myEnforceProtocolVersion = protocolVersion; + else + myEnforceProtocolVersion = ""; + myDataMutex.unlock(); + ArLog::log(ArLog::Normal, "ArClientSwitchManager: New enforceProtocolVersionSet"); + +} + +AREXPORT void ArClientSwitchManager::enforceType(ArServerCommands::Type type) +{ + myDataMutex.lock(); + myEnforceType = type; + myDataMutex.unlock(); + ArLog::log(ArLog::Normal, "ArClientSwitchManager: New enforce type: %s", + ArServerCommands::toString(type)); + +} diff --git a/Legacy/Aria/ArNetworking/src/ArHybridForwarderVideo.cpp b/Legacy/Aria/ArNetworking/src/ArHybridForwarderVideo.cpp new file mode 100644 index 0000000..56e12e2 --- /dev/null +++ b/Legacy/Aria/ArNetworking/src/ArHybridForwarderVideo.cpp @@ -0,0 +1,240 @@ +#include "Aria.h" +#include "ArExport.h" +#include "ArHybridForwarderVideo.h" + +/** + @param server this class will addData the video data to the server + + @param client IF the client is connected to something this class + will get video data from the client and send it out when requested + **/ +AREXPORT ArHybridForwarderVideo::ArHybridForwarderVideo(ArServerBase *server, + ArClientBase *client) +{ + myMutex.setLogName("ArHybridForwarderVideo::myMutex"); + myServer = server; + myClient = client; + finishConstructor(); +} + +/** + This will try to connect a client to the hostname and port given, + IF client connects to something this class will get video data from + the client and send it out when requested + + @param server a base server object + @param hostname the host to connect a client to + @param port the port to connect a client to +**/ +AREXPORT ArHybridForwarderVideo::ArHybridForwarderVideo(ArServerBase *server, + const char *hostname, + int port) +{ + myServer = server; + myClient = new ArClientBase(); + myClient->setConnectTimeoutTime(1); + myClient->blockingConnect(hostname, port, false); + myClient->runAsync(); + finishConstructor(); +} + +AREXPORT ArHybridForwarderVideo::~ArHybridForwarderVideo() +{ + +} + +AREXPORT void ArHybridForwarderVideo::finishConstructor(void) +{ + myClient->lock(); + mySendVideoSizeCB = new ArFunctor2C(this, &ArHybridForwarderVideo::sendVideoSize); + + mySendVideoCB = new ArFunctor2C(this, &ArHybridForwarderVideo::sendVideo); + + myReceiveVideoSizeCB = new ArFunctor1C(this, &ArHybridForwarderVideo::receiveVideoSize); + + myReceiveVideoCB = new ArFunctor1C(this, &ArHybridForwarderVideo::receiveVideo); + + myClientCycleCB = new ArFunctorC( + this, &ArHybridForwarderVideo::clientCycleCallback); + + myReqSent = false; + myLastReqSent.setToNow(); + myLastReceivedVideo.setToNow(); + myVideoRequestTime = 100; + myForwardingVideo = false; + + if (myClient != NULL && myServer != NULL && myClient->isConnected()) + { + myClient->addCycleCallback(myClientCycleCB); + if (myClient->dataExists("videoSize")) + { + myServer->addData("videoSize", + "gets the width and height of the video data", + mySendVideoSizeCB, + "none", "uByte2: width, uByte2: height", + "Video", "RETURN_SINGLE"); + myClient->addHandler("videoSize", myReceiveVideoSizeCB); + myClient->requestOnce("videoSize"); + } + if (myClient->dataExists("sendVideo")) + { + ArLog::log(ArLog::Normal, "Forwarding video."); + myForwardingVideo = true; + myClient->addHandler("sendVideo", myReceiveVideoCB); + ArNetPacket packet; + packet.uByteToBuf(90); + myClient->requestOnce("sendVideo", &packet); + + myIsSendVideoAvailable = + myServer->addData("sendVideo", "gets video from the robot's camera (you should requestOnce this, you shouldn't request it, since you could easily fill the bandwidth that way)", + mySendVideoCB, "uByte: quality (0 - 100)", + "out: uByte2: width, uByte2: height, (len - readLen)*uByte: jpegData", "Video", "RETURN_VIDEO"); + } + } + myClient->unlock(); +} + + +AREXPORT const char *ArHybridForwarderVideo::getCameraName() +{ + return myCameraName.c_str(); +} + +AREXPORT void ArHybridForwarderVideo::setCameraName(const char *cameraName) +{ + if (cameraName != NULL) { + myCameraName = cameraName; + } + else { + myCameraName = ""; + } + +} // end method setCameraName + + +AREXPORT void ArHybridForwarderVideo::addToCameraCollection + (ArCameraCollection &collection) +{ + if (myCameraName.empty()) { + return; + } // end if no camera name + + const char *cameraName = myCameraName.c_str(); + if (!collection.exists(cameraName)) { + + return; + } // end if camera not yet created + + bool isSuccess = true; + + if (myForwardingVideo) { + + std::string packetName = "getPicture" + myCameraName; + + // This is a little unusual to add the handler here, but this method + // should only be called once, so hopefully it's no problem... + isSuccess = myServer->addData(packetName.c_str(), + "Gets video from the robot's camera", + mySendVideoCB, "uByte: quality (0 - 100)", + "out: uByte2: width, uByte2: height, (len - readLen)*uByte: jpegData", "Video"); + + if (isSuccess) { + isSuccess = collection.addCameraCommand + (cameraName, + ArCameraCommands::GET_PICTURE, + packetName.c_str(), + myVideoRequestTime); // TODO ? + } + + if (!isSuccess) { + ArLog::log(ArLog::Verbose, + "Video forwarder could not add camera %s command %s", + cameraName, + packetName.c_str()); + } // end if error occurred + + } // end if forwarding video + + // Left the original addData("sendVideo") in the finishConstructor() + // method - just to try to avoid any backwards compatibility issues. + if (myIsSendVideoAvailable) { + + isSuccess = collection.addCameraCommand + (cameraName, + ArCameraCommands::GET_VIDEO, + "sendVideo", + myVideoRequestTime); // TODO ? + } + +} // end method addToCameraCollection + + + +AREXPORT void ArHybridForwarderVideo::sendVideoSize(ArServerClient *client, + ArNetPacket *packet) +{ + myMutex.lock(); + myReceivedVideoSize.setCommand(packet->getCommand()); + client->sendPacketTcp(&myReceivedVideoSize); + myMutex.unlock(); +} + +AREXPORT void ArHybridForwarderVideo::sendVideo(ArServerClient *client, + ArNetPacket *packet) +{ + //printf("Sending video\n"); + myMutex.lock(); + mySendVideoArgument.duplicatePacket(packet); + mySendVideoArgument.resetRead(); + // MPL fixed the code so that this next line worked, but should + // probably let the base figure out the command (since it does it + // for everything else) + //myReceivedVideo.setCommand(packet->getCommand()); + myReceivedVideo.setCommand(0); + client->sendPacketUdp(&myReceivedVideo); + //printf("Sent video %d\n", myReceivedVideo.getLength()); + myMutex.unlock(); +} + +AREXPORT void ArHybridForwarderVideo::receiveVideoSize(ArNetPacket *packet) +{ + //printf("Receiving video size\n"); + myMutex.lock(); + myReceivedVideoSize.duplicatePacket(packet); + mySendVideoArgument.resetRead(); + myMutex.unlock(); +} + +AREXPORT void ArHybridForwarderVideo::receiveVideo(ArNetPacket *packet) +{ + //printf("Receiving video\n"); + myMutex.lock(); + myReceivedVideo.duplicatePacket(packet); + myReceivedVideo.resetRead(); + myLastReceivedVideo.setToNow(); + myReqSent = false; + myMutex.unlock(); +} + +AREXPORT void ArHybridForwarderVideo::clientCycleCallback(void) +{ + myMutex.lock(); + if ((myLastReceivedVideo.mSecSince() > myVideoRequestTime && !myReqSent) || + (myReqSent && myLastReqSent.mSecSince() > 3000)) + { + //printf("Requesting video\n"); + myClient->requestOnce("sendVideo", &mySendVideoArgument); + myLastReqSent.setToNow(); + myReqSent = true; + } + myMutex.unlock(); +} + +AREXPORT bool ArHybridForwarderVideo::isForwardingVideo(void) const +{ + return myForwardingVideo; +} diff --git a/Legacy/Aria/ArNetworking/src/ArMapChanger.cpp b/Legacy/Aria/ArNetworking/src/ArMapChanger.cpp new file mode 100644 index 0000000..dd019f4 --- /dev/null +++ b/Legacy/Aria/ArNetworking/src/ArMapChanger.cpp @@ -0,0 +1,3212 @@ +#include "Aria.h" +#include "ArExport.h" +#include "ArMapChanger.h" + +#include +#include + +#include "ArFileParser.h" +#include "ArMapUtils.h" +#include "ArMD5Calculator.h" + +//#define ARDEBUG_MAP_CHANGER +#ifdef ARDEBUG_MAP_CHANGER +#define IFDEBUG(code) {code;} +#else +#define IFDEBUG(code) +#endif + +const char *ArMapChanger::PROCESS_CHANGES_PACKET_NAME = + "processMapChanges"; + +const char *ArMapChanger::PROCESS_ROBOT_CHANGES_PACKET_NAME = + "processRobotMapObjectChange"; + +const char *ArMapChanger::CHANGES_IN_PROGRESS_PACKET_NAME = + "mapChangesInProgress"; + +const char *ArMapChanger::ROBOT_CHANGES_COMPLETE_PACKET_NAME = + "robotMapObjectChangeComplete"; + +AREXPORT ArMapChanger::ArMapChanger(ArMapInterface *map) : + myMap(map), + myWorkingMap(NULL), + myChangeDetails(NULL), + //myInfoCount((map != NULL) ? map->getInfoCount() : 0), + myInfoNames(), + myServer(NULL), + myClientSwitch(NULL), + myIsServerClientInit(false), + myClientMutex(), + myClient(NULL), + myClientInfoMutex(), + myClientInfo(NULL), + myInterleaveMutex(), + myReadyForNextPacket(false), + myIsWaitingForReturn(false), + myIdleProcessingMutex(), + myIsIdleProcessingPending(false), + myPreWriteCBList(), + myPostWriteCBList(), + myChangeCBList(), + myHandleChangePacketCB(this, &ArMapChanger::handleChangePacket), + myHandleRobotReplyPacketCB(this, &ArMapChanger::handleRobotChangeReplyPacket), + myHandleChangesInProgressPacketCB(this, &ArMapChanger::handleChangesInProgressPacket), + myHandleReplyPacketCB(this, &ArMapChanger::handleChangeReplyPacket), + myHandleIdleProcessingPacketCB(this, &ArMapChanger::handleIdleProcessingPacket), + myClientShutdownCB(this, &ArMapChanger::handleClientShutdown) +{ + if (myMap != NULL) { + myInfoNames = myMap->getInfoNames(); + } +} // end ctor + +AREXPORT ArMapChanger::ArMapChanger(ArServerBase *server, + ArMapInterface *map) : + myMap(map), + myWorkingMap(NULL), + myChangeDetails(NULL), + //myInfoCount((map != NULL) ? map->getInfoCount() : 0), + myInfoNames(), + myServer(server), + myClientSwitch(NULL), + myIsServerClientInit(false), + myClientMutex(), + myClient(NULL), + myClientInfoMutex(), + myClientInfo(NULL), + myInterleaveMutex(), + myReadyForNextPacket(false), + myIsWaitingForReturn(false), + myIdleProcessingMutex(), + myIsIdleProcessingPending(false), + myPreWriteCBList(), + myPostWriteCBList(), + myChangeCBList(), + myHandleChangePacketCB(this, &ArMapChanger::handleChangePacket), + myHandleRobotReplyPacketCB(this, &ArMapChanger::handleRobotChangeReplyPacket), + myHandleChangesInProgressPacketCB(this, &ArMapChanger::handleChangesInProgressPacket), + myHandleReplyPacketCB(this, &ArMapChanger::handleChangeReplyPacket), + myHandleIdleProcessingPacketCB(this, &ArMapChanger::handleIdleProcessingPacket), + myClientShutdownCB(this, &ArMapChanger::handleClientShutdown) +{ + if (myMap != NULL) { + myInfoNames = myMap->getInfoNames(); + } + if (myServer == NULL) { + + return; + } + myServer->addData(PROCESS_CHANGES_PACKET_NAME, + "Applies changes to the map", + &myHandleChangePacketCB, + "TODO", + "TODO", + "Map", + "RETURN_SINGLE|IDLE_PACKET"); + + myServer->addData(PROCESS_ROBOT_CHANGES_PACKET_NAME, + "Applies changes originated by the robot to the map", + &myHandleChangePacketCB, // Same handler + "Complex packet containing the map changes. See ArMapChangeDetails.", + "None", + "Map", + "RETURN_SINGLE|IDLE_PACKET"); + + myServer->addData(CHANGES_IN_PROGRESS_PACKET_NAME, + "Notifies clients that changes are being applied to the map", + NULL, + "TODO", + "TODO", + "Map", + "RETURN_NONE"); + +} // end ctor + + +AREXPORT ArMapChanger::ArMapChanger(ArClientSwitchManager *clientSwitch, + ArServerBase *server, + ArMapInterface *map) : + myMap(map), + myWorkingMap(NULL), + myChangeDetails(NULL), + //myInfoCount((map != NULL) ? map->getInfoCount() : 0), + myInfoNames(), + myServer(server), + myClientSwitch(clientSwitch), + myIsServerClientInit(false), + myClientMutex(), + myClient(NULL), + myClientInfoMutex(), + myClientInfo(NULL), + myInterleaveMutex(), + myReadyForNextPacket(false), + myIsWaitingForReturn(false), + myIdleProcessingMutex(), + myIsIdleProcessingPending(false), + myPreWriteCBList(), + myPostWriteCBList(), + myChangeCBList(), + myHandleChangePacketCB(this, &ArMapChanger::handleChangePacket), + myHandleRobotReplyPacketCB(this, &ArMapChanger::handleRobotChangeReplyPacket), + myHandleChangesInProgressPacketCB(this, &ArMapChanger::handleChangesInProgressPacket), + myHandleReplyPacketCB(this, &ArMapChanger::handleChangeReplyPacket), + myHandleIdleProcessingPacketCB(this, &ArMapChanger::handleIdleProcessingPacket), + myClientShutdownCB(this, &ArMapChanger::handleClientShutdown) +{ + if (myMap != NULL) { + myInfoNames = myMap->getInfoNames(); + } + if (myServer != NULL) { + + myServer->addData(PROCESS_CHANGES_PACKET_NAME, + "Applies changes to the map", + &myHandleChangePacketCB, + "TODO", + "TODO", + "Map", + "RETURN_SINGLE|IDLE_PACKET"); + + myServer->addData(CHANGES_IN_PROGRESS_PACKET_NAME, + "Notifies clients that changes are being applied to the map", + NULL, + "TODO", + "TODO", + "Map", + "RETURN_NONE"); + } + + if ((myClientSwitch != NULL) && + (myClientSwitch->getCentralServerHostName() != NULL)) { + + myServer->addData(PROCESS_ROBOT_CHANGES_PACKET_NAME, + "Applies ARCL/robot-originated changes to the map", + NULL, + "Complex packet containing the map changes. See ArMapChangeDetails.", + "None", + "Map", + "RETURN_SINGLE|IDLE_PACKET"); + + myServer->addData(ROBOT_CHANGES_COMPLETE_PACKET_NAME, + "Handles notification that the ARCL/robot-originated changes are complete", + &myHandleRobotReplyPacketCB, + "None", + "string: robot originating changes; uByte2: status (0 = failed, 10 = success)" ); + } // end if + +} // end ctor + +AREXPORT ArMapChanger::ArMapChanger(ArClientBase *client, + const std::list &infoNames) : + myMap(NULL), + myWorkingMap(NULL), + myChangeDetails(NULL), + //myInfoCount(infoCount), + myInfoNames(infoNames), + myServer(NULL), + myClientSwitch(NULL), + myClientMutex(), + myClient(client), + myClientInfoMutex(), + myClientInfo(NULL), + myInterleaveMutex(), + myReadyForNextPacket(false), + myIsWaitingForReturn(false), + myIdleProcessingMutex(), + myIsIdleProcessingPending(false), + myPreWriteCBList(), + myPostWriteCBList(), + myChangeCBList(), + myHandleChangePacketCB(this, &ArMapChanger::handleChangePacket), + myHandleChangesInProgressPacketCB(this, &ArMapChanger::handleChangesInProgressPacket), + myHandleReplyPacketCB(this, &ArMapChanger::handleChangeReplyPacket), + myHandleIdleProcessingPacketCB(this, &ArMapChanger::handleIdleProcessingPacket), + myClientShutdownCB(this, &ArMapChanger::handleClientShutdown) +{ + // myMap is null, so don't do this + // if (myMap != NULL) { + // myInfoNames = myMap->getInfoNames(); + //} + + myClientMutex.setLogName("ArMapChanger_ClientMutex"); + myClientInfoMutex.setLogName("ArMapChanger_ClientInfoMutex"); + + if (myClient == NULL) { + + return; + } + myClientMutex.lock(); + + if (myClient && myClient->dataExists(PROCESS_CHANGES_PACKET_NAME)) { + + ArLog::log(ArLog::Normal, + "ArMapChanger::ctor() server supports map changes"); + + myClient->addHandler(PROCESS_CHANGES_PACKET_NAME, + &myHandleReplyPacketCB); + + } // end if processMapChanges available + + if (myClient && myClient->dataExists(CHANGES_IN_PROGRESS_PACKET_NAME)) { + + ArLog::log(ArLog::Normal, + "ArMapChanger::ctor() server notifies of map changes"); + + myClient->addHandler(CHANGES_IN_PROGRESS_PACKET_NAME, + &myHandleChangesInProgressPacketCB); + + myClient->requestOnce(CHANGES_IN_PROGRESS_PACKET_NAME); + myClient->request(CHANGES_IN_PROGRESS_PACKET_NAME, -1); + } + + if (myClient && myClient->dataExists("idleProcessingPending")) { + + ArLog::log(ArLog::Normal, + "ArMapChanger::ctor() server notifies of idle processing"); + + myClient->addHandler("idleProcessingPending", + &myHandleIdleProcessingPacketCB); + + myClient->requestOnce("idleProcessingPending"); + myClient->request("idleProcessingPending", -1); + } + if (myClient) { + myClient->addServerShutdownCB(&myClientShutdownCB); + myClient->addDisconnectOnErrorCB(&myClientShutdownCB); + } + myClientMutex.unlock(); + +} // end ctor + + +AREXPORT ArMapChanger::~ArMapChanger() +{ + if (myClient != NULL) { + myClient->remHandler(PROCESS_CHANGES_PACKET_NAME, + &myHandleReplyPacketCB); + myClient->remHandler(CHANGES_IN_PROGRESS_PACKET_NAME, + &myHandleChangesInProgressPacketCB); + myClient->remHandler("idleProcessingPending", + &myHandleIdleProcessingPacketCB); + myClient->remServerShutdownCB(&myClientShutdownCB); + myClient->remDisconnectOnErrorCB(&myClientShutdownCB); + } +} + +AREXPORT bool ArMapChanger::sendMapChanges(ArMapChangeDetails *changeDetails) +{ + if (changeDetails == NULL) { + return false; + } + if (myClient == NULL) { + return false; + } + + bool isInterleaved = true; + myInterleaveMutex.lock(); + if (myIsWaitingForReturn) + { + ArLog::log(ArLog::Terse, + "ArMapChanger::sendMapChanges() already busy sending changes"); + myInterleaveMutex.unlock(); + return false; + } + myIsWaitingForReturn = true; + myReadyForNextPacket = false; + ArLog::log(ArLog::Normal, + "ArMapChanger::sendMapChanges() set myIsWaitingForReturn = true && myReadyForNextPacket = false"); + myInterleaveMutex.unlock(); + + + + ArMapId givenOrigMapId; + ArMapId givenNewMapId; + + changeDetails->getOrigMapId(&givenOrigMapId); + changeDetails->getNewMapId(&givenNewMapId); + + + // A giant hack to strip out the source name if we're sending the + // changes back to the original source. + myClientMutex.lock(); + const char *robotName = ((myClient != NULL) ? myClient->getRobotName() : ""); + myClientMutex.unlock(); + + if (!ArUtil::isStrEmpty(robotName) && + !ArUtil::isStrEmpty(givenOrigMapId.getSourceName())) { + if (ArUtil::strcasecmp(robotName, givenOrigMapId.getSourceName()) == 0) { + ArMapId modOrigMapId = givenOrigMapId; + modOrigMapId.setSourceName(NULL); + modOrigMapId.setTimestamp(-1); + changeDetails->setOrigMapId(modOrigMapId); + } + } + if (!ArUtil::isStrEmpty(robotName) && + !ArUtil::isStrEmpty(givenNewMapId.getSourceName())) { + if (ArUtil::strcasecmp(robotName, givenNewMapId.getSourceName()) == 0) { + ArMapId modNewMapId = givenNewMapId; + modNewMapId.setSourceName(NULL); + modNewMapId.setTimestamp(-1); + changeDetails->setNewMapId(modNewMapId); + } + } + + + // TODO Probably just want to send each packet as created... + std::list packetList; + bool isSuccess = convertChangeDetailsToPacketList(changeDetails, + &packetList); + + + if (!isSuccess) { + + ArLog::log(ArLog::Normal, + "ArMapChanger::sendMapChanges() error converting change details to network packets"); + return false; + } + + isSuccess = sendPacketList(packetList); + + changeDetails->setOrigMapId(givenOrigMapId); + changeDetails->setNewMapId(givenNewMapId); + + ArLog::log(ArLog::Normal, + "ArMapChanger::sendMapChanges() changes sent (%i), deleting packet list...", + isSuccess); + + ArUtil::deleteSet(packetList.begin(), packetList.end()); + packetList.clear(); + + + return isSuccess; + +} // end method sendMapChanges + + +/// Sends the given map changes from the robot to the central server. +AREXPORT bool ArMapChanger::sendRobotMapChanges(ArMapChangeDetails *changeDetails) +{ + // KMC TODO This looks a lot like sendMapChanges and should be refactored + // (presuming it works) + + if (changeDetails == NULL) { + return false; + } + if ((myClientSwitch == NULL) || + (myClientSwitch->getServerClient() == NULL)) { + return false; + } + + + bool isInterleaved = true; + myInterleaveMutex.lock(); + if (myIsWaitingForReturn) + { + ArLog::log(ArLog::Terse, + "ArMapChanger: already busy sending changes"); + myInterleaveMutex.unlock(); + return false; + } + myIsWaitingForReturn = true; + myReadyForNextPacket = false; + ArLog::log(ArLog::Normal, + "ArMapChanger::sendRobotMapChanges() set myIsWaitingForReturn = true && myReadyForNextPacket = false"); + myInterleaveMutex.unlock(); + + + + ArMapId givenOrigMapId; + ArMapId givenNewMapId; + + changeDetails->getOrigMapId(&givenOrigMapId); + changeDetails->getNewMapId(&givenNewMapId); + + + // A giant hack to strip out the source name if we're sending the + // changes back to the original source. + myClientMutex.lock(); + std::string robotName = ((myClientSwitch != NULL) ? myClientSwitch->getIdentifier() : ""); + myClientMutex.unlock(); + + if (!ArUtil::isStrEmpty(robotName.c_str()) && + !ArUtil::isStrEmpty(givenOrigMapId.getSourceName())) { + if (ArUtil::strcasecmp(robotName.c_str(), givenOrigMapId.getSourceName()) == 0) { + ArMapId modOrigMapId = givenOrigMapId; + modOrigMapId.setSourceName(NULL); + modOrigMapId.setTimestamp(-1); + changeDetails->setOrigMapId(modOrigMapId); + } + } + if (!ArUtil::isStrEmpty(robotName.c_str()) && + !ArUtil::isStrEmpty(givenNewMapId.getSourceName())) { + if (ArUtil::strcasecmp(robotName.c_str(), givenNewMapId.getSourceName()) == 0) { + ArMapId modNewMapId = givenNewMapId; + modNewMapId.setSourceName(NULL); + modNewMapId.setTimestamp(-1); + changeDetails->setNewMapId(modNewMapId); + } + } + + + // TODO Probably just want to send each packet as created... + std::list packetList; + bool isSuccess = convertChangeDetailsToPacketList(changeDetails, + &packetList); + + + if (!isSuccess) { + + ArLog::log(ArLog::Normal, + "ArMapChanger::sendRobotMapChanges() error converting change details to network packets"); + return false; + } + + isSuccess = sendRobotPacketList(packetList); + + changeDetails->setOrigMapId(givenOrigMapId); + changeDetails->setNewMapId(givenNewMapId); + + ArLog::log(ArLog::Normal, + "ArMapChanger::sendMapChanges() changes sent (%i), deleting packet list...", + isSuccess); + + ArUtil::deleteSet(packetList.begin(), packetList.end()); + packetList.clear(); + + + return isSuccess; + +} // end method sendRobotMapChanges + + +bool ArMapChanger::sendPacketList(const std::list &packetList) { + + bool isInterleaved = true; + + ArTime started; + started.setToNow(); + + for (std::list::const_iterator iter = packetList.begin(); + iter != packetList.end(); + iter++) { + + started.setToNow(); + + ArNetPacket *packet = *iter; + if (packet == NULL) { + continue; + } + myClientMutex.lock(); + if (myClient != NULL) { + myClient->requestOnce(PROCESS_CHANGES_PACKET_NAME, + packet); + } + else { + ArLog::log(ArLog::Terse, + "ArMapChanger::sendPacketList aborted because connection lost"); + myClientMutex.unlock(); + return false; + } + + myClientMutex.unlock(); + + /*** + if (isInterleaved) { + if (!waitForReply(started)) { + return false; + } + } // end if interleaved + ***/ + } // end for each packet + + if (!packetList.empty()) { + if (isInterleaved) { + if (!waitForReply(started)) { + return false; + } + } // end if interleaved + } + + return true; + +} // end method sendPacketList + + + +bool ArMapChanger::sendRobotPacketList(const std::list &packetList) { + + bool isInterleaved = true; + ArLog::log(ArLog::Normal, + "ArMapChanger::sendRobotPacketList() count = %i", packetList.size()); + + ArTime started; + started.setToNow(); + + for (std::list::const_iterator iter = packetList.begin(); + iter != packetList.end(); + iter++) { + + started.setToNow(); + + ArNetPacket *packet = *iter; + if (packet == NULL) { + continue; + } + myClientMutex.lock(); + if ((myClientSwitch != NULL) && + (myClientSwitch->getServerClient() != NULL)) { + + unsigned int mapChangesCommand = myClientSwitch->getServerClient()-> + findCommandFromName(PROCESS_ROBOT_CHANGES_PACKET_NAME); + + packet->setCommand(mapChangesCommand); + + myClientSwitch->getServerClient()->broadcastPacketTcp(packet); + +// PROCESS_ROBOT_CHANGES_PACKET_NAME); + } + else { + ArLog::log(ArLog::Terse, + "ArMapChanger::sendRobotPacketList aborted because connection lost"); + myClientMutex.unlock(); + return false; + } + + myClientMutex.unlock(); + + /*** + if (isInterleaved) { + if (!waitForReply(started)) { + return false; + } + } // end if interleaved + ***/ + } // end for each packet + +/*** KMC Don't actually want to wait for the packet + if (!packetList.empty()) { + if (isInterleaved) { + if (!waitForCentralServerReply(started)) { + return false; + } + } // end if interleaved + } +***/ + return true; + +} // end method sendRobotPacketList + + + +bool ArMapChanger::waitForReply(ArTime &started) +{ + myInterleaveMutex.lock(); + + // myReadyForNextPacket is set to true when the response is received + // from the server. + while (!myReadyForNextPacket) + { + if (!myIsWaitingForReturn) + { + ArLog::log(ArLog::Normal, + "ArMapChanger::waitForReply: Put was cancelled or failed."); + myInterleaveMutex.unlock(); + return false; + } + myInterleaveMutex.unlock(); + + + myClientMutex.lock(); + + if (myClient == NULL) { + ArLog::log(ArLog::Normal, + "ArMapChanger::waitForReply: Client was shutdown."); + myClientMutex.unlock(); + return false; + } + myClientMutex.unlock(); + + ArUtil::sleep(1); + + if (!isIdleProcessingPending()) { + if (started.secSince() > 30) + { + myInterleaveMutex.lock(); + ArLog::log(ArLog::Normal, + "ArMapChanger::waitForReply() set myIsWaitingForReturn = false"); + myIsWaitingForReturn = false; + myInterleaveMutex.unlock(); + + ArLog::log(ArLog::Normal, + "ArMapChanger::waitForReply: No return from client within 30 seconds, failing put."); + return false; + } + } + else { + started.setToNow(); + } + myInterleaveMutex.lock(); + + } // end while not ready for next packet + + // Reset the flag so we'll wait for a response during the next loop iteration. + myReadyForNextPacket = false; + ArLog::log(ArLog::Normal, + "ArMapChanger::waitForReply() set myReadyForNextPacket = false"); + + myInterleaveMutex.unlock(); + + return true; + +} // end method waitForReply + + +bool ArMapChanger::waitForCentralServerReply(ArTime &started) +{ + ArLog::log(ArLog::Normal, + "ArMapChanger::waitForCentralServerReply() called"); + + myInterleaveMutex.lock(); + + // myReadyForNextPacket is set to true when the response is received + // from the server. + while (!myReadyForNextPacket) + { + if (!myIsWaitingForReturn) + { + ArLog::log(ArLog::Normal, + "ArMapChanger::waitForCentralServerReply: Put was cancelled or failed."); + myInterleaveMutex.unlock(); + return false; + } + myInterleaveMutex.unlock(); + +/*** KMC TODO + myClientMutex.lock(); + + if (myClient == NULL) { + ArLog::log(ArLog::Normal, + "ArMapChanger::waitForCentralServerReply: Client was shutdown."); + myClientMutex.unlock(); + return false; + } + myClientMutex.unlock(); +******/ + + ArUtil::sleep(1); + + if (true || !isIdleProcessingPending()) { + if (started.secSince() > 30) + { + myInterleaveMutex.lock(); + myIsWaitingForReturn = false; + ArLog::log(ArLog::Normal, + "ArMapChanger::waitForCentralServerReply() set myIsWaitingForReturn = false (timeout)"); + myInterleaveMutex.unlock(); + + ArLog::log(ArLog::Normal, + "ArMapChanger::waitForCentralServerReply: No return from client within 30 seconds, failing put."); + return false; + } + } + else { + started.setToNow(); + } + myInterleaveMutex.lock(); + + } // end while not ready for next packet + + // Reset the flag so we'll wait for a response during the next loop iteration. + ArLog::log(ArLog::Normal, + "ArMapChanger::waitForCentralServerReply() set myReadyForNextPacket = false"); + myReadyForNextPacket = false; + + myInterleaveMutex.unlock(); + + return true; + +} // end method waitForCentralServerReply + +bool ArMapChanger::isIdleProcessingPending() +{ + myIdleProcessingMutex.lock(); + bool isPending = myIsIdleProcessingPending; + myIdleProcessingMutex.unlock(); + + return isPending; + +} // end method isIdleProcessingPending + + +AREXPORT void ArMapChanger::handleChangeReplyPacket(ArNetPacket *packet) +{ + IFDEBUG(ArLog::log(ArLog::Normal, + "ArMapChanger::handleChangeReplyPacket()")); + + myInterleaveMutex.lock(); + if (!myIsWaitingForReturn) + { + myInterleaveMutex.unlock(); + return; + } + + int ret = packet->bufToUByte2(); + + // packet->bufToStr(fileName, sizeof(fileName)); + // if (myInterleaved && ret == 10) + if (ret == CHANGE_SUCCESS) + { + myReadyForNextPacket = true; + ArLog::log(ArLog::Normal, + "ArMapChanger::handleChangeReplyPacket() set myReadyForNextPacket = false"); + + } + else + { + myIsWaitingForReturn = false; + ArLog::log(ArLog::Normal, + "ArMapChanger::handleChangeReplyPacket() set myIsWaitingForReturn = false"); + } + myInterleaveMutex.unlock(); + + //if (done) + // callFileSentCallbacks(ret); +} // end method handleChangeReplyPacket + + +AREXPORT void ArMapChanger::handleChangesInProgressPacket(ArNetPacket *packet) +{ + if (packet == NULL) { + return; + } + bool isInProgress = (packet->bufToUByte() != 0); + + ArLog::log(ArLog::Normal, + "ArMapChanger::handleChangesInProgressPacket() in progress = %i", + isInProgress); + +} // end method handleChangesInProgressPacket + + +AREXPORT void ArMapChanger::handleIdleProcessingPacket(ArNetPacket *packet) +{ + if (packet == NULL) { + return; + } + unsigned char isPending = packet->bufToByte(); + + ArLog::log(ArLog::Normal, + "ArMapChanger::handleIdleProcessingPacket() idleProcessingPending = %i", + isPending); + + myIdleProcessingMutex.lock(); + myIsIdleProcessingPending = isPending; + myIdleProcessingMutex.unlock(); + +} // end method handleIdleProcessingPacket + + +AREXPORT void ArMapChanger::handleChangePacket(ArServerClient *client, + ArNetPacket *packet) +{ + if (packet == NULL) { + return; + } + + if (myMap == NULL) { + ArLog::log(ArLog::Normal, + "ArMapChanger::handleChangePacket no map to change"); + return; + } + + ArNetPacket replyPacket; + bool isChangesStarted = false; + bool isChangesFinished = false; + + ArMapId thisMapId; + myMap->getMapId(&thisMapId); + + MapChangeCommand command; + ArMapId origMapId; + ArMapId newMapId; + + bool isSuccess = unpackHeader(packet, &command, &origMapId, &newMapId); + + if (!isSuccess) { + ArLog::log(ArLog::Terse, + "ArMapChanger::handleChangePacket() cannot unpack header"); + + replyPacket.uByte2ToBuf(CHANGE_FAILED); + client->sendPacketTcp(&replyPacket); + + return; + + } + + // KMC TODO Figure out appropriate "same map" check for deltas from robot + bool isSameMap = true; + + if (!origMapId.isNull()) { + isSameMap = thisMapId.isSameFile(origMapId); + + if (isSameMap) { + if (ArUtil::strcasecmp(thisMapId.getFileName(), + newMapId.getFileName()) != 0) { + // Hopefully this won't happen, but make sure that the client isn't + // renaming the map file. + isSameMap = false; + } + } + } // end if same map + + // TODO: Not sure how to handle this... Right now just allowing changes + // on current map. But may want a big map manager thing later. + if (!isSameMap) { + + + // In the case of changes propagated from the central server, no one + // will be waiting for the replies -- and so the FINISH_CHANGES message + // will be received. Send this server's map ID to the central server + // so that the CS can refresh the file if necessary. (Most likely in + // the case in which the CS and the robot have different + // AramMapInfoMinder's.) + if (command == FINISH_CHANGES) { + + ArLog::log(ArLog::Normal, + "ArMapChanger::handleChangePacket() packet received for other map"); + thisMapId.log("This Map"); + origMapId.log("Received Map - Original"); + newMapId.log("Received Map - New"); + + replyPacket.uByte2ToBuf(CHANGE_FAILED); + client->sendPacketTcp(&replyPacket); + + // Have no idea whether this is going to work... + + ArNetPacket mapIdPacket; + + unsigned int mapIdCommand = client->findCommandFromName("getMapId"); + + mapIdPacket.setCommand(mapIdCommand); + ArMapId::toPacket(thisMapId, + &mapIdPacket); + + ArLog::log(ArLog::Normal, + "ArMapChanger::internalChangeMap() packet sending map Id packet command = %i", + mapIdCommand); + + client->sendPacketTcp(&mapIdPacket); + + } + + return; + + } // end if not same map + + + switch (command) { + + case START_CHANGES: + { + myClientInfoMutex.lock(); + // if other client making changes then + if (myClientInfo != NULL) { + // if other client has timed out then + if (myClientInfo->myLastActivityTime.secSince() > 15) { + // TODO notify other client that its being dumped + + delete myClientInfo; + myClientInfo = NULL; + } + else { + + // TODO notify this client that it can't change yet + + myClientInfoMutex.unlock(); + return; + } // end else other client has not timed out + } // end if other client is currently changing same map + + // setup changes for this client + myClientInfo = new ClientChangeInfo(client); + + myClientInfo->addPacket(packet); + + isChangesStarted = true; + + + myClientInfoMutex.unlock(); + + + } + break; + + case CONTINUE_CHANGES: + { + + // append changes for this client + myClientInfoMutex.lock(); + if ((myClientInfo != NULL) && (myClientInfo->myClient == client)) { + + // TODO: Not entirely sure about this... We could build up the + // change details and then apply them... + + // Save a copy of the packet... Want to receive all changes before applying them + + // TODO The copy ctor for ArNetPacket should be disabled if it's not going to work + myClientInfo->addPacket(packet); + } + else { + + // notify the client that something has gone terribly wrong + } + myClientInfoMutex.unlock(); + } + break; + + case FINISH_CHANGES: + { + // apply changes for this client + myClientInfoMutex.lock(); + + if ((myClientInfo != NULL) && (myClientInfo->myClient == client)) { + + // TODO: Probably need to do the apply in a separate thread and have a + // success/fail callback + + myClientInfo->addPacket(packet); + + ArMapChangeDetails *changeDetails = new ArMapChangeDetails(); + + isSuccess = convertPacketListToChangeDetails(myClientInfo->myPacketList, + changeDetails); + + changeDetails->log(); + + ArMapId newMapId; + changeDetails->getNewMapId(&newMapId); + bool isRepackageChanges = (!newMapId.isValidTimestamp()); + + + if (isSuccess) { + + isSuccess = applyMapChanges(changeDetails); + + if (isSuccess) { + + ArLog::log(ArLog::Normal, + "ArMapChanger::internalChangeMap Change details successfully applied to map"); + + } + else { // error applying map changes + ArLog::log(ArLog::Normal, + "ArMapChanger::internalChangeMap Error applying change details to map"); + } // end else error applying map changes + } + else { // error converting packet list + ArLog::log(ArLog::Normal, + "ArMapChanger::internalChangeMap Error converting packet list to map change details"); + } // end else error converting packet list + + + if (isSuccess && !myChangeCBList.empty()) { + + std::list relayPacketList; + if (!isRepackageChanges) { + ArLog::log(ArLog::Normal, + "ArMapChanger::internalChangeMap Relaying original change packets"); + relayPacketList = myClientInfo->myPacketList; + } + else { + ArLog::log(ArLog::Normal, + "ArMapChanger::internalChangeMap Recreating change packets"); + convertChangeDetailsToPacketList(changeDetails, + &relayPacketList, + true); + } + + for (std::list< ArFunctor2 *> *>::iterator cbIter = + myChangeCBList.begin(); + cbIter != myChangeCBList.end(); + cbIter++) { + + ArFunctor2 *> *functor = + *cbIter; + + resetPacketList(&myClientInfo->myPacketList); + + functor->invoke(myClientInfo->myClient, + &relayPacketList); + } + + } // end if changes successfully applied and callbacks + + + delete changeDetails; + + delete myClientInfo; + myClientInfo = NULL; + + } + else { + + // notify the client that something has gone terribly wrong + ArLog::log(ArLog::Normal, + "ArMapChanger::handleChangePacket() cannot finish changes from other client"); + isSuccess = false; + + } + + isChangesFinished = true; + + myClientInfoMutex.unlock(); + } + break; + + case CANCEL_CHANGES: + { + // cancel changes for this client + // reset + // apply changes for this client + myClientInfoMutex.lock(); + if ((myClientInfo != NULL) && (myClientInfo->myClient == client)) { + delete myClientInfo; + myClientInfo = NULL; + ArLog::log(ArLog::Normal, + "ArMapChanger::handleChangePacket() cancelling changes"); + } + else { + + // notify the client that something has gone terribly wrong + ArLog::log(ArLog::Normal, + "ArMapChanger::handleChangePacket() cannot cancel changes from other client"); + isSuccess = false; + } + + isChangesFinished = true; + + myClientInfoMutex.unlock(); + } + break; + + } // end switch + + + if ((isChangesStarted) && (myServer != NULL)) { + // Broadcast that changes are in progress in order to prevent others from + // applying changes during this time. + // + ArNetPacket inProgressPacket; + inProgressPacket.uByteToBuf(true); + myServer->broadcastPacketTcp(&inProgressPacket, + CHANGES_IN_PROGRESS_PACKET_NAME); + + } + + if (isChangesFinished) { + if (isSuccess) { + replyPacket.uByte2ToBuf(CHANGE_SUCCESS); + } + else { + replyPacket.uByte2ToBuf(CHANGE_FAILED); + // TODO Think about adding an error message + } + client->sendPacketTcp(&replyPacket); + + + if (myServer != NULL) { + // Broadcast that changes are no longer in progress. + // + ArNetPacket inProgressPacket; + inProgressPacket.uByteToBuf(false); + myServer->broadcastPacketTcp(&inProgressPacket, + CHANGES_IN_PROGRESS_PACKET_NAME); + } + } // end if + +} // end method handleChangePacket + + +AREXPORT void ArMapChanger::handleClientShutdown() +{ + ArLog::log(ArLog::Normal, + "ArMapChanger::handleClientShutdown() received"); + + // Doing this so that we don't attempt to remove the handlers in the destructor -- + // which wreaks havoc if the client base has already been deleted. + + myClientMutex.lock(); + myClient = NULL; + myClientMutex.unlock(); + +} // end method handleClientShutdown + + +void ArMapChanger::resetPacketList(std::list *packetList) +{ + if (packetList == NULL) { + return; + } + + for (std::list::iterator iter = packetList->begin(); + iter != packetList->end(); + iter++) { + ArNetPacket *packet = *iter; + if (packet == NULL) { + continue; + } + packet->resetRead(); + } + +} // end method packetList + +/*** +bool ArMapChanger::applyMapChanges(std::list &packetList) +{ + ArMapChangeDetails *changeDetails = new ArMapChangeDetails(); + + bool isSuccess = convertPacketListToChangeDetails(packetList, + changeDetails); + + if (isSuccess) { + isSuccess = applyMapChanges(changeDetails); + + if (isSuccess) { + + ArLog::log(ArLog::Normal, + "Change details successfully applied to map"); + + } + else { // error applying map changes + ArLog::log(ArLog::Normal, + "Error applying change details to map"); + } // end else error applying map changes + } + else { // error converting packet list + ArLog::log(ArLog::Normal, + "Error converting packet list to map change details"); + } // end else error converting packet list + + changeDetails->log(); + + delete changeDetails; + + return isSuccess; +} +***/ + +AREXPORT bool ArMapChanger::applyMapChanges(ArMapChangeDetails *changeDetails) +{ + + if (changeDetails == NULL) { + return false; + } + if (myMap == NULL) { + return false; + } + + myMap->lock(); + + ArLog::log(ArLog::Normal, + "ArMapChanger::applyMapChanges() begin"); + + myWorkingMap = myMap->clone(); + + bool isSuccess = true; + + // -------------------------------------------------------------------------- + // Apply Scan changes... + // + isSuccess = applyScanChanges(changeDetails) && isSuccess; + + // -------------------------------------------------------------------------- + // Apply Supplement changes... + // + isSuccess = applySupplementChanges(changeDetails) && isSuccess; + + // -------------------------------------------------------------------------- + // Apply Object changes... + // + isSuccess = applyObjectChanges(changeDetails) && isSuccess; + + // -------------------------------------------------------------------------- + // Apply Info changes... + // + isSuccess = applyInfoChanges(changeDetails) && isSuccess; + + + ArMapId mapId; + ArMapId changesMapId; + ArMapId newMapId; + + myMap->getMapId(&mapId); + + + + if (isSuccess) { + + changeDetails->getNewMapId(&changesMapId); + + unsigned char tempChecksum[ArMD5Calculator::DIGEST_LENGTH]; + myWorkingMap->calculateChecksum(tempChecksum, + ArMD5Calculator::DIGEST_LENGTH); + + if ((changesMapId.getChecksum () != NULL) && + (memcmp(changesMapId.getChecksum(), + tempChecksum, + ArMD5Calculator::DIGEST_LENGTH) != 0)) { + + char tempChecksumDisplay[ArMD5Calculator::DISPLAY_LENGTH]; + ArMD5Calculator::toDisplay(tempChecksum, + ArMD5Calculator::DIGEST_LENGTH, + tempChecksumDisplay, + ArMD5Calculator::DISPLAY_LENGTH); + + // Different checksums + ArLog::log(ArLog::Normal, +"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n\ +Map Checksums different after applying changes\n\ + From Client: %s\n\ + Calculated : %s\n\ +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!", + changesMapId.getDisplayChecksum(), + tempChecksumDisplay); + + isSuccess = false; + + /*** + // Re-insert this to debug why map changes weren't applied + // successfully. (Run diff on MapChangeError.map and robot's + // current map.) + bool isWriteBadMap = true; + + if (isWriteBadMap) { + myWorkingMap->writeFile("MapChangeError.map"); + } + ***/ + + } // end if different checksums + + } // end if changes successfully applied + + if (isSuccess) { + + myMap->set(myWorkingMap); + + ArLog::log(ArLog::Normal, + "Successfully applied changes to map %s, saving file", + mapId.getFileName()); + + std::list::iterator iter = myPreWriteCBList.begin(); + + for (iter = myPreWriteCBList.begin(); + iter != myPreWriteCBList.end(); + iter++) { + myMap->addPreWriteFileCB(*iter); + } + for (iter = myPostWriteCBList.begin(); + iter != myPostWriteCBList.end(); + iter++) { + myMap->addPostWriteFileCB(*iter); + } + + isSuccess = myMap->writeFile(mapId.getFileName(), + true, + NULL, 0, + changesMapId.getTimestamp()); + + for (iter = myPreWriteCBList.begin(); + iter != myPreWriteCBList.end(); + iter++) { + myMap->remPreWriteFileCB(*iter); + } + for (iter = myPostWriteCBList.begin(); + iter != myPostWriteCBList.end(); + iter++) { + myMap->remPostWriteFileCB(*iter); + } + + myMap->getMapId(&newMapId); + + if (changesMapId.isNull() || (changesMapId == newMapId)) { + // This will actually insert the timestamp into the map ID + changeDetails->setNewMapId(newMapId); + + } + else { + + ArLog::log(ArLog::Normal, +"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n\ + Map IDs different after applying changes\n\ +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); + changesMapId.log("Changes Map ID"); + newMapId.log("New Map ID"); + + isSuccess = false; + + } + } // end if successful + + if (isSuccess) { + + ArLog::log(ArLog::Normal, + "Successfully saved file for map %s, emitting mapChanged", + mapId.getFileName()); + + myMap->mapChanged(); // ??? TODO + } + else { // error occurred + + ArLog::log(ArLog::Terse, + "An error occurred while applying changes to map %s", + mapId.getFileName()); + + // TODO Notify client of error (and hopefully get full map file) + + } // end else error occurred + + delete myWorkingMap; + myWorkingMap = NULL; + + myMap->unlock(); + + ArLog::log(ArLog::Normal, + "ArMapChanger::applyMapChanges() end"); + + return isSuccess; + +} // end method applyMapChanges + + +bool ArMapChanger::applyScanChanges(ArMapChangeDetails *changeDetails) +{ + if ((changeDetails == NULL) || (myWorkingMap == NULL)) { + return false; + } + + std::list *scanTypeList = changeDetails->getScanTypes(); + + if ((scanTypeList == NULL) || (scanTypeList->empty())) { + return true; + } + ArFileParser parser; + bool isSuccess = myWorkingMap->addToFileParser(&parser); + + for (std::list::iterator iter = scanTypeList->begin(); + (isSuccess && (iter != scanTypeList->end())); + iter++) { + + const char *scanType = (*iter).c_str(); + isSuccess = applyScanChanges(changeDetails, scanType, parser); + } + + myWorkingMap->remFromFileParser(&parser); + + return isSuccess; + +} // end for each scan type + + +bool ArMapChanger::applyScanChanges(ArMapChangeDetails *changeDetails, + const char *scanType, + ArFileParser &parser) +{ + + ArLog::log(ArLog::Normal, + "ArMapChanger::applyScanChanges() for scan type %s", + scanType); + + ArMapFileLineSet *newSummaryLines = changeDetails->getChangedSummaryLines + (ArMapChangeDetails::ADDITIONS, + scanType); + if (newSummaryLines == NULL) { + ArLog::log(ArLog::Normal, + "ArMapChanger::applyScanChanges() for scan type %s, error getting added summary lines", + scanType); + return false; + } + + bool isSuccess = true; + + char buf[10000]; + + for (ArMapFileLineSet::iterator iter = newSummaryLines->begin(); + iter != newSummaryLines->end(); + iter++) { + ArMapFileLineGroup &group = *iter; + strncpy(buf, group.getParentLine()->getLineText(), sizeof(buf)); + buf[sizeof(buf) - 1] = '\0'; + ArLog::log(ArLog::Normal, + "Parsing summary line: %s", + buf); + + isSuccess = parser.parseLine(buf) && isSuccess; + if (!isSuccess) { + + ArLog::log(ArLog::Normal, + "Error parsing summary line: %s", + group.getParentLine()->getLineText()); + } + + } // end for each new summary line + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Process point changes... + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + std::vector *deletedPoints = changeDetails->getChangedPoints + (ArMapChangeDetails::DELETIONS, + scanType); + std::vector *addedPoints = changeDetails->getChangedPoints + (ArMapChangeDetails::ADDITIONS, + scanType); + + std::vector *mapPoints = myWorkingMap->getPoints(scanType); + + if ((deletedPoints == NULL) || (addedPoints == NULL) || (mapPoints == NULL)) { + return false; + } + ArLog::log(ArLog::Normal, + "ArMapChanger::applyScanChanges() for scan type %s initial points: %i deletedPoints: %i addedPoints: %i, numPointsInMap: %i", + scanType, + mapPoints->size(), + deletedPoints->size(), + addedPoints->size(), + myWorkingMap->getNumPoints()); + + std::sort(mapPoints->begin(), mapPoints->end()); + std::sort(deletedPoints->begin(), deletedPoints->end()); + std::sort(addedPoints->begin(), addedPoints->end()); + + /****/ + // Handle the simple but unlikely case that all points were deleted + if (deletedPoints->size() >= mapPoints->size()) { + mapPoints->clear(); + *mapPoints = *addedPoints; + } + else if (deletedPoints->empty()) { + if (!addedPoints->empty()) { + std::vector tempPoints; + tempPoints.reserve(myWorkingMap->getNumPoints(scanType) + addedPoints->size()); + merge(mapPoints->begin(), mapPoints->end(), + addedPoints->begin(), addedPoints->end(), + std::inserter(tempPoints, + tempPoints.begin())); + *mapPoints = tempPoints; + } // end if points were added (but not deleted) + } + else { // some but not all points were deleted + + ArTime timeToDelete; + std::vector tempPoints; + tempPoints.reserve(myWorkingMap->getNumPoints(scanType)); + + set_difference(mapPoints->begin(), mapPoints->end(), + deletedPoints->begin(), deletedPoints->end(), + std::inserter(tempPoints, + tempPoints.begin())); + long int elapsed = timeToDelete.mSecSince(); + + ArLog::log(ArLog::Normal, + "ArMapChanger::applyScanChanges() took %i msecs to apply deletions in %i points (map points size = %i, deleted points size = %i, temp size = %i)", + elapsed, + myWorkingMap->getNumPoints(scanType), + mapPoints->size(), + deletedPoints->size(), + tempPoints.size()); + + if (!addedPoints->empty()) { + mapPoints->clear(); + mapPoints->reserve(tempPoints.size() + addedPoints->size()); + merge(tempPoints.begin(), tempPoints.end(), + addedPoints->begin(), addedPoints->end(), + std::inserter(*mapPoints, + mapPoints->begin())); + } + else { + ArLog::log(ArLog::Normal, + "ArMapChanger::applyScanChanges() copying tempPoints to map points"); + + *mapPoints = tempPoints; + } + + } // end if some but not all points were deleted + + if (myWorkingMap->getNumPoints(scanType) != mapPoints->size()) { + ArLog::log(ArLog::Normal, + "Error changing points: map's numPoints = %i, num points in map = %i", + myWorkingMap->getNumPoints(scanType), + mapPoints->size()); + } + + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Process line changes... + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + std::vector *deletedLines = changeDetails->getChangedLineSegments + (ArMapChangeDetails::DELETIONS, + scanType); + std::vector *addedLines = changeDetails->getChangedLineSegments + (ArMapChangeDetails::ADDITIONS, + scanType); + + std::vector *mapLines = myWorkingMap->getLines(scanType); + if ((deletedLines == NULL) || (addedLines == NULL) || (mapLines == NULL)) { + return false; + } + + /****/ + // Handle the simple but unlikely case that all lines were deleted + if (deletedLines->size() >= mapLines->size()) { + mapLines->clear(); + *mapLines = *addedLines; + } + else if (deletedLines->empty()) { + if (!addedLines->empty()) { + std::vector tempLines; + tempLines.reserve(myWorkingMap->getNumLines(scanType) + addedLines->size()); + merge(mapLines->begin(), mapLines->end(), + addedLines->begin(), addedLines->end(), + std::inserter(tempLines, + tempLines.begin())); + *mapLines = tempLines; + } // end if lines were added (but not deleted) + } + else { // some but not all lines were deleted + + ArTime timeToDelete; + std::vector tempLines; + tempLines.reserve(myWorkingMap->getNumLines(scanType)); + + set_difference(mapLines->begin(), mapLines->end(), + deletedLines->begin(), deletedLines->end(), + std::inserter(tempLines, + tempLines.begin())); + long int elapsed = timeToDelete.mSecSince(); + + ArLog::log(ArLog::Normal, + "ArMapChanger::applyScanChanges() took %i msecs to apply deletions in %i lines", + elapsed, + myWorkingMap->getNumLines(scanType)); + + if (!addedLines->empty()) { + mapLines->clear(); + mapLines->reserve(tempLines.size() + addedLines->size()); + merge(tempLines.begin(), tempLines.end(), + addedLines->begin(), addedLines->end(), + std::inserter(*mapLines, + mapLines->begin())); + } + else { + *mapLines = tempLines; + } + + } + + if (myWorkingMap->getNumLines(scanType) != mapLines->size()) { + ArLog::log(ArLog::Normal, + "Error changing lines: map's numLines = %i, num lines in map = %i", + myWorkingMap->getNumLines(scanType), + mapLines->size()); + } + + return isSuccess; + +} // end method applyScanChanges + + + +bool ArMapChanger::applySupplementChanges(ArMapChangeDetails *changeDetails) +{ + + ArMapFileLineSet *newSupplementLines = changeDetails->getChangedSupplementLines + (ArMapChangeDetails::ADDITIONS); + if (newSupplementLines == NULL) { + return false; + } + ArFileParser parser; + bool isSuccess = myWorkingMap->addToFileParser(&parser); + + char buf[10000]; + + for (ArMapFileLineSet::iterator iter = newSupplementLines->begin(); + iter != newSupplementLines->end(); + iter++) { + ArMapFileLineGroup &group = *iter; + strncpy(buf, group.getParentLine()->getLineText(), sizeof(buf)); + buf[sizeof(buf) - 1] = '\0'; + ArLog::log(ArLog::Normal, + "Parsing supplement line: %s", + buf); + + isSuccess = parser.parseLine(buf) && isSuccess; + if (!isSuccess) { + + ArLog::log(ArLog::Normal, + "Error parsing summary line: %s", + group.getParentLine()->getLineText()); + } + + } // end for each new supplement line + + myWorkingMap->remFromFileParser(&parser); + + return isSuccess; + +} // end method applySupplementChanges + + +bool ArMapChanger::applyObjectChanges(ArMapChangeDetails *changeDetails) +{ + if ((changeDetails == NULL) || (myWorkingMap == NULL)) { + return false; + } + + ArMapFileLineSet *deletedLineSet = changeDetails->getChangedObjectLines + (ArMapChangeDetails::DELETIONS); + ArMapFileLineSet *addedLineSet = changeDetails->getChangedObjectLines + (ArMapChangeDetails::ADDITIONS); + + if ((deletedLineSet == NULL) || (addedLineSet == NULL)) { + // TODO Log error, really shouldn't happen + return false; + } + + if (myWorkingMap->getMapObjects() == NULL) { + return false; + } + + bool isSuccess = true; + + std::list *mapObjectList = new std::list + (*(myWorkingMap->getMapObjects())); + + + for (ArMapFileLineSet::iterator dIter = deletedLineSet->begin(); + dIter != deletedLineSet->end(); + dIter++) { + + ArMapFileLineGroup &group = *dIter; + + ArArgumentBuilder *objectArg = new ArArgumentBuilder(512, '\0', false, true); + objectArg->addPlain(group.getParentLine()->getLineText()); + objectArg->removeArg(0, true); // To get rid of the Cairn + + ArMapObject *objectToDelete = ArMapObject::createMapObject(objectArg); + + if (objectToDelete == NULL) { + ArLog::log(ArLog::Normal, + "ArMapChanger::applyObjectChanges() error creating object to delete"); + isSuccess = false; + continue; + // TODO Return false? + } + + // TODO Check name doesn't already exist? + + std::list::iterator mIter = mapObjectList->begin(); + for (; + mIter != mapObjectList->end(); + mIter++) { + if (isMatchingObjects(objectToDelete, *mIter)) { // , changeDetails)) { + break; + } + } // end for each map object + + if (mIter != mapObjectList->end()) { + mapObjectList->erase(mIter); + } + else { + ArLog::log(ArLog::Normal, + "Could not find matching map object to delete"); + isSuccess = false; + objectToDelete->log(); + } + + delete objectToDelete; + + } // end for each object to delete + + + for (ArMapFileLineSet::iterator aIter = addedLineSet->begin(); + aIter != addedLineSet->end(); + aIter++) { + + ArMapFileLineGroup &group = *aIter; + + ArArgumentBuilder *objectArg = new ArArgumentBuilder(512, '\0', false, true); + objectArg->addPlain(group.getParentLine()->getLineText()); + objectArg->removeArg(0, true); // To get rid of the Cairn + + ArMapObject *objectToAdd = ArMapObject::createMapObject(objectArg); + + if (objectToAdd == NULL) { + ArLog::log(ArLog::Normal, + "ArMapChanger::applyObjectChanges() error creating object to add"); + isSuccess = false; + continue; + // TODO Return false? + } + + // TODO Check name doesn't already exist? + // TODO Alright to mangle order? Or should we reinsert at "right" line? + + mapObjectList->push_back(objectToAdd); + + } // end for each object to add + + myWorkingMap->setMapObjects(mapObjectList); + + ArUtil::deleteSet(mapObjectList->begin(), mapObjectList->end()); + delete mapObjectList; + + return isSuccess; + +} // end method applyObjectChanges + +bool ArMapChanger::isMatchingObjects(ArMapObject *obj1, + ArMapObject *obj2) +{ + // TODO Make this an ArMapObject method + + if ((obj1 == NULL) || (obj2 == NULL)) { + return false; + } + + if (!ArUtil::isStrEmpty(obj1->getName())) { + if (!ArUtil::isStrEmpty(obj2->getName())) { + if (ArUtil::strcasecmp(obj1->getName(), obj2->getName()) == 0) { + return true; + } + else { // names don't match + return false; + } // end else names don't match + } + else { // second object has null name, no match + return false; + } + } // end if object 1 has name + + // Otherwise, objects don't have names... + + if (obj1->hasFromTo() != obj2->hasFromTo()) { + return false; + } + if (ArUtil::strcasecmp(obj1->getType(), obj2->getType()) != 0) { + return false; + } + if (obj1->getPose() != obj2->getPose()) { + return false; + } + if (obj1->hasFromTo()) { + if (obj1->getFromPose() != obj2->getFromPose()) { + return false; + } + if (obj1->getToPose() != obj2->getToPose()) { + return false; + } + } // end if has from to + + if (ArUtil::strcasecmp(obj1->getDescription(), obj2->getDescription()) != 0) { + return false; + } + if (ArUtil::strcasecmp(obj1->getIconName(), obj2->getIconName()) != 0) { + return false; + } + + std::list obj1Lines = obj1->getFromToSegments(); + std::list obj2Lines = obj2->getFromToSegments(); + + if (obj1Lines.size() != obj2Lines.size()) { + return false; + } + + for (std::list::iterator iter1 = obj1Lines.begin(), + iter2 = obj2Lines.begin(); + ((iter1 != obj1Lines.end()) && (iter2 != obj2Lines.end())); + iter1++, iter2++) { + ArLineSegment &seg1 = *iter1; + ArLineSegment &seg2 = *iter2; + + if (seg1 != seg2) { + return false; + } + } // end for each line segment + + return true; + +} // end method isMatchingObjects + + +bool ArMapChanger::applyInfoChanges(ArMapChangeDetails *changeDetails) +{ + if ((changeDetails == NULL) || (myWorkingMap == NULL)) { + return false; + } + bool isSuccess = true; + + std::list changedInfoNames = changeDetails->findChangedInfoNames(); + + + for (std::list::iterator tIter = changedInfoNames.begin(); + tIter != changedInfoNames.end(); + tIter++) { + + const char *infoName = (*tIter).c_str(); + + IFDEBUG(ArLog::log(ArLog::Normal, + "ArMapChanger::applyInfoChanges() applying changes to %s", + infoName)); + + ArMapFileLineSet *deletedLineSet = changeDetails->getChangedInfoLines + (infoName, + ArMapChangeDetails::DELETIONS); + ArMapFileLineSet *addedLineSet = changeDetails->getChangedInfoLines + (infoName, + ArMapChangeDetails::ADDITIONS); + + + if ((deletedLineSet == NULL) || (addedLineSet == NULL)) { + // TODO Log error, really shouldn't happen + continue; + } + + std::list *infoList = myWorkingMap->getInfo(infoName); + + if (infoList == NULL) { + ArLog::log(ArLog::Normal, + "ArMapChanger::applyInfoChanges() null info list for %s", + infoName); + + isSuccess = false; + continue; + } + + std::list tempInfoList; + + int lineNum = 0; + bool isParentDeleted = false; + + for (std::list::iterator iter1 = infoList->begin(); + iter1 != infoList->end(); + iter1++) { + + ArArgumentBuilder *arg = *iter1; + lineNum++; + + if (!changeDetails->isChildArg(infoName, arg)) { + isParentDeleted = false; + + std::string namePlusArg = infoName; // myWorkingMap->getInfoName(infoType); + namePlusArg += " "; + namePlusArg += arg->getFullString(); + + ArMapFileLineSet::iterator delLineIter = + deletedLineSet->find(ArMapFileLine(lineNum, + namePlusArg.c_str())); + + if (delLineIter != deletedLineSet->end()) { + + // line has been deleted, do not re-add + isParentDeleted = true; + + ArLog::log(ArLog::Normal, + "Deleted: %s", + arg->getFullString()); + ArLog::log(ArLog::Normal, + "Based on: %s", + namePlusArg.c_str()); + + continue; + } + + } + else if (isParentDeleted) { + continue; + } + + tempInfoList.push_back(new ArArgumentBuilder(*arg)); + + } // end for each original info line + + if (!addedLineSet->empty()) { + + std::list newInfoList; + + int lineNum = 0; + bool isDone = false; + ArMapFileLineSet::iterator addIter = addedLineSet->begin(); + std::list::iterator origIter = tempInfoList.begin(); + + while (!isDone) { + + lineNum++; + + if (addIter != addedLineSet->end()) { + + ArMapFileLineGroup &lineGroup = *addIter; + if (lineGroup.getParentLine()->getLineNum() <= lineNum) { + + // Add arg for parent + ArArgumentBuilder *newArg = new ArArgumentBuilder(512, '\0', false, true); + newArg->addPlain(lineGroup.getParentLine()->getLineText()); + newArg->removeArg(0, true); // To get rid of info name + + newArg->compressQuoted(); + + newInfoList.push_back(newArg); + + IFDEBUG(ArLog::log(ArLog::Normal, + "ArMapChanger::applyInfoChanges() adding %s %s", + infoName, + newArg->getFullString())); + + for (std::vector::iterator cIter = lineGroup.getChildLines()->begin(); + cIter != lineGroup.getChildLines()->end(); + cIter++) { + + lineNum++; + ArMapFileLine &line = *cIter; + ArArgumentBuilder *childArg = new ArArgumentBuilder(512, '\0', false, true); + childArg->addPlain(line.getLineText()); + childArg->removeArg(0, true); // To get rid of info name + + childArg->compressQuoted(); + + newInfoList.push_back(childArg); + + IFDEBUG(ArLog::log(ArLog::Normal, + "ArMapChanger::applyInfoChanges() adding child %s %s", + infoName, + childArg->getFullString())); + + } // end for each child line + + addIter++; + + continue; + + } // end if line added + } // end if + + if (origIter != tempInfoList.end()) { + ArArgumentBuilder *arg = *origIter; + newInfoList.push_back(arg); + origIter++; + } + + if ((addIter == addedLineSet->end()) && + (origIter == tempInfoList.end())) { + isDone = true; + } + + } // end while not done + + myWorkingMap->setInfo(infoName, &newInfoList); + // Since setInfoList makes a copy, delete the allocated args. + ArUtil::deleteSet(newInfoList.begin(), newInfoList.end()); + } + else { // no lines added + + myWorkingMap->setInfo(infoName, &tempInfoList); + // Since setInfoList makes a copy, delete the allocated args. + ArUtil::deleteSet(tempInfoList.begin(), tempInfoList.end()); + + } // end else no lines added + + } // end for each changed info type + + return isSuccess; + +} // end method applyInfoChanges + +// ----------------------------------------------------------------------------- + +// TODO: Not really sure whether we want to accumulate the packet list... might +// make more sense just to send... + +bool ArMapChanger::convertChangeDetailsToPacketList + (ArMapChangeDetails *changeDetails, + std::list *packetListOut, + bool isRelay) +{ + if (packetListOut == NULL) { + ArLog::log(ArLog::Normal, + "ArMapChanger::convertChangeDetailsToPacketList() packet list"); + return false; + } + packetListOut->clear(); + + myChangeDetails = changeDetails; + + bool isSuccess = true; + + ArMapId newMapId; + changeDetails->getNewMapId(&newMapId); + + std::list *scanTypeList = changeDetails->getScanTypes(); + + // TODO: Not entirely sure that we want to do this here, or in the map + // producer... + if (!isRelay && !ArUtil::isStrEmpty(newMapId.getSourceName())) { + ArLog::log(ArLog::Normal, + "ArMapChanger::convertChangeDetailsToPacketList() removing timestamp source = %s", + newMapId.getSourceName()); + // This map was obtained from a remote source... Rip out the timestamp so + // that the originator can set it to the correct value. + newMapId.setTimestamp(-1); + changeDetails->setNewMapId(newMapId); + } // end if remote map + + ArNetPacket *startPacket = new ArNetPacket(); + addHeaderToPacket(START_CHANGES, + NO_CHANGE, // unused + ArMapChangeDetails::ADDITIONS, // unused + NULL, + startPacket); + packetListOut->push_back(startPacket); + + for (int i = 0; + (isSuccess && (i < ArMapChangeDetails::CHANGE_TYPE_COUNT)); + i++) { + + ArMapChangeDetails::MapLineChangeType changeType = + (ArMapChangeDetails::MapLineChangeType) i; + + std::list::iterator iter = scanTypeList->end(); + + for (iter = scanTypeList->begin(); iter != scanTypeList->end(); iter++) { + const char *scanType = (*iter).c_str(); + isSuccess = isSuccess && + addFileLineSetPackets + (SUMMARY_DATA, + changeType, + scanType, + NULL, + changeDetails->getChangedSummaryLines(changeType, scanType), + packetListOut); + } // end for each scan type + + isSuccess = isSuccess && + addFileLineSetPackets + (SUPPLEMENT_DATA, + changeType, + NULL, + NULL, + changeDetails->getChangedSupplementLines(changeType), + packetListOut); + + + //for (int infoType = 0; infoType < myInfoCount; infoType++) { + for (std::list::iterator iIter = myInfoNames.begin(); + iIter != myInfoNames.end(); + iIter++) { + const char *infoName = (*iIter).c_str(); + + isSuccess = isSuccess && + addFileLineSetPackets + (INFO_DATA, + changeType, + NULL, + infoName, + changeDetails->getChangedInfoLines(infoName, changeType), + packetListOut); + } // end for each info type + + isSuccess = isSuccess && + addFileLineSetPackets + (OBJECTS_DATA, + changeType, + NULL, + NULL, + changeDetails->getChangedObjectLines(changeType), + packetListOut); + + for (iter = scanTypeList->begin(); iter != scanTypeList->end(); iter++) { + const char *scanType = (*iter).c_str(); + isSuccess = isSuccess && + addPointsPackets + (changeType, + scanType, + changeDetails->getChangedPoints(changeType, scanType), + packetListOut); + } // end for each scan type + + for (iter = scanTypeList->begin(); iter != scanTypeList->end(); iter++) { + const char *scanType = (*iter).c_str(); + isSuccess = isSuccess && + addLinesPackets + (changeType, + scanType, + changeDetails->getChangedLineSegments(changeType, scanType), + packetListOut); + } // end for each scan type + + } // end for each change type + + ArNetPacket *endPacket = new ArNetPacket(); + addHeaderToPacket(FINISH_CHANGES, + NO_CHANGE, // unused + ArMapChangeDetails::ADDITIONS, // unused + NULL, + endPacket); + packetListOut->push_back(endPacket); + + myChangeDetails = NULL; + + return isSuccess; + +} // end method convertChangeDetailsToPacketList + + + +bool ArMapChanger::addFileLineSetPackets + (MapChangeDataType dataType, + ArMapChangeDetails::MapLineChangeType changeType, + const char *scanType, + const char *extra, + ArMapFileLineSet *fileLineSet, + std::list *packetListOut) +{ + if (packetListOut == NULL) { + return false; + } + if ((fileLineSet == NULL) || (fileLineSet->empty())) { + return true; + } + + // TODO Could probably make this work similar to the addGroup and addFileLine... + // i.e. append to previous packet if there is room. + + ArNetPacket *packet = new ArNetPacket(); + + addHeaderToPacket(CONTINUE_CHANGES, dataType, changeType, scanType, packet); + + // TODO Someday we should create a new packet defn that sends a string instead + // of the info name index... (i.e. Keep this in mind if any other changes to + // the packet are necessary.) + int extraIndex = -1; + + if ((dataType == INFO_DATA) && (!ArUtil::isStrEmpty(extra))) { + + int i = 0; + for (std::list::iterator iter = myInfoNames.begin(); + iter != myInfoNames.end(); + iter++, i++) { + if (strcasecmp(extra, (*iter).c_str()) == 0) { + extraIndex = i; + break; + } + } // end for each info name + } // end if + + packet->byte4ToBuf(extraIndex); + + packet->byte4ToBuf(fileLineSet->size()); + + packetListOut->push_back(packet); + + bool isAddSuccess = true; + + for (ArMapFileLineSet::iterator iter2 = fileLineSet->begin(); + (isAddSuccess && (iter2 != fileLineSet->end())); + iter2++) { + + ArMapFileLineGroup &group = *iter2; + + isAddSuccess = addGroupToPacketList(dataType, + changeType, + scanType, + group, + packetListOut); + + } // end for each group + + return isAddSuccess; + +} // end method addFileLineSetPackets + + +void ArMapChanger::addHeaderToPacket + (MapChangeCommand command, + MapChangeDataType dataType, + ArMapChangeDetails::MapLineChangeType changeType, + const char *scanType, + ArNetPacket *packet) +{ + + if (myChangeDetails == NULL) { + ArLog::log(ArLog::Normal, + "ArMapChanger::addHeaderToPacket() cannot create packet because no change details"); + return; + } + ArLog::log(ArLog::Normal, + "ArMapChanger::addHeaderToPacket() creating packet for data type %i change type %i", + dataType, changeType); + + packet->uByte2ToBuf(command); + + ArMapId origMapId; + ArMapId newMapId; + myChangeDetails->getOrigMapId(&origMapId); + myChangeDetails->getNewMapId(&newMapId); + + bool isSuccess = true; + + isSuccess = ArMapId::toPacket(origMapId, packet) && isSuccess; + isSuccess = ArMapId::toPacket(newMapId, packet) && isSuccess; + + if ((command != CONTINUE_CHANGES)) { + return; + } + + packet->uByteToBuf(dataType); + packet->uByteToBuf(changeType); + if (scanType != NULL) { + packet->strToBuf(scanType); + } + else { + packet->strToBuf(""); + } + +} // end method addHeaderToPacket + + +bool ArMapChanger::addGroupToPacketList(MapChangeDataType dataType, + ArMapChangeDetails::MapLineChangeType changeType, + const char *scanType, + ArMapFileLineGroup &group, + std::list *packetListOut) +{ + int packetPadding = 1000; + + ArNetPacket *packet = packetListOut->back(); + + for (int i = 0; i < 2; i++) { + if (packet->getLength() + + strlen(group.getParentLine()->getLineText()) + 1 + + 4 // line number + + 4 // child count + + packetPadding > packet->getMaxLength()) { + + if (i == 0) { + + packet = new ArNetPacket(); + addHeaderToPacket(CONTINUE_CHANGES, dataType, changeType, scanType, packet); + + packet->byte4ToBuf(-1); // for continuation + packet->byte4ToBuf(-1); // "" + + packetListOut->push_back(packet); + } + else { + // TODO Log error + return false; + } + } + else { + break; + } // end if line is too long for packet + } // end for each try + + packet->byte4ToBuf(group.getChildLines()->size()); + + packet->byte4ToBuf(group.getParentLine()->getLineNum()); + packet->strToBuf(group.getParentLine()->getLineText()); + + bool isAddSuccess = true; + + for (std::vector::iterator iter = group.getChildLines()->begin(); + (isAddSuccess && (iter != group.getChildLines()->end())); + iter++) { + const ArMapFileLine &fileLine = *iter; + + isAddSuccess = addFileLineToPacketList(dataType, + changeType, + scanType, + fileLine, + packetListOut); + + } + + return isAddSuccess; + +} // end method addGroupToPacketList + + +bool ArMapChanger::addFileLineToPacketList(MapChangeDataType dataType, + ArMapChangeDetails::MapLineChangeType changeType, + const char *scanType, + const ArMapFileLine &fileLine, + std::list *packetListOut) +{ + int packetPadding = 1000; + + ArNetPacket *packet = packetListOut->back(); + + for (int i = 0; i < 2; i++) { + if (packet->getLength() + + strlen(fileLine.getLineText()) + 1 + + 4 // line number + + packetPadding > packet->getMaxLength()) { + + if (i == 0) { + + packet = new ArNetPacket(); + addHeaderToPacket(CONTINUE_CHANGES, dataType, changeType, scanType, packet); + packet->byte4ToBuf(-1); // for continuation + packet->byte4ToBuf(-1); // "" + + packetListOut->push_back(packet); + } + else { + + ArLog::log(ArLog::Normal, + "ArMapChanger::addFileLineToPacketList() line #%i is too long to add", + fileLine.getLineNum()); + return false; + } + } // end if line is too long for packet + } // end for each try + + packet->byte4ToBuf(fileLine.getLineNum()); + packet->strToBuf(fileLine.getLineText()); + + return true; + +} // end method addFileLineToPacketList + + +bool ArMapChanger::addPointsPackets + (ArMapChangeDetails::MapLineChangeType changeType, + const char *scanType, + std::vector *pointList, + std::list *packetListOut) +{ + if (packetListOut == NULL) { + return false; + } + if ((pointList == NULL) || (pointList->empty())) { + return true; + } + + // TODO Could probably make this work similar to the addGroup and addFileLine... + // i.e. append to previous packet if there is room. + + ArNetPacket *packet = new ArNetPacket(); + addHeaderToPacket(CONTINUE_CHANGES, POINTS_DATA, changeType, scanType, packet); + packet->byte4ToBuf(pointList->size()); + + packetListOut->push_back(packet); + + int currentCount = 0; + + for (std::vector::iterator iter = pointList->begin(); + iter != pointList->end(); + iter++) { + + if (currentCount >= MAX_POINTS_IN_PACKET) { + + ArNetPacket *packet = new ArNetPacket(); + + addHeaderToPacket(CONTINUE_CHANGES, POINTS_DATA, changeType, scanType, packet); + + packet->byte4ToBuf(-1); // for a continuation... + + packetListOut->push_back(packet); + + currentCount = 0; + } + currentCount++; + /*** + ArLog::log(ArLog::Normal, + "Packed: %li %li", + (long int) (*iter).getX(), + (long int) (*iter).getY()); + ***/ + + packet->byte4ToBuf((long int) (*iter).getX()); + packet->byte4ToBuf((long int) (*iter).getY()); + + } // end for each point + + return true; + +} // end method addPointsPackets + + + +bool ArMapChanger::addLinesPackets + (ArMapChangeDetails::MapLineChangeType changeType, + const char *scanType, + std::vector *lineSegmentList, + std::list *packetListOut) +{ + if (packetListOut == NULL) { + return false; + } + if ((lineSegmentList == NULL) || (lineSegmentList->empty())) { + return true; + } + + // TODO Could probably make this work similar to the addGroup and addFileLine... + // i.e. append to previous packet if there is room. + + ArNetPacket *packet = new ArNetPacket(); + addHeaderToPacket(CONTINUE_CHANGES, LINES_DATA, changeType, scanType, packet); + + packet->byte4ToBuf(lineSegmentList->size()); + + packetListOut->push_back(packet); + + int currentCount = 0; + + for (std::vector::iterator iter = lineSegmentList->begin(); + iter != lineSegmentList->end(); + iter++) { + + if (currentCount >= MAX_LINES_IN_PACKET) { + + ArNetPacket *packet = new ArNetPacket(); + + addHeaderToPacket(CONTINUE_CHANGES, LINES_DATA, changeType, scanType, packet); + packet->byte4ToBuf(-1); // for a continuation... + + packetListOut->push_back(packet); + + currentCount = 0; + } + currentCount++; + + packet->byte4ToBuf((long int) (*iter).getX1()); + packet->byte4ToBuf((long int) (*iter).getY1()); + packet->byte4ToBuf((long int) (*iter).getX2()); + packet->byte4ToBuf((long int) (*iter).getY2()); + + } // end for each point + + return true; + +} // end method addLinesPackets + +// ----------------------------------------------------------------------------- + +bool ArMapChanger::convertPacketListToChangeDetails + (std::list &packetList, + ArMapChangeDetails *changeDetailsOut) +{ + + if (changeDetailsOut == NULL) { + return false; + } + + bool isSuccess = true; + int numPoints = 0; + int numLines = 0; + int numGroups = 0; + int numChildren = 0; + + for (std::list::iterator iter = packetList.begin(); + (isSuccess && iter != packetList.end()); + iter++) { + ArNetPacket *packet = *iter; + if (packet == NULL) { + continue; + } + + MapChangeCommand command = CONTINUE_CHANGES; + ArMapId origMapId; + ArMapId newMapId; + MapChangeDataType dataType = NO_CHANGE; + ArMapChangeDetails::MapLineChangeType changeType =ArMapChangeDetails::ADDITIONS; + std::string scanType; + + bool isSuccess = unpackHeader(packet, + &command, + &origMapId, + &newMapId, + &dataType, + &changeType, + &scanType); + + if (command == START_CHANGES) { + changeDetailsOut->setOrigMapId(origMapId); + changeDetailsOut->setNewMapId(newMapId); + } + + if (command != CONTINUE_CHANGES) { + continue; + } + + switch (dataType) { + + case NO_CHANGE: + break; + + case SUMMARY_DATA: + case INFO_DATA: + case OBJECTS_DATA: + case SUPPLEMENT_DATA: + { + isSuccess = unpackFileLineSet(packet, + dataType, + changeType, + scanType.c_str(), + &numGroups, + &numChildren, + changeDetailsOut); + } + break; + + case POINTS_DATA: + { + isSuccess = unpackPoints(packet, + changeType, + scanType.c_str(), + &numPoints, + changeDetailsOut); + } + break; + case LINES_DATA: + { + isSuccess = unpackLines(packet, + changeType, + scanType.c_str(), + &numLines, + changeDetailsOut); + } + break; + } // end switch dataType + + } // end for each packet + + return isSuccess; + +} // end method convertPacketListToChangeDetails + + +bool ArMapChanger::unpackHeader(ArNetPacket *packet, + MapChangeCommand *commandOut, + ArMapId *origMapIdOut, + ArMapId *newMapIdOut, + MapChangeDataType *dataTypeOut, + ArMapChangeDetails::MapLineChangeType *changeTypeOut, + std::string *scanTypeOut) +{ + if (packet == NULL) { + return false; + } + if ((commandOut == NULL) || (origMapIdOut == NULL)) { + return false; + } + ArTypes::UByte2 commandVal = packet->bufToUByte2(); + + if ((commandVal > LAST_CHANGE_COMMAND)) { + return false; + } + + *commandOut = (MapChangeCommand) commandVal; + + bool isSuccess = true; + + isSuccess = ArMapId::fromPacket(packet, origMapIdOut) && isSuccess; + + if (newMapIdOut == NULL) { + return isSuccess; + } + + isSuccess = ArMapId::fromPacket(packet, newMapIdOut) && isSuccess; + + if ((commandVal != CONTINUE_CHANGES)) { + return isSuccess; + } + + if (dataTypeOut == NULL) { + return isSuccess; + } + + int dataTypeVal = packet->bufToUByte(); + if ((dataTypeVal < 0) || (dataTypeVal > LAST_CHANGE_DATA_TYPE)) { + ArLog::log(ArLog::Normal, + "ArMapChanger::convertPacketListToChangeDetails() data type error (%i)", + dataTypeVal); + return false; + } + *dataTypeOut = (MapChangeDataType) dataTypeVal; + + + if (changeTypeOut == NULL) { + return isSuccess; + } + + int changeTypeVal = packet->bufToUByte(); + if ((changeTypeVal < 0) || (changeTypeVal > ArMapChangeDetails::LAST_CHANGE_TYPE)) { + ArLog::log(ArLog::Normal, + "ArMapChanger::convertPacketListToChangeDetails() change type error (%i)", + changeTypeVal); + return false; + } + + *changeTypeOut = (ArMapChangeDetails::MapLineChangeType) changeTypeVal; + + if (scanTypeOut == NULL) { + return isSuccess; + } + + char buf[512]; + buf[0] = '\0'; + packet->bufToStr(buf, sizeof(buf)); + *scanTypeOut = buf; + + return isSuccess; + +} // end method unpackHeader + +bool ArMapChanger::unpackFileLineSet(ArNetPacket *packet, + MapChangeDataType dataType, + ArMapChangeDetails::MapLineChangeType changeType, + const char *scanType, + int *numGroups, + int *numChildren, + ArMapChangeDetails *changeDetails) +{ + + if ((packet == NULL) || (numGroups == NULL) || + (numChildren == NULL) || (changeDetails == NULL)) { + ArLog::log(ArLog::Normal, + "ArMapChanger::unpackFileLineSet() param error"); + return false; + } + + + // TODO Get info type... + int extra = packet->bufToByte4(); + + + int tempGroups = packet->bufToByte4(); + if (tempGroups >= 0) { + IFDEBUG(ArLog::log(ArLog::Normal, + "ArMapChanger::unpackFileLineSet() setting numGroups to %i", tempGroups)); + *numGroups = tempGroups; + } + else { + IFDEBUG(ArLog::log(ArLog::Normal, + "ArMapChanger::unpackFileLineSet() continuing from previous (numGroups = %i)", + *numGroups)); + + } // continuing from previous... + + if (*numGroups <= 0) { + ArLog::log(ArLog::Normal, + "ArMapChanger::unpackFileLineSet() invalid group count %i", + *numGroups); + return false; + } + + + ArMapFileLineSet *fileLineSet = NULL; + + switch (dataType) { + case SUMMARY_DATA: + fileLineSet = changeDetails->getChangedSummaryLines(changeType, scanType); + break; + case INFO_DATA: + { + const char *infoName = NULL; + if ((extra >= 0) && (extra < (int) myInfoNames.size())) { + int i = 0; + for (std::list::iterator iter = myInfoNames.begin(); + iter != myInfoNames.end(); + iter++, i++) { + if (i == extra) { + infoName = (*iter).c_str(); + break; + } + } // end for + } // end if + if (infoName != NULL) { + fileLineSet = changeDetails->getChangedInfoLines(infoName, changeType); + } + } + break; + case OBJECTS_DATA: + fileLineSet = changeDetails->getChangedObjectLines(changeType); + break; + default: + ArLog::log(ArLog::Normal, + "ArMapChanger::unpackFileLineSet() unexpected data type %i", + dataType); + return false; + break; + } + + if (fileLineSet == NULL) { + ArLog::log(ArLog::Normal, + "ArMapChanger::unpackFileLineSet() null file line set for %i", + dataType); + return false; + } + IFDEBUG(ArLog::log(ArLog::Normal, + "ArMapChanger::unpackFileLineSet() unpacking packet for data type %i", + dataType)); + + char buf[10000]; + + while ((*numGroups > 0) && + (packet->getReadLength() < packet->getLength()) && + (packet->isValid())) { + + IFDEBUG(ArLog::log(ArLog::Normal, + "ArMapChanger::unpackFileLineSet() begin loop, numGroups = %i", + *numGroups)); + + int tempChildren = packet->bufToByte4(); + if (tempChildren >= 0) { + *numChildren = tempChildren; + IFDEBUG(ArLog::log(ArLog::Normal, + "ArMapChanger::unpackFileLineSet() setting numChildren to %i", tempChildren)); + } + else { + IFDEBUG(ArLog::log(ArLog::Normal, + "ArMapChanger::unpackFileLineSet() continuing previous children %i", *numChildren)); + } // continuing from previous... + + // Note that it's alright to have 0 children + if (*numChildren < 0) { + ArLog::log(ArLog::Normal, + "ArMapChanger::unpackFileLineSet() invalid child count %i", + *numChildren); + return false; + } + + if (tempChildren >= 0) { + + // this is the parent + int lineNum = packet->bufToByte4(); + packet->bufToStr(buf, sizeof(buf)); + + if (!packet->isValid()) { + ArLog::log(ArLog::Normal, + "ArMapChanger::unpackFileLineSet() packet not valid"); + return false; + } + + IFDEBUG(ArLog::log(ArLog::Normal, + "ArMapChanger::unpackFileLineSet() creating new group: #%i %s", + lineNum, buf)); + + ArMapFileLineGroup newGroup(ArMapFileLine(lineNum, buf)); + fileLineSet->push_back(newGroup); + + + } + if (*numChildren > 0) { + + if (fileLineSet->empty()) { + ArLog::log(ArLog::Normal, + "ArMapChanger::unpackFileLineSet() no parent for children"); + return false; + } + ArMapFileLineGroup &group = fileLineSet->back(); + + while ((*numChildren > 0) && + (packet->getReadLength() < packet->getLength()) && + (packet->isValid())) { + + int childLineNum = packet->bufToByte4(); + packet->bufToStr(buf, sizeof(buf)); + + if (!packet->isValid()) { + ArLog::log(ArLog::Normal, + "ArMapChanger::unpackFileLineSet() invalid packet in child read"); + return false; + } + + IFDEBUG(ArLog::log(ArLog::Normal, + "ArMapChanger::unpackFileLineSet() creating new child (of #%i): #%i %s", + group.getParentLine()->getLineNum(), + childLineNum, + buf)); + group.getChildLines()->push_back(ArMapFileLine(childLineNum, buf)); + + *numChildren = *numChildren - 1; + + } // end while more children to read + + IFDEBUG( + if (*numChildren <= 0) { + ArLog::log(ArLog::Normal, + "ArMapChanger::unpackFileLineSet() exited inner loop because numChildren = %i", + *numChildren); + + } + else if (packet->getReadLength() >= packet->getLength()) { + ArLog::log(ArLog::Normal, + "ArMapChanger::unpackFileLineSet() exited inner loop because readLength (%i) >= length (%i)", + packet->getReadLength(), packet->getLength()); + + } + else if (!packet->isValid()) { + ArLog::log(ArLog::Normal, + "ArMapChanger::unpackFileLineSet() exited inner loop because packet not valid"); + + } + ); + + + + } // end if there were children to read + + if (*numChildren == 0) { + IFDEBUG(ArLog::log(ArLog::Normal, + "ArMapChanger::unpackFileLineSet() done reading group, old num = %i", + *numGroups)); + + + *numGroups = *numGroups - 1; + + IFDEBUG(ArLog::log(ArLog::Normal, + "ArMapChanger::unpackFileLineSet() done reading group, new num = %i", + *numGroups)); + } + + } // end while more to read from packet + + IFDEBUG( + if (*numGroups <= 0) { + ArLog::log(ArLog::Normal, + "ArMapChanger::unpackFileLineSet() exited loop because numGroups = %i", + *numGroups); + + } + else if (packet->getReadLength() >= packet->getLength()) { + ArLog::log(ArLog::Normal, + "ArMapChanger::unpackFileLineSet() exited loop because readLength (%i) >= length (%i)", + packet->getReadLength(), packet->getLength()); + + } + else if (!packet->isValid()) { + ArLog::log(ArLog::Normal, + "ArMapChanger::unpackFileLineSet() exited loop because packet not valid"); + + } + ); + + return true; + +} // end method unpackFileLineSet + + +bool ArMapChanger::unpackPoints(ArNetPacket *packet, + ArMapChangeDetails::MapLineChangeType changeType, + const char *scanType, + int *numPoints, + ArMapChangeDetails *changeDetails) +{ + if ((packet == NULL) || (numPoints == NULL) || (changeDetails == NULL)) { + return false; + } + + int tempPoints = packet->bufToByte4(); + if (tempPoints >= 0) { + *numPoints = tempPoints; + ArLog::log(ArLog::Normal, + "Set numPoints = %i", tempPoints); + } + else {} // continuing from previous... + + if (*numPoints <= 0) { + return false; + } + + std::vector *pointList = changeDetails->getChangedPoints(changeType, scanType); + + for (int i = 0; i < MAX_POINTS_IN_PACKET; i++) { + + long int x = packet->bufToByte4(); + long int y = packet->bufToByte4(); + + ArPose p(x, y); + pointList->push_back(p); + + /*** + ArLog::log(ArLog::Normal, + "Unpacked: %li %li", + (long int) p.getX(), + (long int) p.getY()); + ***/ + + *numPoints = *numPoints - 1; + if (*numPoints == 0) { + // TODO: Make sure packet is empty? + return true; + } + } // end for each point in packet + + // TODO: Make sure packet is empty? + + return true; + +} // end method unpackPoints + +bool ArMapChanger::unpackLines(ArNetPacket *packet, + ArMapChangeDetails::MapLineChangeType changeType, + const char *scanType, + int *numLines, + ArMapChangeDetails *changeDetails) +{ + if ((packet == NULL) || (numLines == NULL) || (changeDetails == NULL)) { + return false; + } + + int tempLines = packet->bufToByte4(); + if (tempLines >= 0) { + *numLines = tempLines; + } + else {} // continuing from previous... + + if (*numLines <= 0) { + return false; + } + + std::vector *lineSegmentList = + changeDetails->getChangedLineSegments(changeType, scanType); + + for (int i = 0; i < MAX_LINES_IN_PACKET; i++) { + + long int x1 = packet->bufToByte4(); + long int y1 = packet->bufToByte4(); + long int x2 = packet->bufToByte4(); + long int y2 = packet->bufToByte4(); + + lineSegmentList->push_back(ArLineSegment(x1, y1, x2, y2)); + *numLines = *numLines - 1; + if (*numLines == 0) { + // TODO: Make sure packet is empty? + return true; + } + } // end for each point in packet + + // TODO: Make sure packet is empty? + + return true; + +} // end method unpackLines + + +AREXPORT bool ArMapChanger::addChangeCB(ArFunctor2 *> *functor) +{ + if (functor == NULL) { + return false; + } + myChangeCBList.push_back(functor); + return true; +} + +AREXPORT bool ArMapChanger::remChangeCB + (ArFunctor2 *> *functor) +{ + if (functor == NULL) { + return false; + } + // TODO Improve return val + myChangeCBList.remove(functor); + return true; + +} + +AREXPORT bool ArMapChanger::addRobotChangeReplyCB + (ArFunctor2 *functor) +{ + if (functor == NULL) { + return false; + } + myRobotChangeReplyCBList.push_back(functor); + return true; + +} // end method addRobotChangeReplyCB + + +AREXPORT bool ArMapChanger::remRobotChangeReplyCB + (ArFunctor2 *functor) +{ + if (functor == NULL) { + return false; + } + // TODO Improve return val + myRobotChangeReplyCBList.remove(functor); + return true; + +} // end method remRobotChangeReplyCB + +// ----------------------------------------------------------------------------- + +ArMapChanger::ClientChangeInfo::ClientChangeInfo(ArServerClient *client) : + myClient(client), + myForwarder(NULL), + myStartTime(), + myLastActivityTime(), + myPacketList() +{ +} + +ArMapChanger::ClientChangeInfo::ClientChangeInfo(ArCentralForwarder *forwarder) : + myClient(NULL), + myForwarder(forwarder), + myStartTime(), + myLastActivityTime(), + myPacketList() +{ +} + + +ArMapChanger::ClientChangeInfo::~ClientChangeInfo() +{ + ArUtil::deleteSet(myPacketList.begin(), myPacketList.end()); + myPacketList.clear(); +} + +void ArMapChanger::ClientChangeInfo::addPacket(ArNetPacket *packet) +{ + if (packet == NULL) { + return; + } + ArNetPacket *packetCopy = new ArNetPacket(); + packetCopy->duplicatePacket(packet); + packetCopy->resetRead(); + + myPacketList.push_back(packetCopy); + +} // end method addPacket + + +AREXPORT void ArMapChanger::addPreWriteFileCB(ArFunctor *functor, + ArListPos::Pos position) +{ + addToCallbackList(functor, position, &myPreWriteCBList); + +} // end method addPreWriteFileCB + +AREXPORT void ArMapChanger::remPreWriteFileCB(ArFunctor *functor) +{ + remFromCallbackList(functor, &myPreWriteCBList); + +} // end method remPreWriteFileCB + +AREXPORT void ArMapChanger::addPostWriteFileCB(ArFunctor *functor, + ArListPos::Pos position) +{ + addToCallbackList(functor, position, &myPostWriteCBList); + +} // end method addPostWriteFileCB + +AREXPORT void ArMapChanger::remPostWriteFileCB(ArFunctor *functor) +{ + remFromCallbackList(functor, &myPostWriteCBList); + +} // end method remPostWriteFileCB + + +AREXPORT void ArMapChanger::addToCallbackList(ArFunctor *functor, + ArListPos::Pos position, + std::list *cbList) +{ + if (functor == NULL) { + ArLog::log(ArLog::Terse, + "ArMapChanger::addToCallbackList cannot add null functor"); + return; + } + if (cbList == NULL) { + ArLog::log(ArLog::Terse, + "ArMapChanger::addToCallbackList cannot add functor to null list"); + return; + } + + switch (position) { + case ArListPos::FIRST: + cbList->push_front(functor); + break; + case ArListPos::LAST: + cbList->push_back(functor); + break; + default: + ArLog::log(ArLog::Terse, + "ArMapChanger::addToCallbackList invalid position (%i)", + position); + } // end switch +} // end method addToCallbackList + +AREXPORT void ArMapChanger::remFromCallbackList(ArFunctor *functor, + std::list *cbList) +{ + if (functor == NULL) { + ArLog::log(ArLog::Terse, + "ArMapChanger::remFromCallbackList cannot remove null functor"); + return; + } + if (cbList == NULL) { + ArLog::log(ArLog::Terse, + "ArMapChanger::addToCallbackList cannot remove functor to null list"); + return; + } + cbList->remove(functor); + +} // end method remFromCallbackList + + +AREXPORT void ArMapChanger::handleRobotChangeReplyPacket(ArServerClient *client, + ArNetPacket *packet) +{ + IFDEBUG(ArLog::log(ArLog::Normal, + "ArMapChanger::handleRobotChangeReplyPacket()")); + + myInterleaveMutex.lock(); + if (!myIsWaitingForReturn) + { + myInterleaveMutex.unlock(); + return; + } + + char robotName[512]; + packet->bufToStr(robotName, sizeof(robotName)); + + int ret = packet->bufToUByte2(); + + // packet->bufToStr(fileName, sizeof(fileName)); + // if (myInterleaved && ret == 10) + if (ret == CHANGE_SUCCESS) + { + myReadyForNextPacket = true; + myIsWaitingForReturn = false; + ArLog::log(ArLog::Normal, + "ArMapChanger::handleRobotChangeReplyPacket() set myReadyForNextPacket = true && myIsWaitingForReturn = false"); + } + else + { + myIsWaitingForReturn = false; + ArLog::log(ArLog::Normal, + "ArMapChanger::handleRobotChangeReplyPacket() set myIsWaitingForReturn = false"); + } + + myInterleaveMutex.unlock(); + + for (std::list< ArFunctor2 *>::iterator cbIter = + myRobotChangeReplyCBList.begin(); + cbIter != myRobotChangeReplyCBList.end(); + cbIter++) { + + packet->resetRead(); + + ArFunctor2 *functor = *cbIter; + + if (functor != NULL) { + functor->invoke(client, packet); + } + } +} // end method handleRobotChangeReplyPacket + + diff --git a/Legacy/Aria/ArNetworking/src/ArNetPacket.cpp b/Legacy/Aria/ArNetworking/src/ArNetPacket.cpp new file mode 100644 index 0000000..2e4d723 --- /dev/null +++ b/Legacy/Aria/ArNetworking/src/ArNetPacket.cpp @@ -0,0 +1,212 @@ +#include "Aria.h" +#include "ArExport.h" +#include "ArNetPacket.h" + +AREXPORT ArNetPacket::ArNetPacket(ArTypes::UByte2 bufferSize) : + ArBasePacket(bufferSize, ArNetPacket::HEADER_LENGTH, NULL, + ArNetPacket::FOOTER_LENGTH), + myPacketSource(TCP), + myAddedFooter(false), + myArbitraryString(), + myCommand(0) +{ + insertHeader(); +} + +AREXPORT ArNetPacket::ArNetPacket(const ArNetPacket &other) : + ArBasePacket(other), + myPacketSource(other.myPacketSource), + myAddedFooter(other.myAddedFooter), + myArbitraryString(other.myArbitraryString), + myCommand(other.myCommand) +{ +} + +AREXPORT ArNetPacket &ArNetPacket::operator=(const ArNetPacket &other) +{ + if (this != &other) { + ArBasePacket::operator=(other); + myPacketSource = other.myPacketSource; + myAddedFooter = other.myAddedFooter; + myArbitraryString = other.myArbitraryString; + myCommand = other.myCommand; + } + return *this; +} + + +AREXPORT ArNetPacket::~ArNetPacket() +{ + +} + +AREXPORT void ArNetPacket::doubleToBuf(double val) +{ + char buf[256]; + if (val == -HUGE_VAL) + sprintf(buf, "-INF"); + else if (val == HUGE_VAL) + sprintf(buf, "INF"); + else + sprintf(buf, "%g", val); + strToBuf(buf); +} + +AREXPORT double ArNetPacket::bufToDouble(void) +{ + char buf[256]; + char *endPtr; + double ret; + + bufToStr(buf, sizeof(buf)); + if (strncmp(buf, "-INF", sizeof(buf)) == 0) + { + ret = -HUGE_VAL; + return ret; + } + else if (strncmp(buf, "INF", sizeof(buf)) == 0) + { + ret = HUGE_VAL; + return ret; + } + else + { + ret = strtod(buf, &endPtr); + if (endPtr[0] == '\0' && endPtr != buf) + return ret; + else + return 0; + } +} + +AREXPORT void ArNetPacket::empty(void) +{ + myCommand = 0; + myLength = myHeaderLength; + myAddedFooter = false; + resetValid(); +} + + +void ArNetPacket::insertHeader() +{ + int length = myLength; + myLength = 0; + uByteToBuf(0xF); // 1 + uByteToBuf(0xC); // 2 + + if (myAddedFooter) + uByte2ToBuf(length); // 3 & 4 + else + uByte2ToBuf(length+2); // 3 & 4 + + uByte2ToBuf(myCommand); // 5 & 6 + + if (myAddedFooter) + myLength = length - 2; + else + myLength = length; + +} // end method insertHeader + + +AREXPORT void ArNetPacket::finalizePacket(void) +{ + + insertHeader(); + + int chkSum = calcCheckSum(); + byteToBuf((chkSum >> 8) & 0xff ); + byteToBuf(chkSum & 0xff ); + myAddedFooter = true; + //log(); + //printf("%d %d %d\n", myLength ,myCommand, chkSum); +} + +AREXPORT void ArNetPacket::resetRead(void) +{ + myReadLength = 4; + myCommand = bufToUByte2(); + myReadLength = myHeaderLength; + resetValid(); + +} + +AREXPORT void ArNetPacket::setCommand(ArTypes::UByte2 command) +{ + myCommand = command; +} + +AREXPORT ArTypes::UByte2 ArNetPacket::getCommand(void) +{ + return myCommand; +} + +AREXPORT void ArNetPacket::duplicatePacket(ArNetPacket *packet) +{ + myLength = packet->myLength; + + // if (myMaxLength < myLength) + // setMaxLength(packet->myLength); + if (myMaxLength < myLength + packet->myFooterLength) + setMaxLength(packet->myLength + packet->myFooterLength); + + myReadLength = packet->myReadLength; + myHeaderLength = packet->myHeaderLength; + myFooterLength = packet->myFooterLength; + myCommand = packet->myCommand; + myAddedFooter = packet->myAddedFooter; + memcpy(myBuf, packet->getBuf(), packet->myLength + packet->myFooterLength); + myArbitraryString = packet->myArbitraryString; +} + +AREXPORT ArTypes::Byte2 ArNetPacket::calcCheckSum(void) +{ + int c = 0; + + //printf("%d\n", myLength); + //log(); + int i = 3; + int n = myLength - 2; + + while (n > 3) { + + //printf("n %d i %d c %d c1 %d c2 %d\n", n, i, c, myBuf[i], myBuf[i+1]); + c += ((unsigned char)myBuf[i]<<8) | (unsigned char)myBuf[i+1]; + c = c & 0xffff; + n -= 2; + i += 2; + } + //printf("aft n %d i %d c %d\n", n, i, c); + if (n > 0) + c = c ^ (int)((unsigned char) myBuf[i]); + //printf("%d\n", c); + return c; +} + +AREXPORT bool ArNetPacket::verifyCheckSum(void) +{ + ArTypes::Byte2 chksum; + ArTypes::Byte2 calcedChksum; + unsigned char c1, c2; + int length; + + if (myLength - 2 < myHeaderLength) + return false; + + c2 = myBuf[myLength-2]; + c1 = myBuf[myLength-1]; + chksum = (c1 & 0xff) | (c2 << 8); + length = myLength; + myLength = myLength - 2; + calcedChksum = calcCheckSum(); + myLength = length; + + //printf("%d %d\n", chksum, calcedChksum); + if (chksum == calcedChksum) { + return true; + } else { + return false; + } + +} diff --git a/Legacy/Aria/ArNetworking/src/ArNetPacketReceiverTcp.cpp b/Legacy/Aria/ArNetworking/src/ArNetPacketReceiverTcp.cpp new file mode 100644 index 0000000..622626d --- /dev/null +++ b/Legacy/Aria/ArNetworking/src/ArNetPacketReceiverTcp.cpp @@ -0,0 +1,328 @@ +#include "Aria.h" +#include "ArExport.h" +#include "ArNetPacketReceiverTcp.h" +#ifndef WIN32 +#include "errno.h" +#endif + +AREXPORT ArNetPacketReceiverTcp::ArNetPacketReceiverTcp() : + + myState(STATE_SYNC1), + myProcessPacketCB(NULL), + myQuiet(false), + mySocket(NULL), + myLastPacket(), + myPacket(), + + myReadBuff(), + myReadCount(0), + myReadLength(0), + myReadCommand(0), + mySync1(0xF), + mySync2(0xC), + myLoggingPrefix("") +{ + memset(myReadBuff, 0, TOTAL_PACKET_LENGTH); +} + +AREXPORT ArNetPacketReceiverTcp::~ArNetPacketReceiverTcp() +{ + +} + +/** + Sets the socket that this receiver will use, note that it does not + transfer ownership of the socket. + + @param socket the socket to use for receiving data +**/ +AREXPORT void ArNetPacketReceiverTcp::setSocket(ArSocket *socket) +{ + mySocket = socket; +} + +AREXPORT void ArNetPacketReceiverTcp::setLoggingPrefix( + const char *loggingPrefix) +{ + if (loggingPrefix != NULL && loggingPrefix[0] != '\0') + myLoggingPrefix = loggingPrefix; + else + myLoggingPrefix = ""; +} + +/** + Gets the socket that the receiver is using, note that it does not + have ownership of this socket and that whatever created it should. +**/ +AREXPORT ArSocket *ArNetPacketReceiverTcp::getSocket(void) +{ + return mySocket; +} + +/** + This reads in the available data in the TCP port so that packets + can be fetched with getPacket. If an error occurs that is + unrecoverable false will be returned which means that the socket + owner who is calling this should close the socket and clean up. + + @return false on an error that should cause the socket to be closed, + true with no errors +**/ +AREXPORT bool ArNetPacketReceiverTcp::readData(void) +{ + Ret ret; + + while (1) + { + ret = readPacket(100); + if (ret == RET_TIMED_OUT) + { + // commenting this out since it can happen really often + // sometimes and there's an actual timeout that causes the + // connect to get dropped so the informational printf isn't + // needed + //if (!myQuiet) + //ArLog::log(ArLog::Normal, "%sReadTcp timed out", + //myLoggingPrefix.c_str()); + return true; + } + else if (ret == RET_CONN_CLOSED) + { + if (!myQuiet) + ArLog::log(ArLog::Terse, "%sConnection to %s closed", + myLoggingPrefix.c_str(), mySocket->getIPString()); + return false; + } + else if (ret == RET_CONN_ERROR) + { + if (!myQuiet) + ArLog::log(ArLog::Terse, + "%sConnection to %s had an error and is being closed", + myLoggingPrefix.c_str(), mySocket->getIPString()); + return false; + } + else if (ret == RET_FAILED_READ) + { + // this now just returns true since the previous checks for if + // the failed read was an error or not are handled by readpacket + // now + return true; + } + else if (ret == RET_BAD_PACKET) + { + // well... there was a bad checksum, keep going + } + else if (ret == RET_GOT_PACKET) + { + if (myProcessPacketCB != NULL) + { + //printf("Got in a packet of %d\n", myPacket.getCommand()); + myPacket.setPacketSource(ArNetPacket::TCP); + myProcessPacketCB->invoke(&myPacket); + } + } + else + { + if (!myQuiet) + ArLog::log(ArLog::Terse, "%sArNetPacketReceiverTcp: bad Ret value %d", myLoggingPrefix.c_str(), ret); + return false; + } + } +} + +AREXPORT ArNetPacketReceiverTcp::Ret ArNetPacketReceiverTcp::readPacket(int msWait) +{ + long timeToRunFor = -1; + int numRead = 0; + bool printing = true; + int ret = 0; + unsigned char c = 0; + + ArTime timeDone; + timeDone.setToNow(); + if (!timeDone.addMSec(msWait)) { + ArLog::log(ArLog::Normal, + "ArNetPacketReceiverTcp::readPacket() error adding msecs (%i)", + msWait); + } + + //printf("Read packet!\n"); + do + { + timeToRunFor = timeDone.mSecTo(); + if (timeToRunFor < 0) + timeToRunFor = 0; + + if (myState != STATE_ACQUIRE_DATA) + { + c = 0; + if ((ret = mySocket->read((char *)&c, 1, 0/*timeToRunFor*/)) == -1) + { + if (!mySocket->getBadRead() && myState == STATE_SYNC1) + { + return RET_FAILED_READ; + } + else + { + // if the read is fine, just return timed out + if (!mySocket->getBadRead()) + return RET_TIMED_OUT; + // otherwise return the connection is closed (since that's + // some -1 error other than to try again, meaning a socket + // error of some kind) + else + return RET_CONN_ERROR; + } + } + else if (ret == 0) + { + return RET_CONN_CLOSED; + } + } + + /* + if (myState != STATE_ACQUIRE_DATA) + { + printf("%d", myState); + printf(" %d\n", c); + } + */ + //else + //{ + //printf("\n"); + //} + switch (myState) { + case STATE_SYNC1: + if (c == mySync1) // move on, resetting packet + { + myState = STATE_SYNC2; + myPacket.empty(); + myPacket.setLength(0); + myPacket.uByteToBuf(c); + } + else + { + if (printing) + ArLog::log(ArLog::Verbose, "%sBad char in sync1 %d", myLoggingPrefix.c_str(), c); + return RET_BAD_PACKET; + } + break; + case STATE_SYNC2: + if (c == mySync2) // move on, adding this byte + { + myState = STATE_LENGTH1; + myPacket.uByteToBuf(c); + } + else // go back to beginning, packet hosed + { + if (printing) + ArLog::log(ArLog::Verbose, "%sBad char in sync2 %d, returning to sync1", myLoggingPrefix.c_str(), c); + myState = STATE_SYNC1; + return RET_BAD_PACKET; + } + break; + case STATE_LENGTH1: + myState = STATE_LENGTH2; + myReadLength = ((unsigned int)c & 0xff); + myPacket.uByteToBuf(c); + break; + case STATE_LENGTH2: + myState = STATE_ACQUIRE_DATA; + myReadLength += ((unsigned int)c & 0xff) << 8; + myPacket.uByteToBuf(c); + myReadCount = 0; + break; + case STATE_ACQUIRE_DATA: + if (myReadLength > ArNetPacket::MAX_LENGTH || + myReadLength < myPacket.getHeaderLength() + myPacket.getFooterLength()) + { + if (!myQuiet) + ArLog::log(ArLog::Normal, + "%sArNetPacketReceiverTcp::readPacket: bad packet length, it is %d which is more than max length of %d bytes or less than the minimum %d", + myLoggingPrefix.c_str(), myReadLength, + ArNetPacket::MAX_LENGTH, + myPacket.getHeaderLength() + myPacket.getFooterLength()); + myState = STATE_SYNC1; + return RET_BAD_PACKET; + } + + // here we read until we get as much as we want, OR until + // we go 100 ms without data... its arbitrary but it doesn't happen often + // and it'll mean a bad packet anyways + if (myReadCount < myReadLength - 4) + { + numRead = mySocket->read(myReadBuff + myReadCount, + myReadLength - myReadCount - 4); + //printf("numRead %d myReadLength %d\n", numRead, myReadLength); + // trap if it wasn't data + if (numRead == 0) + return RET_CONN_CLOSED; + else if (numRead < 0) + return RET_FAILED_READ; + // if it was data add it to our number read + myReadCount += numRead; + } + if (myReadCount > myReadLength - 4) + { + if (!myQuiet) + ArLog::log(ArLog::Terse, + "%sRead is greater than it should be at %d > %d", + myLoggingPrefix.c_str(), myReadCount, myReadLength - 4); + } + if (myReadCount == myReadLength - 4) + { + myPacket.dataToBuf(myReadBuff, myReadCount); + + if (myPacket.verifyCheckSum()) + { + myPacket.resetRead(); + // take off the footer from the packets length Variable + /* put this in if you want to see the packets received + //printf("Input "); + myPacket.log(); + */ + // you can also do this next line if you only care about type + //printf("Input %x\n", myPacket.getCommand()); + //myPacket.log(); + myState = STATE_SYNC1; + return RET_GOT_PACKET; + } + else + { + myPacket.resetRead(); + //if (!myQuiet) + ArLog::log(ArLog::Normal, + "%sArNetPacketReceiverTcp::receivePacket: bad packet, bad checksum on packet %d", myLoggingPrefix.c_str(), myPacket.getCommand()); + myState = STATE_SYNC1; + return RET_BAD_PACKET; + } + } + break; + default: + break; + } + } while (timeDone.mSecTo() >= 0 || myState != STATE_SYNC1); + + return RET_TIMED_OUT; + +} + + +/** + @param functor the callback to use when a packet needs to be processed +**/ +AREXPORT void ArNetPacketReceiverTcp::setProcessPacketCB( + ArFunctor1 *functor) +{ + myProcessPacketCB = functor; +} + +/** + @return the callback used when a packet needs to be processed +**/ +AREXPORT ArFunctor1 *ArNetPacketReceiverTcp::getProcessPacketCB(void) +{ + return myProcessPacketCB; +} + + diff --git a/Legacy/Aria/ArNetworking/src/ArNetPacketReceiverUdp.cpp b/Legacy/Aria/ArNetworking/src/ArNetPacketReceiverUdp.cpp new file mode 100644 index 0000000..cf23063 --- /dev/null +++ b/Legacy/Aria/ArNetworking/src/ArNetPacketReceiverUdp.cpp @@ -0,0 +1,141 @@ +#include "Aria.h" +#include "ArExport.h" +#include "ArNetPacketReceiverUdp.h" +#ifndef WIN32 +#include +#endif + +AREXPORT ArNetPacketReceiverUdp::ArNetPacketReceiverUdp() : + myProcessPacketCB(NULL), + mySocket(NULL), + myLastPacket(), + myPacket(), + myBuff() +{ + memset(myBuff, 0, ArNetPacket::MAX_LENGTH+20); + + // one little odd note, this calls setBuf on the packet so that its + // using our own buffer and not its own... this is the only place we + // don't want it to own the buffer + myPacket.setBuf(myBuff, sizeof(myBuff)); +} + +AREXPORT ArNetPacketReceiverUdp::~ArNetPacketReceiverUdp() +{ + +} + +/** + Sets the socket that this receiver will use, note that it does not + transfer ownership of the socket. + + @param socket the socket to use for receiving data +**/ +AREXPORT void ArNetPacketReceiverUdp::setSocket(ArSocket *socket) +{ + mySocket = socket; +} + +/** + Gets the socket that the receiver is using, note that it does not + have ownership of this socket and that whatever created it should. +**/ +AREXPORT ArSocket *ArNetPacketReceiverUdp::getSocket(void) +{ + return mySocket; +} + + +/** + @param functor the callback to use when a packet needs to be processed +**/ +AREXPORT void ArNetPacketReceiverUdp::setProcessPacketCB( + ArFunctor2 *functor) +{ + myProcessPacketCB = functor; +} + +/** + @return the callback used when a packet needs to be processed +**/ +AREXPORT ArFunctor2 *ArNetPacketReceiverUdp::getProcessPacketCB(void) +{ + return myProcessPacketCB; +} + +AREXPORT bool ArNetPacketReceiverUdp::readData(void) +{ + int ret; + int packetLength; + struct sockaddr_in sin; + + if (mySocket == NULL) + { + ArLog::log(ArLog::Verbose, "NULL Udp Socket"); + return false; + } + // while we can read a packet, do it + while ((ret = mySocket->recvFrom(myBuff, sizeof(myBuff), &sin)) > 0) + { + packetLength = (myBuff[3] << 8) | myBuff[2] & 0xff; + if (ret != packetLength) + fprintf(stderr, "packet length %d not equal to udp packet length %d", + packetLength, ret); + myPacket.setLength(packetLength); + myPacket.setBuf(myBuff, sizeof(myBuff)); + if (myPacket.verifyCheckSum()) + { + myPacket.resetRead(); + /* put this in if you want to see the packets received + //printf("Input "); + myPacket.log(); + */ + // you can also do this next line if you only care about type + //printf("Input %x\n", myPacket.getCommand()); + //myPacket.log(); + myPacket.resetRead(); + if (myProcessPacketCB != NULL) + { + myPacket.setPacketSource(ArNetPacket::UDP); + myProcessPacketCB->invoke(&myPacket, &sin); + } + } + else + { + myPacket.resetRead(); + ArLog::log(ArLog::Normal, + "ArNetPacketReceiverUdp::receivePacket: bad packet, bad checksum on packet %d", myPacket.getCommand()); + } + + } + + + + // see why we ran out of packets, if its bad return false so that it + // is known the socket is bad now + if (ret < 0) + { +#ifdef WIN32 + if (WSAGetLastError() == WSAEWOULDBLOCK || WSAGetLastError() == WSAECONNRESET) + return true; + else + ArLog::log(ArLog::Terse, "Failed on read UDP, error %d", WSAGetLastError()); +#endif +#ifndef WIN32 + if (errno == EAGAIN) + return true; + else + ArLog::log(ArLog::Terse, "Failed on read UDP, error %d", errno); +#endif + ArLog::log(ArLog::Terse, "Failed on the udp read"); + return false; + } + else if (ret == 0) + { + printf("Read 0 byte UDP packet\n"); + return true; + } + + return true; + +} diff --git a/Legacy/Aria/ArNetworking/src/ArNetPacketSenderTcp.cpp b/Legacy/Aria/ArNetworking/src/ArNetPacketSenderTcp.cpp new file mode 100644 index 0000000..5479d5d --- /dev/null +++ b/Legacy/Aria/ArNetworking/src/ArNetPacketSenderTcp.cpp @@ -0,0 +1,251 @@ +#include "Aria.h" +#include "ArExport.h" +#include "ArNetPacketSenderTcp.h" + +AREXPORT ArNetPacketSenderTcp::ArNetPacketSenderTcp() : + mySocket(NULL), + myPacketList(), + myPacket(NULL), + myAlreadySent(false), + myBuf(NULL), + myLength(0) +{ + myDataMutex.setLogName("ArNetPacketSenderTcp::myDataMutex"); + setDebugLogging(false); + myBackupTimeout = -1; + myLastGoodSend.setToNow(); +} + +AREXPORT ArNetPacketSenderTcp::~ArNetPacketSenderTcp() +{ + ArNetPacket *packet; + int i = 0; + long bytes = 0; + while (myPacketList.begin() != myPacketList.end()) + { + i++; + packet = myPacketList.front(); + bytes += packet->getLength(); + myPacketList.pop_front(); + delete packet; + } + if (i > 0) + ArLog::log(ArLog::Normal, "Deleted %d packets of %d bytes", i, bytes); +} + +/** + Sets the socket that this receiver will use, note that it does not + transfer ownership of the socket. + + @param socket the socket to use for receiving data +**/ +AREXPORT void ArNetPacketSenderTcp::setSocket(ArSocket *socket) +{ + myDataMutex.lock(); + mySocket = socket; + myDataMutex.unlock(); +} + +AREXPORT void ArNetPacketSenderTcp::setBackupTimeout( + double connectionTimeoutInMins) +{ + myBackupTimeout = connectionTimeoutInMins; +} + +AREXPORT void ArNetPacketSenderTcp::setLoggingPrefix( + const char *loggingPrefix) +{ + if (loggingPrefix != NULL && loggingPrefix[0] != '\0') + myLoggingPrefix = loggingPrefix; + else + myLoggingPrefix = ""; +} + +AREXPORT void ArNetPacketSenderTcp::setDebugLogging(bool debugLogging) +{ + myDebugLogging = debugLogging; + if (myDebugLogging) + myVerboseLogLevel = ArLog::Normal; + else + myVerboseLogLevel = ArLog::Verbose; +} + +/** + Gets the socket that the receiver is using, note that it does not + have ownership of this socket and that whatever created it should. +**/ +AREXPORT ArSocket *ArNetPacketSenderTcp::getSocket(void) +{ + return mySocket; +} + +AREXPORT void ArNetPacketSenderTcp::sendPacket(ArNetPacket *packet, + const char *loggingString) +{ + ArNetPacket *sendPacket; + sendPacket = new ArNetPacket(packet->getLength() + 5); + sendPacket->duplicatePacket(packet); + if (myDebugLogging && sendPacket->getCommand() <= 255 && + loggingString != NULL && loggingString[0] != '\0') + sendPacket->setArbitraryString(loggingString); + myDataMutex.lock(); + myPacketList.push_back(sendPacket); + /* this shouldn't really ever be in doubt + if (myDebugLogging && sendPacket->getCommand() <= 255 && + loggingString != NULL && loggingString[0] != '\0') + ArLog::log(ArLog::Normal, "%s Sender put command %d in list", + myLoggingPrefix.c_str(), + loggingString, sendPacket->getCommand()); + */ + myDataMutex.unlock(); +} + +AREXPORT bool ArNetPacketSenderTcp::sendData(void) +{ + int ret; + ArTime start; + start.setToNow(); + //printf("sendData %g\n", start.mSecSince() / 1000.0); + myDataMutex.lock(); + // if we have no data to send count it as a good send + if (myPacketList.begin() == myPacketList.end() && myPacket == NULL) + myLastGoodSend.setToNow(); + + while (myPacketList.begin() != myPacketList.end() || myPacket != NULL) + { + if (myPacket == NULL) + { + //printf("!startedSending %g\n", start.mSecSince() / 1000.0); + myPacket = myPacketList.front(); + myPacketList.pop_front(); + myAlreadySent = 0; + myBuf = myPacket->getBuf(); + myLength = myPacket->getLength(); + if (myDebugLogging && myPacket->getCommand() <= 255) + ArLog::log(ArLog::Normal, "%s %s Starting sending tcp command %d", + myLoggingPrefix.c_str(), + myPacket->getArbitraryString(), myPacket->getCommand()); + if (myPacket->getCommand() == 0)// || myPacket->getCommand() > 1000) + { + ArLog::log(ArLog::Normal, "%sgetCommand is %d when it probably shouldn't be", myLoggingPrefix.c_str(), myPacket->getCommand()); + } + } + if (myLength < 0 || myLength > ArNetPacket::MAX_LENGTH) + { + ArLog::log(ArLog::Terse, "%sArNetPacketSenderTcp: getLength for command %d packet is bad at %d", + myLoggingPrefix.c_str(), myPacket->getCommand(), myLength); + delete myPacket; + myPacket = NULL; + continue; + } + if (myLength - myAlreadySent == 0) + ArLog::log(ArLog::Normal, "%sHave no data to send... but ...", + myLoggingPrefix.c_str()); + ret = mySocket->write(&myBuf[myAlreadySent], myLength - myAlreadySent); + if (ret < 0) + { + // we didn't send any data so make sure we've sent some recently enough + if (myBackupTimeout >= -.0000001 && myLastGoodSend.secSince() >= 5 && + myLastGoodSend.secSince() / 60.0 >= myBackupTimeout) + { + ArLog::log(ArLog::Normal, "%sConnection to %s backed up for %g minutes and is being closed", + myLoggingPrefix.c_str(), mySocket->getIPString(), + myBackupTimeout); + myDataMutex.unlock(); + return false; + } + +#ifdef WIN32 + if (WSAGetLastError() == WSAEWOULDBLOCK) + { + myDataMutex.unlock(); + if (myDebugLogging && myPacket->getCommand() <= 255) + ArLog::log(ArLog::Normal, + "%s%sContinue sending tcp command %d, no data could be sent", + myLoggingPrefix.c_str(), myPacket->getArbitraryString(), + myPacket->getCommand()); + return true; + } + else + { + ArLog::log(ArLog::Normal, "%sWindows failed write with error %d on packet %d with length of %d", myLoggingPrefix.c_str(), + WSAGetLastError(), myPacket->getCommand(), myLength); + myDataMutex.unlock(); + return false; + } + +#else + if (errno == EAGAIN)/* || errno == EINTR)*/ + { + myDataMutex.unlock(); + if (myDebugLogging && myPacket->getCommand() <= 255) + ArLog::log(ArLog::Normal, + "%s%sContinue sending tcp command %d, no data could be sent", + myLoggingPrefix.c_str(), + myPacket->getArbitraryString(), myPacket->getCommand()); + return true; + } + else + { + ArLog::log(ArLog::Normal, "%sLinux failed write with error %d on packet %d with length of %d", + myLoggingPrefix.c_str(), errno, myPacket->getCommand(), + myLength); + myDataMutex.unlock(); + return false; + } +#endif + } + else if (ret == 0) + { + // we didn't send any data so make sure we've sent some recently enough + if (myBackupTimeout >= -.0000001 && myLastGoodSend.secSince() >= 5 && + myLastGoodSend.secSince() / 60.0 >= myBackupTimeout) + { + ArLog::log(ArLog::Normal, "%sConnection to %s backed up for %g minutes and is being closed", + myLoggingPrefix.c_str(), mySocket->getIPString(), + myBackupTimeout); + myDataMutex.unlock(); + return false; + } + // If network connectivity goes down for a length of time, and the + // socket's buffer fills, we will have this error. An alternative action + // would be to retain myAlreadySent at its current value and keep trying to + // write data to the socket, in the hope that the network will come back. + ArLog::log(myVerboseLogLevel, "%s Couldn't send packet with command %d and length %d: No data could be sent through socket (%d bytes sent until now).", + myLoggingPrefix.c_str(), myPacket->getCommand(), myLength, + myAlreadySent); + myDataMutex.unlock(); + return true; + } + else if (ret > 0) + { + // we sent some data, count it as a good send + myLastGoodSend.setToNow(); + myAlreadySent += ret; + if (myAlreadySent == myLength) + { + if (myDebugLogging && myPacket->getCommand() <= 255) + ArLog::log(ArLog::Normal, "%s%sFinished sending tcp command %d", + myLoggingPrefix.c_str(), myPacket->getArbitraryString(), + myPacket->getCommand()); + //printf("sent one %g\n", start.mSecSince() / 1000.0); + delete myPacket; + myPacket = NULL; + continue; + } + else if (myDebugLogging && myPacket->getCommand() <= 255) + ArLog::log(ArLog::Normal, + "%s%sContinue sending tcp command %d, sent %d", + myLoggingPrefix.c_str(), myPacket->getArbitraryString(), + myPacket->getCommand(), ret); + + } + else + { + ArLog::log(ArLog::Terse, "%sBad case in sArNetPacketSenderTcp::sendData", + myLoggingPrefix.c_str()); + } + } + myDataMutex.unlock(); + return true; +} diff --git a/Legacy/Aria/ArNetworking/src/ArNetworkingDLL-vc2003.vcproj b/Legacy/Aria/ArNetworking/src/ArNetworkingDLL-vc2003.vcproj new file mode 100644 index 0000000..fd77a38 --- /dev/null +++ b/Legacy/Aria/ArNetworking/src/ArNetworkingDLL-vc2003.vcproj @@ -0,0 +1,520 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/ArNetworking/src/ArNetworkingDLL-vc2008.vcproj b/Legacy/Aria/ArNetworking/src/ArNetworkingDLL-vc2008.vcproj new file mode 100644 index 0000000..86abac8 --- /dev/null +++ b/Legacy/Aria/ArNetworking/src/ArNetworkingDLL-vc2008.vcproj @@ -0,0 +1,700 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/ArNetworking/src/ArNetworkingDLL-vc2010.vcxproj b/Legacy/Aria/ArNetworking/src/ArNetworkingDLL-vc2010.vcxproj new file mode 100644 index 0000000..cec75e7 --- /dev/null +++ b/Legacy/Aria/ArNetworking/src/ArNetworkingDLL-vc2010.vcxproj @@ -0,0 +1,298 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + ArNetworkingDLL + {783BA2AB-07CE-43AD-8FC2-FFD9F19DF575} + ArNetworkingDLL + + + + DynamicLibrary + false + MultiByte + false + v100 + + + DynamicLibrary + false + MultiByte + false + v100 + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + ../../bin/ + ../../obj/$(ProjectName)-$(Configuration)-VC10/ + false + ../../bin/ + ../../obj/$(ProjectName)-$(Configuration)-VC10/ + false + ArNetworkingDebugVC10 + ArNetworkingVC10 + + + + $(IntDir)$(ProjectName)BuildLog.htm + + + NDEBUG;%(PreprocessorDefinitions) + true + true + Win32 + .\../../lib/ArNetworkingDLL.tlb + + + + + MaxSpeed + AnySuitable + true + ..\include;..\..\include;..\internalLibraries\festival\src\include;..\internalLibraries\speech_tools\include;..\internalLibraries\sphinx2\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + false + Sync + Default + MultiThreadedDLL + false + false + NotSet + true + $(IntDir)$(TargetName)-VC10.pdb + Level3 + true + CompileAsCpp + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + AriaVC10.lib;ws2_32.lib;%(AdditionalDependencies) + $(OutDir)$(TargetFileName) + true + ../../lib;%(AdditionalLibraryDirectories) + true + $(TargetDir)$(TargetName)-VC10.pdb + false + + + ../../lib/ArNetworkingVC10.lib + MachineX86 + + + + + $(IntDir)$(ProjectName)BuildLog.htm + + + _DEBUG;%(PreprocessorDefinitions) + true + true + Win32 + .\../../lib/ArNetworkingDLL.tlb + + + + + Disabled + ..\include;..\..\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;ARIADLL_EXPORTS;%(PreprocessorDefinitions) + false + EnableFastChecks + MultiThreadedDebugDLL + true + false + true + $(IntDir)$(TargetName)-VC10.pdb + Level3 + true + ProgramDatabase + CompileAsCpp + true + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + winmm.lib;ws2_32.lib;AriaDebugVC10.lib;%(AdditionalDependencies) + $(OutDir)$(TargetFileName) + true + ../../lib;%(AdditionalLibraryDirectories) + true + $(TargetDir)$(TargetName)-VC10.pdb + false + + + ../../lib/ArNetworkingDebugVC10.lib + MachineX86 + + + + + + + + Disabled + %(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;ARSPEECHLIB_EXPORTS + Default + MaxSpeed + %(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;ARSPEECHLIB_EXPORTS + + + + + + + + + Disabled + %(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;ARSPEECHLIB_EXPORTS + Default + MaxSpeed + %(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;ARSPEECHLIB_EXPORTS + + + Disabled + %(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;ARSPEECHLIB_EXPORTS + Default + MaxSpeed + %(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;ARSPEECHLIB_EXPORTS + + + Disabled + %(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;ARSPEECHLIB_EXPORTS + Default + MaxSpeed + %(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;ARSPEECHLIB_EXPORTS + + + + Disabled + %(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;ARSPEECHLIB_EXPORTS + Default + MaxSpeed + %(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;ARSPEECHLIB_EXPORTS + + + Disabled + %(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;ARSPEECHLIB_EXPORTS + Default + MaxSpeed + %(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;ARSPEECHLIB_EXPORTS + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {606257ae-e882-4c66-84c0-72331642d09f} + false + + + + + + \ No newline at end of file diff --git a/Legacy/Aria/ArNetworking/src/ArNetworkingStatic-vc2003.vcproj b/Legacy/Aria/ArNetworking/src/ArNetworkingStatic-vc2003.vcproj new file mode 100644 index 0000000..34df001 --- /dev/null +++ b/Legacy/Aria/ArNetworking/src/ArNetworkingStatic-vc2003.vcproj @@ -0,0 +1,502 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/ArNetworking/src/ArNetworkingStatic-vc2008.vcproj b/Legacy/Aria/ArNetworking/src/ArNetworkingStatic-vc2008.vcproj new file mode 100644 index 0000000..a96cf45 --- /dev/null +++ b/Legacy/Aria/ArNetworking/src/ArNetworkingStatic-vc2008.vcproj @@ -0,0 +1,514 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/ArNetworking/src/ArNetworkingStatic-vc2010.vcxproj b/Legacy/Aria/ArNetworking/src/ArNetworkingStatic-vc2010.vcxproj new file mode 100644 index 0000000..d985424 --- /dev/null +++ b/Legacy/Aria/ArNetworking/src/ArNetworkingStatic-vc2010.vcxproj @@ -0,0 +1,263 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + ArNetworkingStatic + {1D08AFC4-1036-425C-B381-6FE522207D47} + + + + + + StaticLibrary + false + MultiByte + + + StaticLibrary + false + MultiByte + true + + + StaticLibrary + false + MultiByte + true + Windows7.1SDK + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + .\../../lib\ + ../obj/$(ProjectName)-$(Configuration)-VC10-Static\ + .\../../lib\ + ../obj/$(ProjectName)-$(Configuration)-VC10-Static\ + $(ProjectName)DebugVC10 + $(ProjectName)VC10 + + + + MaxSpeed + OnlyExplicitInline + ../../include;../include;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_LIB;ARIA_STATIC;%(PreprocessorDefinitions) + false + Default + MultiThreaded + false + false + NotSet + true + + + $(IntDir)ArNetworkingStaticVC10.pch + $(IntDir) + $(IntDir) + $(IntDir)$(TargetName)-VC10.pdb + Level3 + true + Default + + + .\../../lib\ArNetworkingStaticVC10.lib + true + %(IgnoreSpecificDefaultLibraries) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + + + Disabled + ../../include;../include;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_LIB;ARIA_STATIC;%(PreprocessorDefinitions) + Default + MultiThreadedDebug + false + true + + + $(IntDir)/ArNetworkingStaticVC10.pch + $(IntDir) + $(IntDir) + $(IntDir)$(TargetName)-VC10.pdb + Level3 + true + EditAndContinue + Default + + + .\../../lib\ArNetworkingStaticDebugVC10.lib + true + libcmtd.lib;%(IgnoreSpecificDefaultLibraries) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + + + + + + Disabled + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + EnableFastChecks + MaxSpeed + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + + + + + + + + Disabled + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + EnableFastChecks + MaxSpeed + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + Disabled + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + EnableFastChecks + MaxSpeed + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + Disabled + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + EnableFastChecks + MaxSpeed + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + Disabled + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + EnableFastChecks + MaxSpeed + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + Disabled + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + EnableFastChecks + MaxSpeed + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + Disabled + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + EnableFastChecks + MaxSpeed + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Legacy/Aria/ArNetworking/src/ArServerBase.cpp b/Legacy/Aria/ArNetworking/src/ArServerBase.cpp new file mode 100644 index 0000000..c309cc5 --- /dev/null +++ b/Legacy/Aria/ArNetworking/src/ArServerBase.cpp @@ -0,0 +1,2299 @@ +#include "Aria.h" +#include "ArExport.h" +#include "ArServerBase.h" +#include "ArServerCommands.h" +#include "ArClientCommands.h" +#include "ArServerMode.h" + +//#define ARDEBUG_SERVERBASE + +#if (defined(ARDEBUG_SERVERBASE)) +//#if ((_DEBUG) && defined(ARDEBUG_SERVERBASE)) +#define IFDEBUG(code) {code;} +#else +#define IFDEBUG(code) +#endif + +/** + @param addAriaExitCB whether to add an exit callback to aria or not + @param serverName the name for logging + @param addBackupTimeoutToConfig whether to add the backup timeout + (to clients of this server) as a config option, if this is true it + sets a default value for the timeout of 2 minutes, if its false it + has no timeout (but you can set one, see + ArServerBase::setBackupTimeout()) + @param backupTimeoutName the name of backup timeout + @param backupTimeoutName the description of backup timeout + @param masterServer If this is a master server (ie a central manager) + @param slaveServer If this is a slave server (ie a central forwarder) + @param logPasswordFailureVerbosely Whether we log password failure verbosely or not + @param allowSlowPackets Whether we allow slow packets (that go in + their own thread) or not... if we don't then they're processed in + the main thread like they have always been + @param allowIdlePackets Whether we allow idle packets (that go in + their own thread and are processed only when the robot is idle) or + not... if we don't then they're processed in the main thread like + they have always been + @param numClientsAllowed This is the number of client connections + allowed, negative values mean allow any number (the default is -1) +**/ + +AREXPORT ArServerBase::ArServerBase(bool addAriaExitCB, + const char * serverName, + bool addBackupTimeoutToConfig, + const char *backupTimeoutName, + const char *backupTimeoutDesc, + bool masterServer, bool slaveServer, + bool logPasswordFailureVerbosely, + bool allowSlowPackets, + bool allowIdlePackets, + int maxClientsAllowed) : + myProcessPacketCB(this, &ArServerBase::processPacket), + mySendUdpCB(this, &ArServerBase::sendUdp), + myAriaExitCB(this, &ArServerBase::close), + myGetFrequencyCB(this, &ArServerBase::getFrequency, 0, true), + myProcessFileCB(this, &ArServerBase::processFile), + myIdentGetConnectionIDCB(this, &ArServerBase::identGetConnectionID), + myIdentSetConnectionIDCB(this, &ArServerBase::identSetConnectionID), + myIdentSetSelfIdentifierCB(this, &ArServerBase::identSetSelfIdentifier), + myIdentSetHereGoalCB(this, &ArServerBase::identSetHereGoal), + myStartRequestTransactionCB(this, &ArServerBase::handleStartRequestTransaction), + myEndRequestTransactionCB(this, &ArServerBase::handleEndRequestTransaction), + myIdleProcessingPendingCB(this, &ArServerBase::netIdleProcessingPending) +{ + + + myDataMutex.setLogName("ArServerBase::myDataMutex"); + myClientsMutex.setLogName("ArServerBase::myClientsMutex"); + myCycleCallbacksMutex.setLogName("ArServerBase::myCycleCallbacksMutex"); + myAddListMutex.setLogName("ArServerBase::myAddListMutex"); + myRemoveSetMutex.setLogName("ArServerBase::myRemoveSetMutex"); + myProcessingSlowIdleMutex.setLogName( + "ArServerBase::myProcessingSlowIdleMutex"); + myIdleCallbacksMutex.setLogName( + "ArServerBase::myIdleCallbacksMutex"); + myBackupTimeoutMutex.setLogName("ArServerBase::myBackupTimeoutMutex"); + + if (serverName != NULL && serverName[0] > 0) + myServerName = serverName; + else + myServerName = "ArServer"; + + myLogPrefix = myServerName + "Base: "; + myDebugLogging = false; + myVerboseLogLevel = ArLog::Verbose; + + setThreadName(myServerName.c_str()); + myTcpPort = 0; + myUdpPort = 0; + myRejecting = 0; + myOpened = false; + myUdpReceiver.setProcessPacketCB(&myProcessPacketCB); + if (slaveServer) + myNextDataNumber = 40000; + else + myNextDataNumber = 256; + myUserInfo = NULL; + myAriaExitCB.setName("ArServerBaseExit"); + if (addAriaExitCB) + Aria::addExitCallback(&myAriaExitCB, 20); + + myLogPasswordFailureVerbosely = logPasswordFailureVerbosely; + myConnectionNumber = 1; + + myMostClients = 0; + myUsingOwnNumClients = true; + myNumClients = 0; + + myLoopMSecs = 1; + + if (slaveServer) + { + myAllowSlowPackets = false; + myAllowIdlePackets = false; + } + else + { + myAllowSlowPackets = allowSlowPackets; + myAllowIdlePackets = allowIdlePackets; + } + mySlowIdleThread = NULL; + + if (myAllowSlowPackets || myAllowIdlePackets) + mySlowIdleThread = new SlowIdleThread(this); + + myHaveSlowPackets = false; + myHaveIdlePackets = false; + myHaveIdleCallbacks = false; + + myMaxClientsAllowed = maxClientsAllowed; + + myEnforceType = ArServerCommands::TYPE_UNSPECIFIED; + + if (addBackupTimeoutToConfig) + { + myBackupTimeout = 10; + Aria::getConfig()->addParam( + ArConfigArg(backupTimeoutName, + &myBackupTimeout, + backupTimeoutDesc, -1), + "Connection timeouts", + ArPriority::DETAILED); + myProcessFileCB.setName("ArServerBase"); + Aria::getConfig()->addProcessFileCB(&myProcessFileCB, -100); + } + else + myBackupTimeout = -1; + + myNewBackupTimeout = false; + + if (masterServer) + { + addData("identGetConnectionID", + "gets an id for this connection, this id should then be set on any connections to the other servers associated with this one (ie the ones for individual robots) so that all the connections to one client can be tied together", + &myIdentGetConnectionIDCB, "none", "ubyte4: id", + "RobotInfo", "RETURN_SINGLE"); + } + + if (slaveServer) + { + addData("identSetConnectionID", + "Sets an id for this connection, this id should then be from the getID on the main connection for this server, this is so that all the connections to one client can be tied together", + &myIdentSetConnectionIDCB, "ubyte4: id", "none", + "RobotInfo", "RETURN_SINGLE"); + } + + addData("identSetSelfIdentifier", + "Sets an arbitrary self identifier for this connection, this can be used by programs to send information back to the same client (if this and the identSetHereGoal)", + &myIdentSetSelfIdentifierCB, "string: selfID", "none", + "RobotInfo", "RETURN_SINGLE"); + + addData("identSetHereGoal", + "Sets an string for the here goal for this connection, this can be used by programs to send information back to the same client (if this and the identSetSelfID match)", + &myIdentSetHereGoalCB, "string: hereGoal", "none", + "RobotInfo", "RETURN_SINGLE"); + + addData("requestOnceReturnIsAlwaysTcp", + "The presence of this command means that any requestOnce commands will have the data sent back to them as tcp... any requestOnceUdp will be returned either as tcp or udp (that is up to the callback sending the data)", + &myIdentSetHereGoalCB, "none", "none", + "RobotInfo", "RETURN_NONE"); + + if (myAllowIdlePackets) + addData("idleProcessingPending", + "The presence of this command means that the server will process packets flagged IDLE_PACKET only when the robot is idle. This packet will be broadcast when the state of idle processing changes.", + &myIdleProcessingPendingCB, "none", "byte: 1 for idle processing pending, 0 for idle processing not pending", + "RobotInfo", "RETURN_SINGLE"); + + addData("requestClientRestart", + "If certain changes on the robot happen the clients may need to restart, this message is broadcast when those changes occur.", + NULL, + "none", + "byte: restartNumber, which is 1 for a restart because of config changes (there will likely be more reasons later); string: human readable reason for restart. (The restartNumber is intended for heavy weight clients, the string is intended for lighter weight clients.)", + "RobotInfo", "RETURN_NONE"); + + + + // The start/end-RequestTransaction packets encapsulate a sequence of related + // messages. Their primary purpose is to delay the execution of any queued + // idle packets until the sequence has completed. (This somewhat implies that + // they shouldn't be used to create a sequence of idle packets.) + // + // Currently, these packets are only used by the Central Server when + // it is determining whether the map file needs to be downloaded to the robot. + // The checkMap or setConfig* commands are executed in the idle thread after + // the download has completed. + // + addData("startRequestTransaction", + "Special packet that marks the beginning of a multiple-packet request-response sequence. Must be followed by an endRequestTransaction packet upon completion.", + &myStartRequestTransactionCB, + "none", + "", + "RobotInfo", "RETURN_NONE"); + + addData("endRequestTransaction", + "Special packet that marks the end of a multiple-packet request-response sequence. Idle processing does not proceed until transaction is ended.", + &myEndRequestTransactionCB, + "none", + "", + "RobotInfo", "RETURN_NONE"); + +} + +AREXPORT ArServerBase::~ArServerBase() +{ + close(); + + if (mySlowIdleThread != NULL) + { + delete mySlowIdleThread; + mySlowIdleThread = NULL; + } +} + +/** + This opens the server up on the given port, you will then need to + run the server for it to actually listen and respond to client connections. + + @param port the port to open the server on + @param openOnIP If not null, only listen on the local network interface with this address + @param tcpOnly If true, only accept TCP connections. If false, use both TCP + and UDP communications with clients. + + @return true if the server could open the port, false otherwise +**/ +AREXPORT bool ArServerBase::open(unsigned int port, const char *openOnIP, + bool tcpOnly) +{ + myDataMutex.lock(); + myTcpPort = port; + myTcpOnly = tcpOnly; + if (openOnIP != NULL) + myOpenOnIP = openOnIP; + else + myOpenOnIP = ""; + + + if (myTcpSocket.open(myTcpPort, ArSocket::TCP, openOnIP)) + { + // This can be taken out since the open does this now + //myTcpSocket.setLinger(0); + myTcpSocket.setNonBlock(); + } + else + { + myOpened = false; + myDataMutex.unlock(); + return false; + } + + if (myTcpOnly) + { + if (openOnIP != NULL) + ArLog::log(ArLog::Normal, + "%sStarted on tcp port %d on ip %s.", + myLogPrefix.c_str(), myTcpPort, openOnIP); + else + ArLog::log(ArLog::Normal, "%sStarted on tcp port %d.", + myLogPrefix.c_str(), myTcpPort); + myOpened = true; + myUdpPort = 0; + myDataMutex.unlock(); + return true; + } + + if (myUdpSocket.create(ArSocket::UDP) && + myUdpSocket.findValidPort(myTcpPort, openOnIP) && + myUdpSocket.setNonBlock()) + { + // not possible on udp? myUdpSocket.setLinger(0); + myUdpPort = ArSocket::netToHostOrder(myUdpSocket.inPort()); + myUdpReceiver.setSocket(&myUdpSocket); + if (openOnIP != NULL) + ArLog::log(ArLog::Normal, + "%sStarted on tcp port %d and udp port %d on ip %s.", + myLogPrefix.c_str(), myTcpPort, myUdpPort, openOnIP); + else + ArLog::log(ArLog::Normal, "%sStarted on tcp port %d and udp port %d.", + myLogPrefix.c_str(), myTcpPort, myUdpPort); + + } + else + { + myOpened = false; + myTcpSocket.close(); + myDataMutex.unlock(); + return false; + } + myOpened = true; + myDataMutex.unlock(); + return true; +} + +AREXPORT void ArServerBase::close(void) +{ + std::list::iterator it; + ArServerClient *client; + + myClientsMutex.lock(); + if (!myOpened) + { + myClientsMutex.unlock(); + return; + } + + ArLog::log(ArLog::Normal, "%sServer shutting down.", + myLogPrefix.c_str()); + myOpened = false; + // now send off the client packets to shut down + for (it = myClients.begin(); it != myClients.end(); ++it) + { + client = (*it); + client->shutdown(); + printf("Sending shutdown\n"); + } + + ArUtil::sleep(10); + + while ((it = myClients.begin()) != myClients.end()) + { + client = (*it); + myClients.pop_front(); + delete client; + } + myTcpSocket.close(); + if (!myTcpOnly) + myUdpSocket.close(); + myClientsMutex.unlock(); + + /// MPL adding this since it looks like its leaked + myDataMutex.lock(); + ArUtil::deleteSetPairs(myDataMap.begin(), myDataMap.end()); + myDataMap.clear(); + myDataMutex.unlock(); +} + +void ArServerBase::acceptTcpSockets(void) +{ + //ArSocket socket; + + //myClientsMutex.lock(); + + // loop while we have new connections to make... we need to make a + // udp auth key for any accepted sockets and send our introduction + // to the client + while (myTcpSocket.accept(&myAcceptingSocket) && + myAcceptingSocket.getFD() >= 0) + { + finishAcceptingSocket(&myAcceptingSocket, false); + } + //myClientsMutex.unlock(); +} + +AREXPORT ArServerClient *ArServerBase::makeNewServerClientFromSocket( + ArSocket *socket, bool overrideGeneralReject) +{ + ArServerClient *serverClient = NULL; + //myDataMutex.lock(); + serverClient = finishAcceptingSocket(socket, true, + overrideGeneralReject); + //myDataMutex.unlock(); + return serverClient; +} + +AREXPORT ArServerClient *ArServerBase::finishAcceptingSocket( + ArSocket *socket, bool skipPassword, + bool overrideGeneralReject) +{ + ArServerClient *client; + bool foundAuthKey; + std::list::iterator it; + bool thisKeyBad; + long authKey; + long introKey; + ArNetPacket packet; + int iterations; + + ArLog::log(ArLog::Normal, "%sNew connection from %s", + myLogPrefix.c_str(), socket->getIPString()); + + myClientsMutex.lock(); + // okay, now loop until we find a key or until we've gone 10000 + // times (huge error but not worth locking up on)... basically + // we're making sure that none of the current clients already have + // this key... they should never have it if random is working + // right... but... + for (foundAuthKey = false, authKey = ArMath::random(), iterations = 0; + !foundAuthKey && iterations < 10000; + iterations++, authKey = ArMath::random()) + { + // see if any of the current clients have this authKey + for (thisKeyBad = false, it = myClients.begin(); + !thisKeyBad && it != myClients.end(); + ++it) + { + if (authKey == (*it)->getAuthKey()) + thisKeyBad = true; + } + // if the key wasn't found above it means its clean, so we found + // a good one and are done + if (!thisKeyBad) + foundAuthKey = true; + } + myClientsMutex.unlock(); + if (!foundAuthKey) + authKey = 0; + // now we pick an introKey which introduces the server to the client + // this one isn't critical that it be unique though, so we just + // set it straight out + introKey = ArMath::random(); + std::string passwordKey; + int numInPasswordKey = ArMath::random() % 100; + int i; + passwordKey = ""; + if (!skipPassword) + { + for (i = 0; i < numInPasswordKey; i++) + passwordKey += '0' + ArMath::random() % ('z' - '0'); + } + int reject; + const char *rejectString; + + char tooManyClientsBuf[1024]; + + // if we have too many clients, reject this because of that... + if (myMaxClientsAllowed > 0 && myNumClients + 1 > myMaxClientsAllowed) + { + sprintf(tooManyClientsBuf, "Server rejecting connection since it would exceed the maximum number of allowed connections (which is %d)", + myMaxClientsAllowed); + reject = 5; + rejectString = tooManyClientsBuf; + + myTooManyClientsCBList.invoke(socket->getIPString()); + } + // if we're overriding the blanket reject it's probably because we + // are rejecting direct connections and this connection is from the + // client switch.... + else if (overrideGeneralReject) + { + reject = 0; + rejectString = ""; + } + else + { + reject = myRejecting; + rejectString = myRejectingString.c_str(); + } + std::string serverClientName = myServerName + "Client_" + socket->getIPString(); + ArLog::log(myVerboseLogLevel, "%sHanding off connection to %s to %s", + myLogPrefix.c_str(), socket->getIPString(), + serverClientName.c_str()); + client = new ArServerClient(socket, myUdpPort, authKey, introKey, + &mySendUdpCB, &myDataMap, + passwordKey.c_str(), myServerKey.c_str(), + myUserInfo, reject, rejectString, + myDebugLogging, serverClientName.c_str(), + myLogPasswordFailureVerbosely, + myAllowSlowPackets, myAllowIdlePackets, + myEnforceProtocolVersion.c_str(), + myEnforceType); + //client->setUdpAddress(socket->sockAddrIn()); + // put the client onto our list of clients... + //myClients.push_front(client); + myAddListMutex.lock(); + myAddList.push_front(client); + myAddListMutex.unlock(); + return client; +} + +AREXPORT int ArServerBase::getNumClients(void) +{ + return myNumClients; +} + +AREXPORT void ArServerBase::run(void) +{ + runInThisThread(); +} + +AREXPORT void ArServerBase::runAsync(void) +{ + create(); +} + +AREXPORT void *ArServerBase::runThread(void *arg) +{ + threadStarted(); + while (myRunning) + { + loopOnce(); + ArUtil::sleep(myLoopMSecs); + } + close(); + threadFinished(); + return NULL; +} + + +/** + This will broadcast this packet to any client that wants this + data.... this no longer excludes things because that doesn't work + well with the central server, so use + broadcastPacketTcpWithExclusion for that if you really want it... + + @param packet the packet to send + @param name the type of data to send + @return false if there is no data for this name +**/ +AREXPORT bool ArServerBase::broadcastPacketTcp(ArNetPacket *packet, + const char *name) +{ + return broadcastPacketTcpWithExclusion(packet, name, NULL); +} + + +/** + This will broadcast this packet to any client that wants this + data.... + + @param packet the packet to send + @param name the type of data to send + @param identifier the identifier to match + @param matchConnectionID true to match the connection ID, false to + match the other ID + @return false if there is no data for this name +**/ +AREXPORT bool ArServerBase::broadcastPacketTcpToMatching( + ArNetPacket *packet, const char *name, + ArServerClientIdentifier identifier, bool matchConnectionID) +{ + return broadcastPacketTcpWithExclusion(packet, name, NULL, true, identifier, + matchConnectionID); +} + +/** + This will broadcast this packet to any client that wants this data. + + @param packet the packet to send + @param name the type of data to send + @param excludeClient don't send data to this client (NULL (the default) just + ignores this feature) + @param match whether to match the identifier or not + @param identifier the identifier to match + @param matchConnectionID true to match the connection ID, false to + match the other ID + @return false if there is no data for this name +**/ +AREXPORT bool ArServerBase::broadcastPacketTcpWithExclusion( + ArNetPacket *packet, const char *name, ArServerClient *excludeClient, + bool match, ArServerClientIdentifier identifier, + bool matchConnectionID) +{ + // first find our number so each client doesn't have to + std::map::iterator it; + unsigned int command = 0; + +// ArLog::log(ArLog::Normal, +// "ArServerBase::broadcastPacketTcpWithExclusion() called"); + + myDataMutex.lock(); +// ArLog::log(ArLog::Normal, +// "ArServerBase::broadcastPacketTcpWithExclusion() data lock obtained"); + for (it = myDataMap.begin(); it != myDataMap.end(); it++) + { + if (!strcmp((*it).second->getName(), name)) + command = (*it).second->getCommand(); + } + if (command == 0) + { + ArLog::log(myVerboseLogLevel, + "ArServerBase::broadcastPacket: no command by name of \"%s\"", + name); + myDataMutex.unlock(); + return false; + } + myDataMutex.unlock(); + return broadcastPacketTcpByCommandWithExclusion( + packet, command, excludeClient, match, identifier, + matchConnectionID); +} + +/** + This will broadcast this packet to any client that wants this + data.... this no longer excludes things because that doesn't work + well with the central server, so use + broadcastPacketTcpByCommandWithExclusion for that... + + @param packet the packet to send + @param command the command number of the data to send + + @return false if there is no data for this name +**/ +AREXPORT bool ArServerBase::broadcastPacketTcpByCommand( + ArNetPacket *packet, unsigned int command) +{ + return broadcastPacketTcpByCommandWithExclusion(packet, command, NULL); +} + +/** + This will broadcast this packet to any client that wants this data. + + @param packet the packet to send + @param command the command number of the data to send + @param excludeClient don't send data to this client (NULL (the default) just + ignores this feature) + @param match whether to match the identifier or not + @param identifier the identifier to match + @param matchConnectionID true to match the connection ID, false to + match the other ID + + @return false if there is no data for this name +**/ +AREXPORT bool ArServerBase::broadcastPacketTcpByCommandWithExclusion( + ArNetPacket *packet, unsigned int command, + ArServerClient *excludeClient, bool match, + ArServerClientIdentifier identifier, bool matchConnectionID) +{ + std::list::iterator lit; + ArServerClient *serverClient; + ArNetPacket emptyPacket; + +// ArLog::log(ArLog::Normal, +// "ArServerBase::broadcastPacketTcpByCommandWithExclusion() called"); + + myClientsMutex.lock(); +// ArLog::log(ArLog::Normal, +// "ArServerBase::broadcastPacketTcpByCommandWithExclusion() client lock obtained"); + emptyPacket.empty(); + + if (!myOpened) + { + ArLog::log(ArLog::Verbose, "ArServerBase::broadcastPacket: server not open to send packet."); + myClientsMutex.unlock(); + return false; + } + + if (packet == NULL) + packet = &emptyPacket; + + packet->setCommand(command); + for (lit = myClients.begin(); lit != myClients.end(); ++lit) + { + serverClient = (*lit); + if (excludeClient != NULL && serverClient == excludeClient) + continue; + if (match && + !serverClient->getIdentifier().matches(identifier, matchConnectionID)) + continue; + serverClient->broadcastPacketTcp(packet); + } + + myClientsMutex.unlock(); + return true; +} + + +/** + This will broadcast this packet to any client that wants this + data.... this no longer excludes things because that doesn't work + well with the central server, so use + broadcastPacketUdpWithExclusion for that if you really want to + + @param packet the packet to send + @param name the type of data to send + + @return false if there is no data for this name +**/ +AREXPORT bool ArServerBase::broadcastPacketUdp(ArNetPacket *packet, + const char *name) +{ + return broadcastPacketUdpWithExclusion(packet, name, NULL); +} + +/** + This will broadcast this packet to any client that wants this + data.... + + @param packet the packet to send + @param name the type of data to send + @param identifier the identifier to match + @param matchConnectionID true to match the connection ID, false to + match the other ID + + @return false if there is no data for this name +**/ +AREXPORT bool ArServerBase::broadcastPacketUdpToMatching( + ArNetPacket *packet, const char *name, + ArServerClientIdentifier identifier, bool matchConnectionID) +{ + return broadcastPacketUdpWithExclusion(packet, name, NULL, true, + identifier, matchConnectionID); +} + +/** + This will broadcast this packet to any client that wants this data. + + @param packet the packet to send + @param name the type of data to send + @param excludeClient don't send data to this client (NULL (the default) just + ignores this feature) + @param match whether to match the identifier or not + @param identifier the identifier to match + @param matchConnectionID true to match the connection ID, false to + match the other ID + @return false if there is no data for this name +**/ + +AREXPORT bool ArServerBase::broadcastPacketUdpWithExclusion( + ArNetPacket *packet, const char *name, ArServerClient *excludeClient, + bool match, ArServerClientIdentifier identifier, + bool matchConnectionID) +{ + // first find our number so each client doesn't have to + std::map::iterator it; + unsigned int command = 0; + + myDataMutex.lock(); + for (it = myDataMap.begin(); it != myDataMap.end(); it++) + { + if (!strcmp((*it).second->getName(), name)) + command = (*it).second->getCommand(); + } + if (command == 0) + { + ArLog::log(myVerboseLogLevel, + "ArServerBase::broadcastPacket: no command by name of \"%s\"", + name); + myDataMutex.unlock(); + return false; + } + myDataMutex.unlock(); + return broadcastPacketUdpByCommandWithExclusion( + packet, command, excludeClient, match, identifier, + matchConnectionID); +} + +/** + This will broadcast this packet to any client that wants this + data.... + + (To restrict what clients the command is sent to, use the + broadcastPacketUdpByCommandWithExclusion() method.) + + @param packet the packet to send + @param command the type of data to send + + @return false if there is no data for this name +**/ +AREXPORT bool ArServerBase::broadcastPacketUdpByCommand( + ArNetPacket *packet, unsigned int command) +{ + return broadcastPacketUdpByCommandWithExclusion(packet, command, NULL); +} + +/** + This will broadcast this packet to any client that wants this data. + + @param packet the packet to send + @param command the type of data to send + @param excludeClient don't send data to this client (NULL (the default) just + ignores this feature) + @param match whether to match the identifier or not + @param identifier the identifier to match + @param matchConnectionID true to match the connection ID, false to + match the other ID + @return false if there is no data for this name +**/ +AREXPORT bool ArServerBase::broadcastPacketUdpByCommandWithExclusion( + ArNetPacket *packet, unsigned int command, + ArServerClient *excludeClient, bool match, + ArServerClientIdentifier identifier, bool matchConnectionID) +{ + std::list::iterator lit; + ArServerClient *serverClient; + ArNetPacket emptyPacket; + + myClientsMutex.lock(); + emptyPacket.empty(); + + if (!myOpened) + { + ArLog::log(ArLog::Verbose, "ArServerBase::broadcastPacket: server not open to send packet."); + myClientsMutex.unlock(); + return false; + } + + if (packet == NULL) + packet = &emptyPacket; + + packet->setCommand(command); + for (lit = myClients.begin(); lit != myClients.end(); ++lit) + { + serverClient = (*lit); + if (excludeClient != NULL && serverClient == excludeClient) + continue; + if (match && + !serverClient->getIdentifier().matches(identifier, matchConnectionID)) + continue; + serverClient->broadcastPacketUdp(packet); + } + myClientsMutex.unlock(); + return true; +} + +/** + @param name Name is the name of the command number to be found + + @return the number of the command or 0 if no command has that name +**/ + +AREXPORT unsigned int ArServerBase::findCommandFromName(const char *name) +{ + // first find our number so each client doesn't have to + std::map::iterator it; + unsigned int num = 0; + myDataMutex.lock(); + + for (it = myDataMap.begin(); it != myDataMap.end(); it++) + { + if (!strcmp((*it).second->getName(), name)) + num = (*it).second->getCommand(); + } + if (num == 0) + { + ArLog::log(myVerboseLogLevel, + "ArServerBase::findCommandFromName: no command by name of \"%s\"", + name); + myDataMutex.unlock(); + return 0; + } + myDataMutex.unlock(); + return num; +} + +/** + This runs the server loop once, normally you'll probably just use + run() or runAsync(), but if you want to drive this server from within your own + loop just call this repeatedly, but do note it takes up no time + at all, so you'll want to put in your own millisecond sleep so it + doesn't monopolize the CPU. + **/ +AREXPORT void ArServerBase::loopOnce(void) +{ + std::list::iterator it; + std::set::iterator setIt; + // for speed we'd use a list of iterators and erase, but for clarity + // this is easier and this won't happen that often + //std::list removeList; + ArServerClient *client; + + myDataMutex.lock(); + if (!myOpened) + { + myDataMutex.unlock(); + return; + } + myDataMutex.unlock(); + + acceptTcpSockets(); + + if (!myTcpOnly) + myUdpReceiver.readData(); + + if (myProcessingSlowIdleMutex.tryLock() == 0) + { + myClientsMutex.lock(); + myAddListMutex.lock(); + while (!myAddList.empty()) + { + myClients.push_back(myAddList.front()); + myAddList.pop_front(); + } + myAddListMutex.unlock(); + myClientsMutex.unlock(); + myProcessingSlowIdleMutex.unlock(); + } + + bool needIdleProcessing = idleProcessingPending(); + if (needIdleProcessing != myLastIdleProcessingPending) + { + ArNetPacket sendingPacket; + if (needIdleProcessing) + sendingPacket.byteToBuf(1); + else + sendingPacket.byteToBuf(0); + broadcastPacketTcp(&sendingPacket, "idleProcessingPending"); + myLastIdleProcessingPending = needIdleProcessing; + } + + myBackupTimeoutMutex.lock(); + + double backupTimeout = myBackupTimeout; + bool newBackupTimeout = myNewBackupTimeout; + myNewBackupTimeout = false; + + myBackupTimeoutMutex.unlock(); + + + bool haveSlowPackets = false; + bool haveIdlePackets = false; + int numClients = 0; + + + // need a recursive lock before we can lock here but we should be + //okay without a lock here (and have been for ages) + //myClientsMutex.lock(); first let the clients handle new data + for (it = myClients.begin(); it != myClients.end(); ++it) + { + client = (*it); + numClients++; + + if (newBackupTimeout) + client->setBackupTimeout(backupTimeout); + + if (!client->tcpCallback()) + { + client->forceDisconnect(true); + myRemoveSetMutex.lock(); + myRemoveSet.insert(client); + myRemoveSetMutex.unlock(); + } + else + { + if (client->hasSlowPackets()) + haveSlowPackets = true; + if (client->hasIdlePackets()) + haveIdlePackets = true; + } + + } + + myHaveSlowPackets = haveSlowPackets; + myHaveIdlePackets = haveIdlePackets; + + // if we're using our own num clients then check the max and set it + if (myUsingOwnNumClients) + { + // remember how many we've had at max so its easier to track down memory + if (numClients > myMostClients) + myMostClients = numClients; + + myNumClients = numClients; + } + else + { + // if not then check the max + if (myNumClients > myMostClients) + myMostClients = myNumClients; + } + + //printf("Before...\n"); + if (myProcessingSlowIdleMutex.tryLock() == 0) + { + //printf("Almost...\n"); + myClientsMutex.lock(); + myRemoveSetMutex.lock(); + //printf("In...\n"); + while ((setIt = myRemoveSet.begin()) != myRemoveSet.end()) + { + client = (*setIt); + myClients.remove(client); + for (std::list *>::iterator rci = myClientRemovedCallbacks.begin(); + rci != myClientRemovedCallbacks.end(); + rci++) { + if (*rci) { + (*rci)->invoke(client); + } + } + + myRemoveSet.erase(client); + delete client; + } + myRemoveSetMutex.unlock(); + myClientsMutex.unlock(); + //printf("out...\n"); + myProcessingSlowIdleMutex.unlock(); + } + + // now let the clients send off their packets + for (it = myClients.begin(); it != myClients.end(); ++it) + { + client = (*it); + client->handleRequests(); + } + // need a recursive lock before we can lock here but we should be + //okay without a lock here (and have been for ages) + //myClientsMutex.unlock(); + myCycleCallbacksMutex.lock(); + // call cycle callbacks + for(std::list::const_iterator f = myCycleCallbacks.begin(); + f != myCycleCallbacks.end(); f++) + { + if(*f) (*f)->invoke(); + } + myCycleCallbacksMutex.unlock(); +} + +AREXPORT void ArServerBase::processPacket(ArNetPacket *packet, struct sockaddr_in *sin) +{ + std::list::iterator it; + unsigned char *bytes = (unsigned char *)&sin->sin_addr.s_addr; + ArServerClient *client; + struct sockaddr_in *clientSin; + + myClientsMutex.lock(); + // if its a udp packet then see if we have its owner + if (packet->getCommand() == ArClientCommands::UDP_INTRODUCTION) + { + long authKey; + bool matched; + + authKey = packet->bufToUByte4(); + for (matched = false, it = myClients.begin(); + !matched && it != myClients.end(); ++it) + { + client = (*it); + if (client->getAuthKey() == authKey) + { + packet->resetRead(); + /* + ArLog::log(ArLog::Normal, "Got process auth from %d.%d.%d.%d %d\n", + bytes[0], bytes[1], bytes[2], bytes[3], + ArSocket::netToHostOrder(sin->sin_port)); + */ + client->processAuthPacket(packet, sin); + } + } + myClientsMutex.unlock(); + return; + } + + // it wasn't the introduction so handle it the normal way + + // walk through our list of clients and see if it was one of them, + // if so return + for (it = myClients.begin(); it != myClients.end(); ++it) + { + client = (*it); + clientSin = client->getUdpAddress(); + if (clientSin->sin_port == sin->sin_port && + clientSin->sin_addr.s_addr == sin->sin_addr.s_addr) + { + client->processPacket(packet, false); + myClientsMutex.unlock(); + return; + } + /* + else + { + bytes = (unsigned char *)&clientSin->sin_addr.s_addr; + printf("Wanted %d.%d.%d.%d %d\n", bytes[0], + bytes[1], bytes[2], bytes[3], + ArSocket::netToHostOrder(clientSin->sin_port)); + } + */ + } + // if it wasn't one of our clients it was from somewhere bogus + //bytes = (unsigned char *)&clientSin->sin_addr.s_addr; + bytes = (unsigned char *)&sin->sin_addr.s_addr; + if (myDataMap.find(packet->getCommand()) != myDataMap.end()) + ArLog::log(ArLog::Normal, + "UDP Packet %s from bogus source %d.%d.%d.%d %d\n", + myDataMap[packet->getCommand()]->getName(), + bytes[0], bytes[1], bytes[2], bytes[3], + ArSocket::netToHostOrder(sin->sin_port)); + else + ArLog::log(ArLog::Normal, + "UDP Packet unknown from bogus source %d.%d.%d.%d %d\n", + bytes[0], bytes[1], bytes[2], bytes[3], + ArSocket::netToHostOrder(sin->sin_port)); + myClientsMutex.unlock(); +} + +AREXPORT bool ArServerBase::sendUdp(ArNetPacket *packet, struct sockaddr_in *sin) +{ + bool ret; + // this doesn't lock since it should only be called from + ret = myUdpSocket.sendTo(packet->getBuf(), packet->getLength(), sin); + return ret; +} + +/** + * @note A callback is called from the server run loop, and if this callback + * does not return in a timely manner data reception will be delayed (blocked). + + + @param name the name of the data + + @param description the more verbose description of what the data is for + + @param functor the functor to call when this data is requested + + @param argumentDescription a description of the arguments expected + + @param returnDescription a description of what the data returns + + @param commandGroup the name of the group this command is in + + @param dataFlags Most people won't need this, its for some advanced + server things... this is a list of data flags separated by | + characters, the flags are listed in ArClientData docs + + @pynote Pass the name of a function or a lambda expression for @arg functor. + @javanote Use a subclass of ArFunctor_ServerData instead of the ArFunctor2 template @arg functor. +**/ +AREXPORT bool ArServerBase::addData( + const char *name, const char *description, + ArFunctor2 * functor, + const char *argumentDescription, const char *returnDescription, + const char *commandGroup, const char *dataFlags) +{ + return addDataAdvanced(name, description, functor, argumentDescription, + returnDescription, commandGroup, dataFlags); +} + +/** + @copydoc ArServerBase::addData() + + @param advancedCommandNumber 0 for most people... it is the optional number + of the command, this is a very advanced option and is made for some + server forwarding things so basically no one should use it, 0 means + use the auto way... anything else does it manually... the number + needs to be the same or higher as the next number available + + @param requestChangedFunctor functor called with the lowest amount + of time requested for this packet, called whenever the requests for + the packet change, note that 0 and higher means thats how often it + was asked for, -1 means something has requested the data but just + when it is called, and -2 means that nothing wants the data + + @param requestOnceFunctor functor called if this was a request + once... with the server and client just like the normal functor, + but its only called if its a request once, note that both are + called (as long as they aren't NULL of course) + + @sa addData() +**/ + +AREXPORT bool ArServerBase::addDataAdvanced( + const char *name, const char *description, + ArFunctor2 * functor, + const char *argumentDescription, const char *returnDescription, + const char *commandGroup, const char *dataFlags, + unsigned int advancedCommandNumber, + ArFunctor2 *requestChangedFunctor, + ArRetFunctor2 *requestOnceFunctor) +{ + ArServerData *serverData; + std::map::iterator it; + + myDataMutex.lock(); + + //printf("%s %s\n", name, description); + // if we already have one we can't do this + for (it = myDataMap.begin(); it != myDataMap.end(); it++) + { + if (!strcmp((*it).second->getName(), name)) + { + ArLog::log(ArLog::Verbose, "ArServerBase::addData: already have data for name \"%s\", could not add it.", name); + myDataMutex.unlock(); + return false; + } + } + ArLog::log(ArLog::Verbose, "ArServerBase::addData: name \"%s\" mapped to number %d", name, myNextDataNumber); + if (advancedCommandNumber != 0) + { + // old check from unified command numbers + /* if (advancedCommandNumber < myNextDataNumber) + { + ArLog::log(ArLog::Normal, "ArServerBase::addData: Advanced command number given for %s but the number is too low, it wasn't added", name); + myDataMutex.unlock(); + return false; + } + */ + if (myDataMap.find(advancedCommandNumber) != myDataMap.end()) + { + ArLog::log(ArLog::Normal, "ArServerBase::addData: Advanced command number given for %s is already used, it wasn't added", name); + myDataMutex.unlock(); + return false; + } + serverData = new ArServerData(name, description, advancedCommandNumber, + functor, argumentDescription, + returnDescription, commandGroup, dataFlags, + &myGetFrequencyCB, requestChangedFunctor, + requestOnceFunctor); + if (myAdditionalDataFlags.size() > 0) + serverData->addDataFlags(myAdditionalDataFlags.c_str()); + myDataMap[advancedCommandNumber] = serverData; + myDataMutex.unlock(); + return true; + + } + else + { + serverData = new ArServerData(name, description, myNextDataNumber, + functor, argumentDescription, + returnDescription, commandGroup, dataFlags, + &myGetFrequencyCB, requestChangedFunctor, + requestOnceFunctor); + if (myAdditionalDataFlags.size() > 0) + serverData->addDataFlags(myAdditionalDataFlags.c_str()); + myDataMap[myNextDataNumber] = serverData; + myNextDataNumber++; + myDataMutex.unlock(); + return true; + } +} + + +/** Cycle callbacks are called every cycle, in no particular order. + * @param functor Functor to add. + */ +AREXPORT void ArServerBase::addCycleCallback(ArFunctor* functor) +{ + myCycleCallbacksMutex.lock(); + myCycleCallbacks.push_back(functor); + myCycleCallbacksMutex.unlock(); +} + +/** Cycle callbacks are called every cycle, in no particular order. + * @param functor Functor to remove. If it's not currently in the cycle callback + * list, nothing is done. + */ +AREXPORT void ArServerBase::remCycleCallback(ArFunctor* functor) +{ + myCycleCallbacksMutex.lock(); + myCycleCallbacks.remove(functor); + myCycleCallbacksMutex.unlock(); +} + +/** + * @javanote Use ArFunctor_ServerClient instead of ArFunctor1 + * for @a functor. + */ +AREXPORT void ArServerBase::addClientRemovedCallback(ArFunctor1 *functor) +{ + myDataMutex.lock(); + myClientRemovedCallbacks.push_back(functor); + myDataMutex.unlock(); +} + +/** + * @javanote Use ArFunctor_ServerClient instead of ArFunctor1 + * for @a functor. + */ +AREXPORT void ArServerBase::remClientRemovedCallback(ArFunctor1 *functor) +{ + myDataMutex.lock(); + myClientRemovedCallbacks.remove(functor); + myDataMutex.unlock(); +} + + +AREXPORT bool ArServerBase::loadUserInfo(const char *fileName, + const char *baseDirectory) +{ + if (myUserInfo != NULL) + { + delete myUserInfo; + myUserInfo = NULL; + } + ArServerUserInfo *userInfo = new ArServerUserInfo; + userInfo->setBaseDirectory(baseDirectory); + if (!userInfo->readFile(fileName)) + { + ArLog::log(ArLog::Terse, "%sloadUserInfo: Could not load user info for %s", myLogPrefix.c_str()); + delete userInfo; + return false; + } + if (!userInfo->doNotUse()) + { + ArLog::log(ArLog::Normal, "%sLoaded user information", + myLogPrefix.c_str()); + myDataMutex.lock(); + myUserInfo = userInfo; + myDataMutex.unlock(); + } + else + { + ArLog::log(ArLog::Normal, + "%sLoaded user information but not using it", + myLogPrefix.c_str()); + delete userInfo; + } + return true; +} + +AREXPORT void ArServerBase::logUserInfo(void) +{ + myDataMutex.lock(); + if (myUserInfo == NULL) + ArLog::log(ArLog::Terse, + "%sNo user name or password needed to connect", + myLogPrefix.c_str()); + else + myUserInfo->logUsers(); + myDataMutex.unlock(); +} + +/** + Logs the different groups of commands. It logs the command names + first along with the list of commands in that group. Then it + outputs a list of groups. Useful for building the user/pass file. +**/ +AREXPORT void ArServerBase::logCommandGroups(void) +{ + logCommandGroupsToFile(NULL); +} + +/** + For a description of what this outputs see logCommandGroups +**/ +AREXPORT void ArServerBase::logCommandGroupsToFile(const char *fileName) +{ + std::map::iterator dit; + + std::multimap groups; + std::multimap::iterator git; + + myDataMutex.lock(); + for (dit = myDataMap.begin(); dit != myDataMap.end(); dit++) + { + std::string group; + std::string command; + command = (*dit).second->getName(); + if ((*dit).second->getCommandGroup() == NULL) + group = ""; + else + group = (*dit).second->getCommandGroup(); + + groups.insert(std::pair(group, command)); + } + + FILE *file = NULL; + if (fileName != NULL) + { + file = ArUtil::fopen(fileName, "w"); + } + + char descLine[10000]; + std::string line; + std::string lastGroup; + bool first = true; + bool firstGroup = true; + std::map::iterator dIt; + std::string listOfGroups = "Groups"; + + for (git = groups.begin(); git != groups.end(); git++) + { + if (ArUtil::strcasecmp((*git).first, lastGroup) != 0 || firstGroup) + { + if (!firstGroup) + { + if (file != NULL) + fprintf(file, "%s", line.c_str()); + else + ArLog::log(ArLog::Terse, "%s", line.c_str()); + } + first = true; + firstGroup = false; + lastGroup = (*git).first; + listOfGroups += " "; + if (lastGroup.size() == 0) + listOfGroups += "None"; + else + listOfGroups += lastGroup; + } + if (first) + { + line = "CommandGroup "; + if ((*git).first.size() == 0) + { + line += "None"; + } + else + { + // output the groups description if therei s one + if ((dIt = myGroupDescription.find((*git).first)) != + myGroupDescription.end()) + snprintf(descLine, sizeof(descLine), + "CommandGroup %s has description %s", + (*git).first.c_str(), (*dIt).second.c_str()); + else + snprintf(descLine, sizeof(descLine), + "CommandGroup %s has no description", + (*git).first.c_str()); + if (file != NULL) + fprintf(file, "%s\n", descLine); + else + ArLog::log(ArLog::Terse, "%s", descLine); + + line += (*git).first.c_str(); + } + line += " is"; + + + } + line += " "; + line += (*git).second.c_str(); + first = false; + } + if (!firstGroup && !first) + { + if (file != NULL) + fprintf(file, "%s\n", line.c_str()); + else + ArLog::log(ArLog::Terse, "%s", line.c_str()); + } + if (file != NULL) + fprintf(file, "%s\n", listOfGroups.c_str()); + else + ArLog::log(ArLog::Terse, "%s", listOfGroups.c_str()); + myDataMutex.unlock(); +} + + +/// +///=========================================================================/// +/// Function: setGroupDescription /// +/// Created: 17-Nov-2005 /// +/// Purpose: To permit the user to update the Command Group Descriptions./// +/// Notes: /// +/// /// +/// Revision History: /// +/// WHEN WHO WHAT and/or WHY /// +/// 17-Nov-2005 NJ Created this function. /// +/// /// +///=========================================================================/// +/// +AREXPORT void ArServerBase::setGroupDescription(const char *cmdGrpName, const char *cmdGrpDesc) +{ + myDataMutex.lock(); + myGroupDescription.insert(std::pair(cmdGrpName, cmdGrpDesc)); + myDataMutex.unlock(); +} + + + + + +// Created: 17-Nov-2005 // +// Purpose: +// Notes: // +// Assumption: Command Group Name Map exists already. // +// // +// Revision History: // +// WHEN WHO WHAT and/or WHY // +// 17-Nov-2005 NJ Created this function. // + +AREXPORT void ArServerBase::logGroupDescriptions(void) +{ + // -- This wrapper insures that NULL is the only input passed to the + // logCommandGroupNamesToFile routine. + // This is used if the log is desired over a filename. + logGroupDescriptionsToFile(NULL); // NULL is the only value passed. +} + +AREXPORT void ArServerBase::logGroupDescriptionsToFile(const char *fileName) +{ + myDataMutex.lock(); + std::map::iterator d_itr; // establish map iterator + char line[1024]; + FILE *file = NULL; + if (fileName != NULL) + file = ArUtil::fopen(fileName, "w"); // open file if exists + + // -- Assemble output strings and send to file or log + for (d_itr = myGroupDescription.begin(); d_itr != myGroupDescription.end(); d_itr++) + { + snprintf(line, sizeof(line), "%-29s %s", (*d_itr).first.c_str(), (*d_itr).second.c_str()); + + if (file != NULL) + fprintf(file, "%s\n", line); // send string to file + else + ArLog::log(ArLog::Terse, "%s", line); // send string to log + } + if (fileName != NULL) // task complete notification + fclose (file); + myDataMutex.unlock(); +} + + + +/** + Text string that is the key required when using user and password + information... this is NOT used if there is no user and password + information. +**/ +AREXPORT void ArServerBase::setServerKey(const char *serverKey) +{ + myDataMutex.lock(); + // if this is setting it to empty and its already empty don't print + // a message + if ((serverKey == NULL || serverKey[0] == '\0') && myServerKey.size() > 0) + ArLog::log(ArLog::Normal, "Clearing server key"); + if (serverKey != NULL && serverKey[0] != '\0') + ArLog::log(ArLog::Normal, "Setting new server key"); + if (serverKey != NULL) + myServerKey = serverKey; + else + myServerKey = ""; + myDataMutex.unlock(); +} + +AREXPORT void ArServerBase::rejectSinceUsingCentralServer( + const char *centralServerIPString) +{ + myDataMutex.lock(); + myRejecting = 2; + myRejectingString = centralServerIPString; + myDataMutex.unlock(); +} + + + +AREXPORT void ArServerBase::enforceProtocolVersion(const char *protocolVersion) +{ + myDataMutex.lock(); + if (protocolVersion != NULL) + myEnforceProtocolVersion = protocolVersion; + else + myEnforceProtocolVersion = ""; + myDataMutex.unlock(); + ArLog::log(ArLog::Normal, "%sNew enforceProtocolVersionSet", myLogPrefix.c_str()); +} + +AREXPORT void ArServerBase::enforceType(ArServerCommands::Type type) +{ + myDataMutex.lock(); + myEnforceType = type; + myDataMutex.unlock(); + ArLog::log(ArLog::Normal, "%sNew enforce type: %s", + myLogPrefix.c_str(), ArServerCommands::toString(type)); + +} + +/** + Sets up the backup timeout, if there are packets to send to clients + and they haven't been sent for longer than this then the connection + is closed. Less than 0 means this won't happen. If this is + positive but less than 5 seconds then 5 seconds is used. +**/ +AREXPORT void ArServerBase::setBackupTimeout(double timeoutInMins) +{ + myBackupTimeoutMutex.lock(); + myBackupTimeout = timeoutInMins; + myNewBackupTimeout = true; + myBackupTimeoutMutex.unlock(); + + /* Taking this out, since it can cause deadlocks in some central + * server circumstances... and doing it next time through is good enough + + std::list::iterator it; +// ArLog::log(ArLog::Normal, "Setting server base backup time to %g\n", myBackupTimeout); + myClientsMutex.lock(); + for (it = myClients.begin(); it != myClients.end(); it++) + (*it)->setBackupTimeout(myBackupTimeout); + myClientsMutex.unlock(); + */ +} + +AREXPORT void ArServerBase::logTracking(bool terse) +{ + std::list::iterator lit; + + myClientsMutex.lock(); + + for (lit = myClients.begin(); lit != myClients.end(); ++lit) + (*lit)->logTracking(terse); + + ArLog::log(ArLog::Terse, ""); + + if (!terse) + { + ArLog::log(ArLog::Terse, "%-85s %7ld udp rcvs %10ld udp B", + "Low Level UDP Received (all conns)", myUdpSocket.getRecvs(), + myUdpSocket.getBytesRecvd()); + ArLog::log(ArLog::Terse, "%-85s %7ld udp snds %10ld udp B", + "Low Level UDP Sent (all conns)", myUdpSocket.getSends(), + myUdpSocket.getBytesSent()); + + ArLog::log(ArLog::Terse, ""); + } + myClientsMutex.unlock(); +} + +AREXPORT void ArServerBase::resetTracking(void) +{ + std::list::iterator lit; + + myClientsMutex.lock(); + + for (lit = myClients.begin(); lit != myClients.end(); ++lit) + (*lit)->resetTracking(); + myClientsMutex.unlock(); + myDataMutex.lock(); + myUdpSocket.resetTracking(); + myDataMutex.unlock(); +} + +AREXPORT const ArServerUserInfo* ArServerBase::getUserInfo(void) const +{ + return myUserInfo; +} + +AREXPORT void ArServerBase::setUserInfo(const ArServerUserInfo *userInfo) +{ + myDataMutex.lock(); + myUserInfo = userInfo; + myDataMutex.unlock(); +} + +/** + @param command the command name as a string + + @param frequency the frequency to get the data, > 0 == + milliseconds, -1 == on broadcast, -2 == never... This function + won't set the value to anything slower than has already been + requested +*/ +AREXPORT bool ArServerBase::internalSetDefaultFrequency( + const char *command, int frequency) +{ + + + // first find our number so each client doesn't have to + std::map::iterator it; + ArServerData *data = NULL; + unsigned int commandNumber = 0; + + myClientsMutex.lock(); + myDataMutex.lock(); + + for (it = myDataMap.begin(); it != myDataMap.end(); it++) + { + if (!strcmp((*it).second->getName(), command)) + { + data = (*it).second; + commandNumber = data->getCommand(); + } + } + + if (commandNumber == 0) + { + myDataMutex.unlock(); + myClientsMutex.unlock(); + ArLog::log(ArLog::Normal, + "%s::setDefaultFrequency: No command of name %s", + myServerName.c_str(), command); + return false; + } + + int freq = -2; + if (myDefaultFrequency.find(commandNumber) != myDefaultFrequency.end()) + freq = myDefaultFrequency[commandNumber]; + + // if the freq is an interval and so is this but this + // is a smaller interval + if (frequency >= 0 && (freq < 0 || (freq >= 0 && frequency < freq))) + freq = frequency; + // if this just wants the data when pushed but freq is still + // at never then set it to when pushed + else if (frequency == -1 && freq == -2) + freq = -1; + + myDefaultFrequency[commandNumber] = freq; + + data->callRequestChangedFunctor(); + + ArLog::log(ArLog::Normal, "%s: Set default frequency for %s (%u) to %d", + myServerName.c_str(), command, commandNumber, freq); + + myDataMutex.unlock(); + myClientsMutex.unlock(); + return true; +} + + +/** + @param command the command number, you can use findCommandFromName + + @param internalCall whether its an internal call or not (whether to + lock or not) + + @return returns lowest amount of time requested for this packet, + note that 0 and higher means thats how often it was asked for, -1 + means nothing requested the data at an interval but wants it when + its been pushed, and -2 means that nothing wants the data +**/ + +AREXPORT long ArServerBase::getFrequency(unsigned int command, + bool internalCall) +{ + std::list::iterator it; + long ret = -2; + long clientFreq; + + if (!internalCall) + myClientsMutex.lock(); + + // if we have a default frequency start with that + if (myDefaultFrequency.find(command) != myDefaultFrequency.end()) + ret = myDefaultFrequency[command]; + + for (it = myClients.begin(); it != myClients.end(); it++) + { + clientFreq = (*it)->getFrequency(command); + // if the ret is an interval and so is this client but this client + // is a smalelr interval + if (clientFreq >= 0 && (ret < 0 || (ret >= 0 && clientFreq < ret))) + ret = clientFreq; + // if this client just wants the data when pushed but ret is still + // at never then set it to when pushed + else if (clientFreq == -1 && ret == -2) + ret = -1; + } + + if (!internalCall) + myClientsMutex.unlock(); + + return ret; +} + +/** + Additional data flags to be added to addData calls (these are added + in with what is there). You can do multiple flags by separating + them with a | character. + **/ +AREXPORT void ArServerBase::setAdditionalDataFlags( + const char *additionalDataFlags) +{ + myDataMutex.lock(); + if (additionalDataFlags == NULL || additionalDataFlags[0] == '\0') + myAdditionalDataFlags = ""; + else + myAdditionalDataFlags = additionalDataFlags; + myDataMutex.unlock(); +} + + +AREXPORT bool ArServerBase::dataHasFlag(const char *name, + const char *dataFlag) +{ + unsigned int command; + if ((command = findCommandFromName(name)) == 0) + { + ArLog::log(ArLog::Verbose, + "ArServerBase::dataHasFlag: %s is not data that is on the server", + name); + return false; + } + + return dataHasFlagByCommand(findCommandFromName(name), dataFlag); +} + +AREXPORT bool ArServerBase::dataHasFlagByCommand(unsigned int command, + const char *dataFlag) +{ + std::map::iterator dIt; + bool ret; + + myDataMutex.lock(); + if ((dIt = myDataMap.find(command)) == myDataMap.end()) + ret = false; + else + ret = (*dIt).second->hasDataFlag(dataFlag); + myDataMutex.unlock(); + + return ret; +} + +AREXPORT unsigned int ArServerBase::getTcpPort(void) +{ + return myTcpPort; +} + +AREXPORT unsigned int ArServerBase::getUdpPort(void) +{ + return myUdpPort; +} + +AREXPORT const char *ArServerBase::getOpenOnIP(void) +{ + if (myOpenOnIP.empty()) + return NULL; + else + return myOpenOnIP.c_str(); +} + +bool ArServerBase::processFile(void) +{ + setBackupTimeout(myBackupTimeout); + return true; +} + +AREXPORT void ArServerBase::identGetConnectionID(ArServerClient *client, + ArNetPacket *packet) +{ + ArNetPacket sending; + ArServerClientIdentifier identifier = client->getIdentifier(); + + // if there is an id then just send that ConnectionID + if (identifier.getConnectionID() != 0) + { + sending.uByte4ToBuf(identifier.getConnectionID()); + client->sendPacketTcp(&sending); + } + // otherwise we need to find an ConnectionID for it (don't lock while doing + // this since the client bases can only be active from within the + // server base) + + // we have the id number, but make sure it isn't already taken + // (maybe we'll wrap a 4 byte number, but its unlikely, but better + // safe than sorry) + bool duplicate; + std::list::iterator it; + bool hitZero; + + // this does both the stepping to find a good ID, the for also winds + // up incrementing it after we find one, which I don't like since + // its a side effect, but oh well + for (duplicate = true, hitZero = false; + duplicate; + myConnectionNumber++) + { + if (myConnectionNumber == 0) + { + // if we hit zero once already and are back there, just use 0 + // for an id + if (hitZero) + { + ArLog::log(ArLog::Terse, "ConnectionID hit zero again, giving up"); + break; + } + ArLog::log(ArLog::Terse, "ConnectionID lookup wrapped"); + // otherwise set that we hit zero and go to 1 + hitZero = true; + myConnectionNumber++; + } + + // see if we have any duplicates + for (it = myClients.begin(); + it != myClients.end(); + it++) + { + if (myConnectionNumber != (*it)->getIdentifier().getConnectionID()) + { + duplicate = false; + break; + } + } + } + + identifier.setConnectionID(myConnectionNumber); + client->setIdentifier(identifier); + + sending.uByte4ToBuf(identifier.getConnectionID()); + client->sendPacketTcp(&sending); +} + +AREXPORT void ArServerBase::identSetConnectionID(ArServerClient *client, ArNetPacket *packet) +{ + ArServerClientIdentifier identifier = client->getIdentifier(); + identifier.setConnectionID(packet->bufToUByte4()); + client->setIdentifier(identifier); +} + +AREXPORT void ArServerBase::identSetSelfIdentifier(ArServerClient *client, + ArNetPacket *packet) +{ + char buf[32000]; + packet->bufToStr(buf, sizeof(buf)); + + ArServerClientIdentifier identifier = client->getIdentifier(); + identifier.setSelfIdentifier(buf); + client->setIdentifier(identifier); +} + +AREXPORT void ArServerBase::identSetHereGoal(ArServerClient *client, ArNetPacket *packet) +{ + char buf[32000]; + packet->bufToStr(buf, sizeof(buf)); + + ArServerClientIdentifier identifier = client->getIdentifier(); + identifier.setHereGoal(buf); + client->setIdentifier(identifier); +} + +AREXPORT void ArServerBase::handleStartRequestTransaction(ArServerClient *client, ArNetPacket *packet) +{ + client->startRequestTransaction(); + + ArLog::log(ArLog::Verbose, + "ArServerBase::handleStartRequestTransaction() from %s complete", + client->getIPString()); + +} // end method handleStartRequestTransaction + + +AREXPORT void ArServerBase::handleEndRequestTransaction(ArServerClient *client, ArNetPacket *packet) +{ + if (client->endRequestTransaction()) { + ArLog::log(ArLog::Verbose, + "ArServerBase::handleEndRequestTransaction() from %s complete", + client->getIPString()); + + } + else { + ArLog::log(ArLog::Verbose, + "ArServerBase::handleEndRequestTransaction() error from %s" , + client->getIPString()); + + } + + +} // end method handleEndRequestTransaction + + +AREXPORT int ArServerBase::getRequestTransactionCount() +{ + myClientsMutex.lock(); + int c = 0; + for (std::list::iterator iter = myClients.begin(); + iter != myClients.end(); + iter++) { + ArServerClient *client = *iter; + if (client != NULL) { + c += client->getRequestTransactionCount(); + } + + } // end for each client + + myClientsMutex.unlock(); + + return c; + +} // end method getRequestTransactionCount + + +AREXPORT void ArServerBase::closeConnectionID(ArTypes::UByte4 idNum) +{ + if (idNum == 0) + { + ArLog::log(ArLog::Verbose, "%s: Cannot close connection to id 0", + myLogPrefix.c_str()); + return; + } + + std::list::iterator it; + // for speed we'd use a list of iterators and erase, but for clarity + // this is easier and this won't happen that often + //std::list removeList; + ArServerClient *client; + + myClientsMutex.lock(); + for (it = myClients.begin(); it != myClients.end(); ++it) + { + client = (*it); + if (client->getIdentifier().getConnectionID() == idNum) + { + client->forceDisconnect(true); + myRemoveSetMutex.lock(); + myRemoveSet.insert(client); + myRemoveSetMutex.unlock(); + } + } + /* + while ((it = removeList.begin()) != removeList.end()) + { + client = (*it); + if (myDebugLogging) + ArLog::log(ArLog::Normal, + "%sClosing (by connection id) connection to %s", + myLogPrefix.c_str(), client->getIPString()); + myClients.remove(client); + for (std::list *>::iterator rci = myClientRemovedCallbacks.begin(); + rci != myClientRemovedCallbacks.end(); + rci++) { + if (*rci) { + (*rci)->invoke(client); + } + } + + delete client; + removeList.pop_front(); + } + */ + myClientsMutex.unlock(); +} + +AREXPORT void ArServerBase::logConnections(const char *prefix) +{ + std::list::iterator it; + ArServerClient *client; + + myClientsMutex.lock(); + + ArLog::log(ArLog::Normal, "%sConnections for %s (%d now, %d max)", prefix, + myServerName.c_str(), myClients.size(), myMostClients); + + for (it = myClients.begin(); it != myClients.end(); ++it) + { + client = (*it); + ArLog::log(ArLog::Normal, "%s\t%s", prefix, client->getIPString()); + } + + myClientsMutex.unlock(); +} +/// Sets debug logging +AREXPORT void ArServerBase::setDebugLogging(bool debugLogging) +{ + myDebugLogging = debugLogging; + if (myDebugLogging) + myVerboseLogLevel = ArLog::Normal; + else + myVerboseLogLevel = ArLog::Verbose; +} + +AREXPORT bool ArServerBase::getDebugLogging(void) +{ + return myDebugLogging; +} + +AREXPORT int ArServerBase::getMostClients(void) +{ + return myMostClients; +} + +void ArServerBase::slowIdleCallback(void) +{ + if (!myOpened) + { + ArUtil::sleep(myLoopMSecs); + return; + } + + bool isRequestTransactionInProgress = (getRequestTransactionCount() > 0); + + std::list::iterator it; + ArServerClient *client = NULL; + + std::list::iterator cIt; + ArFunctor *functor = NULL; + + if (myAllowSlowPackets) + { + myProcessingSlowIdleMutex.lock(); + //printf("SLOW...\n"); + for (it = myClients.begin(); it != myClients.end(); ++it) + { + client = (*it); + if (!client->slowPacketCallback()) + { + client->forceDisconnect(true); + myRemoveSetMutex.lock(); + myRemoveSet.insert(client); + myRemoveSetMutex.unlock(); + } + } + //printf("done slow...\n"); + myProcessingSlowIdleMutex.unlock(); + } + + int activityTime = ArServerMode::getActiveModeActivityTimeSecSince(); + + // This check is solely for the purpose of logging a message if idle + // processing is being delayed because a request transaction is still + // in progress. (Could/should be improved so that it does not spam.) + // + // The if statement is similar to the following one -- except with + // isRequestTransactionInProgress inverted. + if (myAllowIdlePackets && + (activityTime < 0 || activityTime > 1) && + isRequestTransactionInProgress) { + ArLog::log(ArLog::Verbose, + "ArServerBase::slowIdleCallback() waiting until request transaction complete"); + } // end if + + + // Don't process idle packets until all "request transactions" are complete. + // These are multi-step handshake sequences that should not be interrupted. + // + if (myAllowIdlePackets && + (activityTime < 0 || activityTime > 1) && + !isRequestTransactionInProgress) + { + /* + if (idleProcessingPending() && ArServerMode::getActiveMode() != NULL) + ArLog::log(myVerboseLogLevel, "Idle processing pending, idle %ld msecs", + ArServerMode::getActiveMode()->getActivityTime().mSecSince()); + */ + + //printf("IDLE...\n"); + + myProcessingSlowIdleMutex.lock(); + + myIdleCallbacksMutex.lock(); + if (myHaveIdleCallbacks) + { + while ((cIt = myIdleCallbacks.begin()) != myIdleCallbacks.end()) + { + functor = (*cIt); + myIdleCallbacks.pop_front(); + myIdleCallbacksMutex.unlock(); + if (functor->getName() != NULL && functor->getName()[0] != '\0') + ArLog::log(myVerboseLogLevel, "Calling idle callback functor %s", + functor->getName()); + else + ArLog::log(myVerboseLogLevel, + "Calling anonymous idle callback functor"); + functor->invoke(); + myIdleCallbacksMutex.lock(); + } + myHaveIdleCallbacks = false; + } + myIdleCallbacksMutex.unlock(); + + for (it = myClients.begin(); it != myClients.end(); ++it) + { + client = (*it); + if (!client->idlePacketCallback()) + { + client->forceDisconnect(true); + myRemoveSetMutex.lock(); + myRemoveSet.insert(client); + myRemoveSetMutex.unlock(); + } + } + //printf("done idle...\n"); + myProcessingSlowIdleMutex.unlock(); + } + ArUtil::sleep(myLoopMSecs); +} + +/** + * Call this method to delay the current thread after a packet has been sent. + * This allows the packet to be transmitted before any subsequent action. + * + * If the call is made in the main server thread, then loop once will be called + * until the specified time has passed. If the call is made in the idle thread, + * then ArUtil::sleep is used. (Note that if ArUtil::sleep() were called in the + * main thread, then the packet would not actually be transmitted until after + * the sleep exits.) +**/ +void ArServerBase::sleepAfterSend(int msecDelay) +{ + if (msecDelay < 0) { + ArLog::log(ArLog::Normal, + "ArServerBase::sleepAfterSend() unexpected msecDelay = %i", + msecDelay); + return; + } + + if (ArThread::self() == mySlowIdleThread) { + IFDEBUG(ArLog::log(ArLog::Normal, + "ArServerBase::sleepAfterSend() about to sleep in idle thread")); + + ArUtil::sleep(msecDelay); + + IFDEBUG(ArLog::log(ArLog::Normal, + "ArServerBase::sleepAfterSend() finished sleep in idle thread")); + } + else { // not idle thread + + IFDEBUG(ArLog::log(ArLog::Normal, + "ArServerBase::sleepAfterSend() about to loop in main thread")); + + ArTime startTime; + while (startTime.mSecSince() < msecDelay) { + loopOnce(); + ArUtil::sleep(1); + } // end while keep delaying + + IFDEBUG(ArLog::log(ArLog::Normal, + "ArServerBase::sleepAfterSend() finished loop in main thread")); + + } + +} // end method sleepAfterSend + + +AREXPORT bool ArServerBase::hasSlowPackets(void) +{ + return myHaveSlowPackets; +} + +AREXPORT bool ArServerBase::hasIdlePackets(void) +{ + return myHaveIdlePackets; +} + +AREXPORT bool ArServerBase::hasIdleCallbacks(void) +{ + return myHaveIdleCallbacks; +} + +AREXPORT bool ArServerBase::idleProcessingPending(void) +{ + return myHaveIdleCallbacks || myHaveIdlePackets; +} + +AREXPORT void ArServerBase::netIdleProcessingPending(ArServerClient *client, + ArNetPacket *packet) +{ + ArNetPacket sendingPacket; + + if (idleProcessingPending()) + sendingPacket.byteToBuf(1); + else + sendingPacket.byteToBuf(0); + + client->sendPacketTcp(&sendingPacket); +} + +AREXPORT bool ArServerBase::allowingIdlePackets(void) +{ + return myAllowIdlePackets; +} + +/** + Note that if idle packets are not allowed then idle callbacks will + not work. + + @return true if the callback was added, false if not +**/ +AREXPORT bool ArServerBase::addIdleSingleShotCallback(ArFunctor *functor) +{ + if (!myAllowIdlePackets) + return false; + + myIdleCallbacksMutex.lock(); + myIdleCallbacks.push_back(functor); + myHaveIdleCallbacks = true; + if (functor->getName() != NULL && functor->getName()[0] != '\0') + ArLog::log(myVerboseLogLevel, + "Adding idle singleshot callback functor %s", + functor->getName()); + else + ArLog::log(myVerboseLogLevel, + "Adding anonymous idle singleshot callback functor"); + myIdleCallbacksMutex.unlock(); + return true; +} + +AREXPORT void ArServerBase::internalSetNumClients(int numClients) +{ + myUsingOwnNumClients = false; + myNumClients = numClients; +} + + +AREXPORT void ArServerBase::internalLockup(void) +{ + ArLog::log(ArLog::Normal, "%s locking up by request", myServerName.c_str()); + myDataMutex.lock(); +} + +ArServerBase::SlowIdleThread::SlowIdleThread(ArServerBase *serverBase) +{ + setThreadName("ArServerBase::SlowIdleThread"); + myServerBase = serverBase; + runAsync(); +} + +ArServerBase::SlowIdleThread::~SlowIdleThread() +{ + +} + +void * ArServerBase::SlowIdleThread::runThread(void *arg) +{ + threadStarted(); + + while (getRunning()) + { + myServerBase->slowIdleCallback(); + } + + threadFinished(); + return NULL; +} diff --git a/Legacy/Aria/ArNetworking/src/ArServerClient.cpp b/Legacy/Aria/ArNetworking/src/ArServerClient.cpp new file mode 100644 index 0000000..347b403 --- /dev/null +++ b/Legacy/Aria/ArNetworking/src/ArServerClient.cpp @@ -0,0 +1,1563 @@ +#include "Aria.h" +#include "ArExport.h" +#include "ArServerClient.h" +#include "ArServerCommands.h" +#include "ArClientCommands.h" +#include "ArServerData.h" +#include "ArServerUserInfo.h" + +/** + In addition to the normal contructorness this contructor starts the + connection between the server and the client going + + @param tcpSocket the socket that has been established between the + client and the server + + @param udpPort the udp port the server is using + + @param authKey this authKey must be presented by the client to the + server on the server's UDP port for the client to be recognized by + the server + + @param introKey this key must be presented by the server to the + client so that the client will recognize the server + + @param sendUdpCallback the callback used to send Udp packets (since + the udp packets need to be sent from the server's udp port and the + serverclient here doesn't have one) + + @param dataMap the map between command numbers and the command data + + @param passwordKey the key (just plain text thats used in an md5 + along with the serverKey and the password over on the client side) + that was generated for the passwords on this exact connection + + @param serverKey the key (just plain text thats used in an md5 + along with the passwordKey and the password over on the client + side) that should be used for any connections to this server + + @param debugLogging If true, log some debug messages + + @param logPasswordFailureVerbosely If true, log password errors at + ArLog::Verbose + level, if false, log them at ArLog::Normal level. + + @param userInfo the pointer to the item that holds our usernames + and passwords + + @param rejecting + + @param rejectingString string to reject with + **/ + +AREXPORT ArServerClient::ArServerClient( + ArSocket *tcpSocket, unsigned int udpPort, long authKey, + long introKey, ArRetFunctor2 *sendUdpCallback, + std::map *dataMap, + const char *passwordKey, const char *serverKey, + const ArServerUserInfo *userInfo, int rejecting, + const char *rejectingString, bool debugLogging, + const char *serverClientName, bool logPasswordFailureVerbosely, + bool allowSlowPackets, bool allowIdlePackets, + const char *enforceProtocolVersion, + ArServerCommands::Type enforceType) : + + myProcessPacketCB(this, &ArServerClient::processPacket, NULL, true), + + myRequestTransactionCount(0), + myRequestTransactionMutex() + +{ + ArNetPacket packet; + + // set our default to no command + pushCommand(0); + + myAuthKey = authKey; + myIntroKey = introKey; + myTcpSocket.transfer(tcpSocket); + myTcpSocket.setCloseCallback(tcpSocket->getCloseCallback()); + myTcpSocket.setNonBlock(); + myTcpReceiver.setSocket(&myTcpSocket); + myTcpReceiver.setProcessPacketCB(&myProcessPacketCB); + myTcpSender.setSocket(&myTcpSocket); + + mySendUdpCB = sendUdpCallback; + myDataMap = dataMap; + if (udpPort == 0) + myTcpOnly = true; + else + myTcpOnly = false; + mySentTcpOnly = myTcpOnly; + + myUserInfo = userInfo; + myPasswordKey = passwordKey; + myServerKey = serverKey; + myRejecting = rejecting; + if (rejectingString != NULL) + myRejectingString = rejectingString; + + myDebugLogging = debugLogging; + if (myDebugLogging) + myVerboseLogLevel = ArLog::Normal; + else + myVerboseLogLevel = ArLog::Verbose; + + myTcpSender.setDebugLogging(myDebugLogging); + + myLogPrefix = serverClientName; + myLogPrefix += ": "; + myTcpSender.setLoggingPrefix(myLogPrefix.c_str()); + myTcpReceiver.setLoggingPrefix(myLogPrefix.c_str()); + + myLogPasswordFailureVerbosely = logPasswordFailureVerbosely; + + if (enforceProtocolVersion != NULL) + myEnforceProtocolVersion = enforceProtocolVersion; + else + myEnforceProtocolVersion = ""; + myEnforceType = enforceType; + + mySlowPacketsMutex.setLogName("ArServerClient::mySlowPacketsMutex"); + myIdlePacketsMutex.setLogName("ArServerClient::myIdlePacketsMutex"); + + myAllowSlowPackets = allowSlowPackets; + myAllowIdlePackets = allowIdlePackets; + + myRequestTransactionMutex.setLogName("ArServerClient::myRequestTransactionMutex"); + + setIdentifier(ArServerClientIdentifier()); + internalSwitchState(STATE_SENT_INTRO); + + packet.empty(); + packet.setCommand(ArServerCommands::INTRODUCTION); + packet.strToBuf("alpha"); + packet.uByte2ToBuf(udpPort); + packet.uByte4ToBuf(myAuthKey); + packet.uByte4ToBuf(myIntroKey); + packet.strToBuf(myPasswordKey.c_str()); + packet.strToBuf(myEnforceProtocolVersion.c_str()); + sendPacketTcp(&packet); + + mySlowIdleThread = NULL; + + myHaveSlowPackets = false; + myHaveIdlePackets = false; + + myCreationTime.setToNow(); + + resetTracking(); +} + +AREXPORT ArServerClient::~ArServerClient() +{ + myTcpReceiver.setSocket(NULL); + myTcpReceiver.setProcessPacketCB(NULL); + myTcpSocket.close(); + + /// MPL fixing a memory leak + // new way to get the request change functor called + std::list::iterator it; + ArServerClientData *data; + ArServerData *serverData; + while ((it = myRequested.begin()) != myRequested.end()) + { + data = (*it); + serverData = (*it)->getServerData(); + myRequested.pop_front(); + delete data; + serverData->callRequestChangedFunctor(); + } + /* old way + ArUtil::deleteSet(myRequested.begin(), myRequested.end()); + myRequested.clear(); + */ + ArUtil::deleteSetPairs(myTrackingSentMap.begin(), + myTrackingSentMap.end()); + myTrackingSentMap.clear(); + + ArUtil::deleteSetPairs(myTrackingReceivedMap.begin(), + myTrackingReceivedMap.end()); + myTrackingReceivedMap.clear(); + + ArUtil::deleteSet(mySlowPackets.begin(), mySlowPackets.end()); + mySlowPackets.clear(); + ArUtil::deleteSet(myIdlePackets.begin(), myIdlePackets.end()); + myIdlePackets.clear(); + +} + +void ArServerClient::internalSwitchState(ServerState state) +{ + myState = state; + myStateStart.setToNow(); + if (myDebugLogging) + ArLog::log(ArLog::Normal, "%sSwitching to state %d", + myLogPrefix.c_str(), (int)state); +} + +AREXPORT void ArServerClient::setBackupTimeout(double timeoutInMins) +{ + myBackupTimeout = timeoutInMins; + myTcpSender.setBackupTimeout(myBackupTimeout); +} + +AREXPORT bool ArServerClient::tcpCallback(void) +{ + if (myState == STATE_REJECTED) + { + myTcpSender.sendData(); + ArUtil::sleep(10); + return false; + } + + if (myState == STATE_DISCONNECTED && (myHaveSlowPackets || + myHaveIdlePackets)) + return true; + + if (myState == STATE_DISCONNECTED) + return false; + + if (myState == STATE_SENT_INTRO && myStateStart.secSince() >= 60) + { + ArLog::log(myVerboseLogLevel, "%sTook too long for %s to connect", + myLogPrefix.c_str(), getIPString()); + return false; + } + + if (myTcpOnly && !mySentTcpOnly) + { + mySentTcpOnly = true; + ArNetPacket sending; + sending.setCommand(ArServerCommands::TCP_ONLY); + sendPacketTcp(&sending); + } + + if (!myTcpReceiver.readData()) + { + ArLog::log(myVerboseLogLevel, "%sTrouble receiving tcp data from %s", + myLogPrefix.c_str(), getIPString()); + internalSwitchState(STATE_DISCONNECTED); + return tcpCallback(); + //return false; + } + if (!myTcpSender.sendData()) + { + ArLog::log(myVerboseLogLevel, "%sTrouble sending tcp data to %s", + myLogPrefix.c_str(), getIPString()); + internalSwitchState(STATE_DISCONNECTED); + return tcpCallback(); + //return false; + } + + return true; +} + +AREXPORT void ArServerClient::handleRequests(void) +{ + if (myState != STATE_CONNECTED) + return; + + std::list::iterator it; + ArServerClientData *data; + ArServerData *serverData; + ArTime lastSent; + + // walk through our list + for (it = myRequested.begin(); it != myRequested.end(); ++it) + { + data = (*it); + lastSent = data->getLastSent(); + // see if this needs to be called + if (data->getMSec() != -1 && + (data->getMSec() == 0 || lastSent.mSecSince() > data->getMSec())) + { + serverData = data->getServerData(); + // call it, then set it so we know we did + pushCommand(serverData->getCommand()); + pushForceTcpFlag(false); + if (serverData->getFunctor() != NULL) + serverData->getFunctor()->invoke(this, data->getPacket()); + popCommand(); + popForceTcpFlag(); + data->setLastSentToNow(); + } + } +} + + +void ArServerClient::sendListPacket(void) +{ + ArNetPacket packet; + std::map::iterator it; + unsigned int count; + unsigned int shortLen; + unsigned int longLen; + ArServerData *serverData; + + // First we send a list of numbers, names and descriptions + packet.setCommand(ArServerCommands::LIST); + + // number of entries (we'll overwrite it later with the right number) + shortLen = packet.getLength(); + packet.uByte2ToBuf(0); + // loop through the data to build the packet + for (it = myDataMap->begin(), count = 0; it != myDataMap->end(); it++) + { + serverData = (*it).second; + if (myUserInfo == NULL || + serverData->getCommandGroup() == NULL || + serverData->getCommandGroup()[0] == '\0' || + myGroups.count(serverData->getCommandGroup()) != 0 || + myGroups.count("all") != 0) + { + count++; + packet.uByte2ToBuf(serverData->getCommand()); + packet.strToBuf(serverData->getName()); + packet.strToBuf(serverData->getDescription()); + } + } + // put the real number of entries in the right spot + longLen = packet.getLength(); + packet.setLength(shortLen); + packet.uByte2ToBuf(count); + packet.setLength(longLen); + + sendPacketTcp(&packet); + + // then we send a list of the arguments and returns... they aren't + // combined so that the packet structure doesn't need to change + packet.empty(); + packet.setCommand(ArServerCommands::LISTARGRET); + + // number of entries (we'll overwrite it later with the right number) + shortLen = packet.getLength(); + packet.uByte2ToBuf(0); + + // loop through the data to build the packet + for (it = myDataMap->begin(), count = 0; it != myDataMap->end(); it++) + { + serverData = (*it).second; + if (myUserInfo == NULL || + serverData->getCommandGroup() == NULL || + serverData->getCommandGroup()[0] == '\0' || + myGroups.count(serverData->getCommandGroup()) != 0 || + myGroups.count("all") != 0) + { + count++; + packet.uByte2ToBuf(serverData->getCommand()); + packet.strToBuf(serverData->getArgumentDescription()); + packet.strToBuf(serverData->getReturnDescription()); + } + + } + // put the real number of entries in the right spot + longLen = packet.getLength(); + packet.setLength(shortLen); + packet.uByte2ToBuf(count); + packet.setLength(longLen); + sendPacketTcp(&packet); + + + // then we send a list of command groups... they aren't + // combined so that the packet structure doesn't need to change + packet.empty(); + packet.setCommand(ArServerCommands::LISTGROUPANDFLAGS); + + // number of entries (we'll overwrite it later with the right number) + shortLen = packet.getLength(); + packet.uByte2ToBuf(0); + + // loop through the data to build the packet + for (it = myDataMap->begin(), count = 0; it != myDataMap->end(); it++) + { + serverData = (*it).second; + if (myUserInfo == NULL || + serverData->getCommandGroup() == NULL || + serverData->getCommandGroup()[0] == '\0' || + myGroups.count(serverData->getCommandGroup()) != 0 || + myGroups.count("all") != 0) + { + count++; + packet.uByte2ToBuf(serverData->getCommand()); + packet.strToBuf(serverData->getCommandGroup()); + packet.strToBuf(serverData->getDataFlagsString()); + } + + } + // put the real number of entries in the right spot + longLen = packet.getLength(); + packet.setLength(shortLen); + packet.uByte2ToBuf(count); + packet.setLength(longLen); + sendPacketTcp(&packet); +} + +AREXPORT void ArServerClient::processPacket(ArNetPacket *packet, bool tcp) +{ + std::string str; + struct sockaddr_in sin; + unsigned int clientUdpPort; + ArNetPacket retPacket; + + //printf("Command number %d\n", packet->getCommand()); + // if we're in intro mode and received back the intro + if (myState == STATE_SENT_INTRO && + packet->getCommand() == ArClientCommands::INTRODUCTION) + { + char user[512]; + unsigned char password[16]; + char enforceProtocolVersion[256]; + clientUdpPort = packet->bufToUByte2(); + packet->bufToStr(user, sizeof(user)); + packet->bufToData((char *)password, 16); + packet->bufToStr(enforceProtocolVersion, sizeof(enforceProtocolVersion)); + ArServerCommands::Type clientType = (ArServerCommands::Type)packet->bufToByte(); + + if (myRejecting != 0) + { + retPacket.empty(); + retPacket.setCommand(ArServerCommands::REJECTED); + retPacket.byte2ToBuf(myRejecting); + retPacket.strToBuf(myRejectingString.c_str()); + sendPacketTcp(&retPacket); + ArLog::log(ArLog::Normal, + "%sRejected connection from %s (%d, %s)", + myLogPrefix.c_str(), getIPString(), myRejecting, + myRejectingString.c_str()); + internalSwitchState(STATE_REJECTED); + return; + } + + if (!myEnforceProtocolVersion.empty() && + strcmp(enforceProtocolVersion, myEnforceProtocolVersion.c_str()) != 0) + { + retPacket.empty(); + retPacket.setCommand(ArServerCommands::REJECTED); + retPacket.byte2ToBuf(4); + retPacket.strToBuf("Server rejecting client connection since protocol version does not match"); + sendPacketTcp(&retPacket); + ArLog::log(ArLog::Normal, "%sServer rejecting client connection since protocol version does not match", myLogPrefix.c_str()); + internalSwitchState(STATE_REJECTED); + } + + if (myEnforceType != ArServerCommands::TYPE_UNSPECIFIED && + (myEnforceType != clientType || + myEnforceType == ArServerCommands::TYPE_NONE)) + { + retPacket.empty(); + retPacket.setCommand(ArServerCommands::REJECTED); + retPacket.byte2ToBuf(6); + retPacket.strToBuf("Server rejecting client connection since type (real or sim) does not match (but is specified)"); + sendPacketTcp(&retPacket); + ArLog::log(ArLog::Normal, "%sServer rejecting client connection since type (real or sim) does not match (but is specified)", myLogPrefix.c_str()); + internalSwitchState(STATE_REJECTED); + } + + // if user info is NULL we're not checking passwords + if (myUserInfo != NULL && + !myUserInfo->matchUserPassword(user, password, myPasswordKey.c_str(), + myServerKey.c_str(), + myLogPasswordFailureVerbosely)) + { + retPacket.empty(); + retPacket.setCommand(ArServerCommands::REJECTED); + retPacket.byte2ToBuf(1); + retPacket.strToBuf(""); + sendPacketTcp(&retPacket); + ArLog::log(ArLog::Normal, "%sRejected user '%s' or password from %s", + myLogPrefix.c_str(), user, getIPString()); + internalSwitchState(STATE_REJECTED); + return; + } + if (myUserInfo != NULL) + myGroups = myUserInfo->getUsersGroups(user); + else + myGroups.clear(); + sin.sin_family = AF_INET; + sin.sin_addr = *myTcpSocket.inAddr(); + sin.sin_port = ArSocket::hostToNetOrder(clientUdpPort); + if (myUserInfo != NULL) + ArLog::log(ArLog::Normal, + "%sClient connected from %s with user %s", + myLogPrefix.c_str(), getIPString(), user); + else + ArLog::log(ArLog::Normal, + "%sClient connected from %s", myLogPrefix.c_str(), + getIPString()); + + setUdpAddress(&sin); + // send that we've connected + retPacket.empty(); + retPacket.setCommand(ArServerCommands::CONNECTED); + sendPacketTcp(&retPacket); + // note that we're connected + internalSwitchState(STATE_CONNECTED); + + // send them the list + sendListPacket(); + // send the udp introduction if we're using udp + if (!myTcpOnly) + { + retPacket.empty(); + retPacket.setCommand(ArServerCommands::UDP_INTRODUCTION); + retPacket.byte4ToBuf(myIntroKey); + sendPacketUdp(&retPacket); + } + } + // if we aren't in intro mode and got an intro somethings wrong + else if (packet->getCommand() == ArClientCommands::INTRODUCTION) + { + ArLog::log(ArLog::Terse, + "%sReceived introduction when not in intro mode", + myLogPrefix.c_str()); + return; + } + // if we got this over tcp then they only want tcp + else if (packet->getCommand() == ArClientCommands::UDP_INTRODUCTION) + { + if (!myTcpOnly) + { + ArLog::log(ArLog::Normal, "%sGot UDP introduction over tcp, assuming client only wants tcp data.", myLogPrefix.c_str()); + myTcpOnly = true; + } + return; + } + // if we're connected and got a udp confirmation + else if ((myState == STATE_CONNECTED || + myState == STATE_SENT_INTRO) && + packet->getCommand() == ArClientCommands::UDP_CONFIRMATION) + { + myUdpConfirmedTo = true; + ArLog::log(myVerboseLogLevel, + "%s: udp connection to client confirmed.", myLogPrefix.c_str()); + return; + } + // if we're not connected (or close) and got a confirmation + else if (packet->getCommand() == ArClientCommands::UDP_CONFIRMATION) + { + ArLog::log(ArLog::Normal, + "%sReceived udp confirmation when not connected.", + myLogPrefix.c_str()); + return; + } + else if (packet->getCommand() == ArClientCommands::TCP_ONLY) + { + ArLog::log(myVerboseLogLevel, "%sClient only wants tcp data.", myLogPrefix.c_str()); + myTcpOnly = true; + return; + } + else if (packet->getCommand() == ArClientCommands::SHUTDOWN) + { + ArLog::log(ArLog::Normal, "%sClient from %s has disconnected.", + myLogPrefix.c_str(), getIPString()); + internalSwitchState(STATE_DISCONNECTED); + return; + } + // if we're connected its a request, then set all that up + else if (myState == STATE_CONNECTED && + packet->getCommand() == ArClientCommands::REQUEST) + { + std::list::iterator it; + ArServerClientData *data; + ArServerData *serverData; + unsigned int command; + long mSec; + // see which one they requested + command = packet->bufToUByte2(); + mSec = packet->bufToByte4(); + + // first we see if we already have this one + for (it = myRequested.begin(); it != myRequested.end(); ++it) + { + data = (*it); + serverData = data->getServerData(); + if (serverData->getCommand() == command) + { + trackPacketReceived(packet, command); + data->setMSec(mSec); + data->setPacket(packet); + data->getPacket()->setCommand(command); + serverData->callRequestChangedFunctor(); + ArLog::log(myVerboseLogLevel, + "%sRevised request for command %s to %d mSec with new argument", + myLogPrefix.c_str(), + findCommandName(serverData->getCommand()), mSec); + return; + } + } + // we didn't have it, so make a new one + std::map::iterator sdit; + if ((sdit = myDataMap->find(command)) == myDataMap->end()) + { + ArLog::log(ArLog::Terse, + "%sGot request for command %d which doesn't exist", + myLogPrefix.c_str(), command); + return; + } + serverData = (*sdit).second; + if (serverData == NULL) + { + ArLog::log(ArLog::Terse, + "%sprocessPackets request handler has NULL serverData", + myLogPrefix.c_str()); + } + if (myUserInfo != NULL && + serverData->getCommandGroup() != NULL && + serverData->getCommandGroup()[0] != '\0' && + myGroups.count(serverData->getCommandGroup()) == 0 && + myGroups.count("all") == 0) + { + ArLog::log(ArLog::Normal, + "%s%s tried to request command '%s' but it doesn't have access to that command", + myLogPrefix.c_str(), getIPString(), + serverData->getName()); + return; + } + trackPacketReceived(packet, command); + data = new ArServerClientData(serverData, mSec, packet); + data->getPacket()->setCommand(command); + ArLog::log(myVerboseLogLevel, + "%sadded request for command %s every %d mSec", + myLogPrefix.c_str(), serverData->getName(), mSec); + if (mSec == 0) + ArLog::log(ArLog::Normal, "%sClient from %s requested command %s every at 0 msec", myLogPrefix.c_str(), + getIPString(), serverData->getName()); + myRequested.push_front(data); + serverData->callRequestChangedFunctor(); + pushCommand(command); + pushForceTcpFlag(false); + if (serverData->getFunctor() != NULL) + serverData->getFunctor()->invoke(this, data->getPacket()); + popCommand(); + popForceTcpFlag(); + return; + } + // if we got a request when we're not connected + else if (packet->getCommand() == ArClientCommands::REQUEST) + { + ArLog::log(ArLog::Normal, + "Got a request while not connected.", + myLogPrefix.c_str()); + return; + } + // if we're connected its a requestStop, then set all that up + else if (myState == STATE_CONNECTED && + packet->getCommand() == ArClientCommands::REQUESTSTOP) + { + std::list::iterator it; + ArServerClientData *data; + ArServerData *serverData; + unsigned int command; + // see which one they requested + command = packet->bufToUByte2(); + + // first we see if we have this one + for (it = myRequested.begin(); it != myRequested.end(); ++it) + { + data = (*it); + serverData = data->getServerData(); + // we have a match, so set the new params then return + if (data->getServerData()->getCommand() == command) + { + trackPacketReceived(packet, command); + myRequested.erase(it); + ArLog::log(myVerboseLogLevel, "%sStopped request for command %s", + myLogPrefix.c_str(), + findCommandName(serverData->getCommand())); + delete data; + serverData->callRequestChangedFunctor(); + return; + } + } + // if we don't have it... that means that it wasn't here + + // find out what to call it + std::map::iterator sdit; + if ((sdit = myDataMap->find(command)) == myDataMap->end()) + { + ArLog::log(ArLog::Terse, + "%sGot a requeststop for command %d which doesn't exist", + myLogPrefix.c_str(), command); + return; + } + trackPacketReceived(packet, command); + serverData = (*sdit).second; + if (serverData == NULL) + ArLog::log(ArLog::Terse, + "%srequeststop handler has NULL serverData on back command %d", + myLogPrefix.c_str(), command); + else + ArLog::log(ArLog::Normal, "%s: Got a stop request for command %s that isn't requested", myLogPrefix.c_str(), serverData->getName()); + return; + } + // if we got a requestStop when we're not connected + else if (packet->getCommand() == ArClientCommands::REQUESTSTOP) + { + ArLog::log(ArLog::Normal, + "%sGot a requeststop while not connected.", + myLogPrefix.c_str()); + return; + } + // if we're connected and its a command to execute just once + else if (myState == STATE_CONNECTED) + { + unsigned int command; + std::map::iterator it; + ArServerData *serverData; + + command = packet->getCommand(); + if ((it = myDataMap->find(command)) == myDataMap->end()) + { + ArLog::log(ArLog::Terse, + "%sArServerClient got request for command %d which doesn't exist", + myLogPrefix.c_str(), command); + return; + } + serverData = (*it).second; + if (myUserInfo != NULL && + serverData->getCommandGroup() != NULL && + serverData->getCommandGroup()[0] != '\0' && + myGroups.count(serverData->getCommandGroup()) == 0 && + myGroups.count("all") == 0) + { + ArLog::log(ArLog::Normal, + "%s%s tried to request command '%s' once but it doesn't have access to that command", myLogPrefix.c_str(), + getIPString(), + serverData->getName()); + return; + } + trackPacketReceived(packet, command); + + // copy it out and return if its an idle packet + if (myAllowIdlePackets && serverData->isIdlePacket()) + { + myHaveIdlePackets = true; + if (command <= 255) + ArLog::log(myVerboseLogLevel, "%sStoring idle command %d", + myLogPrefix.c_str(), command); + else + ArLog::log(myVerboseLogLevel, "%sStoring idle command %s", + myLogPrefix.c_str(), serverData->getName()); + myIdlePacketsMutex.lock(); + ArNetPacket *idlePacket = new ArNetPacket(packet->getLength() + 5); + idlePacket->duplicatePacket(packet); + myIdlePackets.push_back(idlePacket); + myIdlePacketsMutex.unlock(); + return; + } + // If its a slow or an idle packet (and we're not allowing the + // idle behavior) and we allow slow packets then copy it + else if (myAllowSlowPackets && (serverData->isSlowPacket() || + serverData->isIdlePacket())) + { + myHaveSlowPackets = true; + if (command <= 255) + ArLog::log(myVerboseLogLevel, "%sStoring slow command %d", + myLogPrefix.c_str(), command); + else + ArLog::log(myVerboseLogLevel, "%sStoring slow command %s", + myLogPrefix.c_str(), serverData->getName()); + mySlowPacketsMutex.lock(); + ArNetPacket *slowPacket = new ArNetPacket(packet->getLength() + 5); + slowPacket->duplicatePacket(packet); + mySlowPackets.push_back(slowPacket); + mySlowPacketsMutex.unlock(); + return; + } + + + if (command <= 255) + ArLog::log(myVerboseLogLevel, "%sGot command %s", + myLogPrefix.c_str(), serverData->getName()); + else + ArLog::log(ArLog::Verbose, "%sGot command %s", + myLogPrefix.c_str(), serverData->getName()); + pushCommand(command); + pushForceTcpFlag(tcp); + if (serverData->getFunctor() != NULL) + serverData->getFunctor()->invoke(this, packet); + if (serverData->getRequestOnceFunctor() != NULL) + serverData->getRequestOnceFunctor()->invokeR(this, packet); + popCommand(); + popForceTcpFlag(); + return; + } + else + { + ArLog::log(ArLog::Terse, + "%sRogue packet command %s in state %d", myLogPrefix.c_str(), + findCommandName(packet->getCommand()), myState); + } +} + +AREXPORT void ArServerClient::forceDisconnect(bool quiet) +{ + if (!quiet) + ArLog::log(ArLog::Normal, "Client from %s has been forcibly disconnected.", + getIPString()); + internalSwitchState(STATE_DISCONNECTED); +} + +AREXPORT void ArServerClient::processAuthPacket(ArNetPacket *packet, + struct sockaddr_in *sin) +{ + ArNetPacket retPacket; + long authKey; + // check the auth key again, just in case + + authKey = packet->bufToUByte4(); + if (authKey != myAuthKey) + { + ArLog::log(ArLog::Terse, "ArServerClient: authKey given does not match actual authKey, horrible error."); + return; + } + + if (mySin.sin_port != sin->sin_port) + { + ArLog::log(myVerboseLogLevel, + "Client says it is using port %u but is using port %u\n", + ArSocket::netToHostOrder(mySin.sin_port), + ArSocket::netToHostOrder(sin->sin_port)); + } + myUdpConfirmedFrom = true; + mySin.sin_port = sin->sin_port; + mySin.sin_addr = sin->sin_addr; + ArLog::log(myVerboseLogLevel, "Client connected to server on udp port %u", + ArSocket::netToHostOrder(mySin.sin_port)); + // TODO put some state info here to note that its fully udp connected + retPacket.empty(); + retPacket.setCommand(ArServerCommands::UDP_INTRODUCTION); + retPacket.byte4ToBuf(myIntroKey); + sendPacketUdp(&retPacket); + retPacket.empty(); + retPacket.setCommand(ArServerCommands::UDP_CONFIRMATION); + sendPacketTcp(&retPacket); +} + +AREXPORT void ArServerClient::broadcastPacketTcp(ArNetPacket *packet) +{ + std::list::iterator it; + ArServerClientData *data; + ArServerData *serverData; + ArTime lastSent; + + // walk through our list + for (it = myRequested.begin(); it != myRequested.end(); ++it) + { + data = (*it); + serverData = data->getServerData(); + // see if this is our data, if it is send the packet + if (serverData->getCommand() == packet->getCommand()) + { + sendPacketTcp(packet); + return; + } + } + // we didn't have the data to send +} + +AREXPORT void ArServerClient::broadcastPacketUdp(ArNetPacket *packet) +{ + std::list::iterator it; + ArServerClientData *data; + ArServerData *serverData; + ArTime lastSent; + + // walk through our list + for (it = myRequested.begin(); it != myRequested.end(); ++it) + { + data = (*it); + serverData = data->getServerData(); + // see if this is our data, if it is send the packet + if (serverData->getCommand() == packet->getCommand()) + { + sendPacketUdp(packet); + return; + } + } + // we didn't have the data to send +} + +AREXPORT bool ArServerClient::sendPacketTcp(ArNetPacket *packet) +{ + if (!setupPacket(packet)) + { + if (myDebugLogging && packet->getCommand() <= 255) + ArLog::log(ArLog::Normal, + "%s sendPacket: could not set up tcp command %d", + myLogPrefix.c_str(), packet->getCommand()); + return false; + } + else + { + trackPacketSent(packet, true); + + if (myDebugLogging && packet->getCommand() <= 255) + ArLog::log(ArLog::Normal, "%sSending tcp command %d", + myLogPrefix.c_str(), packet->getCommand()); + + myTcpSender.sendPacket(packet, myLogPrefix.c_str()); + return true; + } +} + +AREXPORT bool ArServerClient::sendPacketUdp(ArNetPacket *packet) +{ + if (myTcpOnly || getForceTcpFlag()) + return sendPacketTcp(packet); + + if (!setupPacket(packet)) + { + if (myDebugLogging && packet->getCommand() <= 255) + ArLog::log(ArLog::Normal, + "%s sendPacket: could not set up udp command %d", + myLogPrefix.c_str(), packet->getCommand()); + return false; + } + else if (mySendUdpCB != NULL) + { + trackPacketSent(packet, false); + if (myDebugLogging && packet->getCommand() <= 255) + ArLog::log(ArLog::Normal, "%sSending udp command %d", + myLogPrefix.c_str(), packet->getCommand()); + return mySendUdpCB->invokeR(packet, &mySin); + } + else + { + if (myDebugLogging && packet->getCommand() <= 255) + ArLog::log(ArLog::Normal, "%sCould not send udp command %d", + myLogPrefix.c_str(), packet->getCommand()); + return false; + } +} + +AREXPORT bool ArServerClient::setupPacket(ArNetPacket *packet) +{ + if (packet->getCommand() == 0) + { + if (getCommand() != 0) + { + packet->setCommand(getCommand()); + } + else + { + ArLog::log(ArLog::Terse, "ArServerClient::sendPacket: packet to send has no command and we have no command in the stack"); + return false; + } + } + + if (myState == STATE_DISCONNECTED) + { + if (myDebugLogging && packet->getCommand() <= 255) + ArLog::log(myVerboseLogLevel, "%s sendPacket: command %s trying to be sent while disconnected", myLogPrefix.c_str(), findCommandName(packet->getCommand())); + return false; + } + + if (packet->getLength() > ArNetPacket::MAX_LENGTH) + { + ArLog::log(ArLog::Terse, + "% send packet: Packet for command %s packet is bad at %d", + myLogPrefix.c_str(), findCommandName(packet->getCommand()), + packet->getLength()); + return false; + } + + packet->finalizePacket(); + return true; +} + + +AREXPORT void ArServerClient::setUdpAddress(struct sockaddr_in *sin) +{ + mySin = *sin; +} + +AREXPORT struct sockaddr_in *ArServerClient::getUdpAddress(void) +{ + return &mySin; +} + +AREXPORT long ArServerClient::getAuthKey(void) +{ + return myAuthKey; +} + +unsigned int ArServerClient::getCommand(void) +{ + if (mySlowIdleThread == NULL || ArThread::self() != mySlowIdleThread) + { + if (!myCommandStack.empty()) + return myCommandStack.front(); + else + return 0; + } + else + { + if (!mySlowIdleCommandStack.empty()) + return mySlowIdleCommandStack.front(); + else + return 0; + } +} + +void ArServerClient::pushCommand(unsigned int command) +{ + myCommandStack.push_front(command); +} + +void ArServerClient::popCommand(void) +{ + if (myCommandStack.size() == 0) + { + ArLog::log(ArLog::Terse, + "ArServerClient::popCommand: popCommand tried to be called when stack empty."); + } + myCommandStack.pop_front(); +} + +void ArServerClient::pushSlowIdleCommand(unsigned int command) +{ + mySlowIdleCommandStack.push_front(command); +} + +void ArServerClient::popSlowIdleCommand(void) +{ + if (mySlowIdleCommandStack.size() == 0) + { + ArLog::log(ArLog::Terse, + "ArServerClient::popCommand: popSlowIdleCommand tried to be called when stack empty."); + } + mySlowIdleCommandStack.pop_front(); +} + + +bool ArServerClient::getForceTcpFlag(void) +{ + if (mySlowIdleThread == NULL || ArThread::self() != mySlowIdleThread) + { + if (!myForceTcpStack.empty()) + return myForceTcpStack.front(); + else + return false; + + } + else + { + if (!mySlowIdleForceTcpStack.empty()) + return mySlowIdleForceTcpStack.front(); + else + return false; + } +} + +void ArServerClient::pushForceTcpFlag(bool forceTcp) +{ + myForceTcpStack.push_front(forceTcp); +} + +void ArServerClient::popForceTcpFlag(void) +{ + if (myForceTcpStack.size() == 0) + { + ArLog::log(ArLog::Terse, + "ArServerClient::popForceTcp: popForceTcpFlag tried to be called when stack empty."); + } + myForceTcpStack.pop_front(); +} + + +void ArServerClient::pushSlowIdleForceTcpFlag(bool forceTcp) +{ + mySlowIdleForceTcpStack.push_front(forceTcp); +} + +void ArServerClient::popSlowIdleForceTcpFlag(void) +{ + if (mySlowIdleForceTcpStack.size() == 0) + { + ArLog::log(ArLog::Terse, + "ArServerClient::popForceTcp: popSlowIdleForceTcpFlag tried to be called when stack empty."); + } + mySlowIdleForceTcpStack.pop_front(); +} + +AREXPORT void ArServerClient::shutdown(void) +{ + ArNetPacket packet; + + packet.setCommand(ArServerCommands::SHUTDOWN); + sendPacketTcp(&packet); + myTcpSender.sendData(); +} + +AREXPORT const char *ArServerClient::getIPString(void) const +{ + return myIPString.c_str(); +} + +AREXPORT ArServerClientIdentifier ArServerClient::getIdentifier(void) const +{ + return myIdentifier; +} + +AREXPORT void ArServerClient::setIdentifier( + ArServerClientIdentifier identifier) +{ + std::string oldIPString = myIPString; + + myIdentifier = identifier; + myIPString = myTcpSocket.getRawIPString(); + if (myIdentifier.getIDString() != 0 && + myIdentifier.getIDString()[0] != '\0') + { + myIPString += " "; + myIPString += myIdentifier.getIDString(); + } + + if (!oldIPString.empty() && oldIPString != myIPString) + ArLog::log(ArLog::Normal, "%s%s changed to %s", myLogPrefix.c_str(), + oldIPString.c_str(), getIPString()); + myTcpSocket.setIPString(getIPString()); +} + +void ArServerClient::trackPacketSent(ArNetPacket *packet, bool tcp) +{ + if (myTrackingSentMap.find(packet->getCommand()) == myTrackingSentMap.end()) + myTrackingSentMap[packet->getCommand()] = new Tracker; + + if (tcp) + { + myTrackingSentMap[packet->getCommand()]->myPacketsTcp++; + myTrackingSentMap[packet->getCommand()]->myBytesTcp += packet->getLength(); + } + else + { + myTrackingSentMap[packet->getCommand()]->myPacketsUdp++; + myTrackingSentMap[packet->getCommand()]->myBytesUdp += packet->getLength(); + } +} + +void ArServerClient::trackPacketReceived(ArNetPacket *packet, + ArTypes::UByte2 command) +{ + if (myTrackingReceivedMap.find(command) == myTrackingReceivedMap.end()) + myTrackingReceivedMap[command] = new Tracker; + + if (packet->getPacketSource() == ArNetPacket::TCP) + { + myTrackingReceivedMap[command]->myPacketsTcp++; + myTrackingReceivedMap[command]->myBytesTcp += packet->getLength(); + } + else + { + myTrackingReceivedMap[command]->myPacketsUdp++; + myTrackingReceivedMap[command]->myBytesUdp += packet->getLength(); + } +} + +AREXPORT void ArServerClient::logTracking(bool terse) +{ + std::map::iterator it; + + ArTypes::UByte2 command; + Tracker *tracker = NULL; + long seconds; + + seconds = myTrackingStarted.secSince(); + if (seconds == 0) + seconds = 1; + + char name[512]; + + long packetsReceivedTcp = 0; + long bytesReceivedTcp = 0; + long packetsReceivedUdp = 0; + long bytesReceivedUdp = 0; + + ArLog::log(ArLog::Terse, ""); + ArLog::log(ArLog::Terse, "Received tracking for %s (active %d seconds):", + getIPString(), seconds); + for (it = myTrackingReceivedMap.begin(); it != myTrackingReceivedMap.end(); it++) + { + command = (*it).first; + tracker = (*it).second; + + packetsReceivedTcp += tracker->myPacketsTcp; + bytesReceivedTcp += tracker->myBytesTcp; + packetsReceivedUdp += tracker->myPacketsUdp; + bytesReceivedUdp += tracker->myBytesUdp; + + std::map::iterator nameIt; + if ((nameIt = myDataMap->find(command)) != myDataMap->end()) + snprintf(name, sizeof(name), "%s", (*nameIt).second->getName()); + // if we're command 255 or less and there's no name its probably + // one of the server commands we don't really need to track + else if (command <= 255) + continue; + // we should know what the name of everything other then the + // server command is, but print if we don't, just in case + else + snprintf(name, sizeof(name), "#%d", command); + if (terse) + { + ArLog::log(ArLog::Terse, + "%35s %7ld pkts %10ld B %7ld B/sec", + name, tracker->myPacketsTcp + tracker->myPacketsUdp, + tracker->myBytesTcp + tracker->myBytesUdp, + ((tracker->myBytesTcp + tracker->myBytesUdp)/ + seconds)); + } + else + { + ArLog::log(ArLog::Terse, + "%35s %7ld tcp pkts %10ld tcp B %7ld tcp B/S %7ld udp pkts %10ld udp B %7ld udp B/s ", + name, tracker->myPacketsTcp, tracker->myBytesTcp, + tracker->myBytesTcp/seconds, + tracker->myPacketsUdp, tracker->myBytesUdp, + tracker->myBytesUdp/seconds); + } + } + + ArLog::log(ArLog::Terse, ""); + if (terse) + { + ArLog::log(ArLog::Terse, "%-35s %7ld pkts %10ld B %7ld B/sec", + "Total Received", packetsReceivedTcp + packetsReceivedUdp, + bytesReceivedTcp + bytesReceivedUdp, + (bytesReceivedTcp + bytesReceivedUdp) / seconds); + } + else + { + ArLog::log(ArLog::Terse, "%-35s %7ld tcp pkts %10ld tcp B %7ld tcp B/S %7ld udp pkts %10ld udp B %7ld udp B/sec", + "Total Received", packetsReceivedTcp, bytesReceivedTcp, + bytesReceivedTcp/seconds, packetsReceivedUdp, bytesReceivedUdp, + bytesReceivedUdp/seconds); + ArLog::log(ArLog::Terse, "%-35s %7ld tcp rcvs %10ld tcp B %7ld tcp B/S", + "Low level TCP Received", myTcpSocket.getRecvs(), + myTcpSocket.getBytesRecvd(), + myTcpSocket.getBytesRecvd()/seconds); + } + + long packetsSentTcp = 0; + long bytesSentTcp = 0; + long packetsSentUdp = 0; + long bytesSentUdp = 0; + + ArLog::log(ArLog::Terse, ""); + ArLog::log(ArLog::Terse, "Sent tracking for %s (active %d seconds):", + getIPString(), seconds); + for (it = myTrackingSentMap.begin(); it != myTrackingSentMap.end(); it++) + { + command = (*it).first; + tracker = (*it).second; + + packetsSentTcp += tracker->myPacketsTcp; + bytesSentTcp += tracker->myBytesTcp; + packetsSentUdp += tracker->myPacketsUdp; + bytesSentUdp += tracker->myBytesUdp; + + std::map::iterator nameIt; + if ((nameIt = myDataMap->find(command)) != myDataMap->end()) + snprintf(name, sizeof(name), "%s", (*nameIt).second->getName()); + // if we're command 255 or less and there's no name its probably + // one of the server commands we don't really need to track + else if (command <= 255) + continue; + // we should know what the name of everything other then the + // server command is, but print if we don't, just in case + else + snprintf(name, sizeof(name), "#%d", command); + if (terse) + { + ArLog::log(ArLog::Terse, + "%35s %7ld pkts %10ld B %7ld B/sec", + name, tracker->myPacketsTcp + tracker->myPacketsUdp, + tracker->myBytesTcp + tracker->myBytesUdp, + ((tracker->myBytesTcp + tracker->myBytesUdp)/ + seconds)); + } + else + { + ArLog::log(ArLog::Terse, + "%35s %7ld tcp pkts %10ld tcp B %7ld tcp B/S %7ld udp pkts %10ld udp B %7ld udp B/s ", + name, tracker->myPacketsTcp, tracker->myBytesTcp, + tracker->myBytesTcp/seconds, + tracker->myPacketsUdp, tracker->myBytesUdp, + tracker->myBytesUdp/seconds); + } + } + + ArLog::log(ArLog::Terse, ""); + if (terse) + { + ArLog::log(ArLog::Terse, "%-35s %7ld pkts %10ld B %7ld B/sec", + "Total Sent", packetsSentTcp + packetsSentUdp, + bytesSentTcp + bytesSentUdp, + (bytesSentTcp + bytesSentUdp) / seconds); + ArLog::log(ArLog::Terse, ""); + ArLog::log(ArLog::Terse, "%-35s %7ld pkts %10ld B %7ld B/sec", + "Total Sent and Received", + (packetsSentTcp + packetsSentUdp + + packetsReceivedTcp + packetsReceivedUdp), + (bytesSentTcp + bytesSentUdp + + bytesReceivedTcp + bytesReceivedUdp), + (bytesSentTcp + bytesSentUdp + + bytesReceivedTcp + bytesReceivedUdp) / seconds); + } + else + { + ArLog::log(ArLog::Terse, "%-35s %7ld tcp pkts %10ld tcp B %7ld tcp B/S %7ld udp pkts %10ld udp B %7ld udp B/sec", + "Total Sent", packetsSentTcp, bytesSentTcp, + bytesSentTcp / seconds, + packetsSentUdp, bytesSentUdp, bytesSentUdp / seconds); + ArLog::log(ArLog::Terse, "%-35s %7ld tcp snds %10ld tcp B %7ld tcp B/S", + "Low level TCP Sent", myTcpSocket.getSends(), + myTcpSocket.getBytesSent(), + myTcpSocket.getBytesSent() / seconds); + + ArLog::log(ArLog::Terse, ""); + ArLog::log(ArLog::Terse, "%-35s %7ld tcp pkts %10ld tcp B %7ld tcp B/S %7ld udp pkts %10ld udp B %7ld udp B/sec", + "Total Sent and Received", packetsSentTcp = packetsReceivedTcp, + bytesSentTcp + bytesReceivedTcp, + (bytesSentTcp + bytesReceivedTcp) / seconds, + packetsSentUdp + packetsReceivedUdp, + bytesSentUdp + bytesReceivedUdp, + (bytesSentUdp + bytesReceivedUdp) / seconds); + } + + ArLog::log(ArLog::Terse, ""); +} + + +AREXPORT void ArServerClient::resetTracking(void) +{ + std::map::iterator it; + + myTrackingStarted.setToNow(); + + for (it = myTrackingSentMap.begin(); it != myTrackingSentMap.end(); it++) + (*it).second->reset(); + + for (it = myTrackingReceivedMap.begin(); + it != myTrackingReceivedMap.end(); + it++) + (*it).second->reset(); + + myTcpSocket.resetTracking(); +} + +AREXPORT bool ArServerClient::hasGroupAccess(const char *group) +{ + if (myUserInfo == NULL || group == NULL || group[0] == '\0' || + myGroups.count(group) > 0 || myGroups.count("all") > 0) + return true; + else + return false; +} + +/** + @param command the command number, you can use findCommandFromName + + @return returns lowest amount of time requested for this packet, + note that 0 and higher means thats how often it was asked for, -1 + means nothing requested the data at an interval but wants it when + its been pushed, and -2 means that nothing wants the data +**/ + +AREXPORT long ArServerClient::getFrequency(ArTypes::UByte2 command) +{ + std::list::iterator it; + ArServerClientData *data; + ArServerData *serverData; + + // walk through our list + for (it = myRequested.begin(); it != myRequested.end(); ++it) + { + data = (*it); + serverData = data->getServerData(); + // see if this is our data, if it is send the packet + if (serverData->getCommand() == command) + { + if (data->getMSec() >= 0) + return data->getMSec(); + else + return -1; + } + } + return -2; +} + + +AREXPORT void ArServerClient::startRequestTransaction() +{ + myRequestTransactionMutex.lock(); + myRequestTransactionCount++; + myRequestTransactionMutex.unlock(); + +} // end method startRequestTransaction + + +AREXPORT bool ArServerClient::endRequestTransaction() +{ + bool isSuccess = false; + myRequestTransactionMutex.lock(); + if (myRequestTransactionCount > 0) { + myRequestTransactionCount--; + isSuccess = true; + } + else { + ArLog::log(ArLog::Normal, + "ArServerClient::endRequestTransaction() transaction not in progress"); + } + myRequestTransactionMutex.unlock(); + + return isSuccess; + +} // end method endRequestTransaction + + +AREXPORT int ArServerClient::getRequestTransactionCount() +{ + myRequestTransactionMutex.lock(); + int c = myRequestTransactionCount; + myRequestTransactionMutex.unlock(); + + return c; + +} // end method getRequestTransactionCount + +/** + * Note that this method is not very efficient; it performs a linear search + * of all commands. +**/ +AREXPORT unsigned int ArServerClient::findCommandFromName(const char *commandName) const +{ + if (ArUtil::isStrEmpty(commandName)) { + return 0; + } + + for (std::map::const_iterator iter = + myDataMap->begin(); + iter != myDataMap->end(); + iter++) { + if (strcmp(commandName, (*iter).second->getName()) == 0) { + return iter->first; + } + } + return 0; + +} // end method findCommandFromName + + +const char *ArServerClient::findCommandName(unsigned int command) const +{ + std::map::const_iterator nameIt; + if ((nameIt = myDataMap->find(command)) != myDataMap->end()) + return (*nameIt).second->getName(); + else + return NULL; +} + + +AREXPORT bool ArServerClient::slowPacketCallback(void) +{ + ArNetPacket *slowPacket; + unsigned int command; + std::map::iterator it; + ArServerData *serverData; + + if (mySlowIdleThread == NULL) + mySlowIdleThread = ArThread::self(); + + mySlowPacketsMutex.lock(); + while (!mySlowPackets.empty()) + { + slowPacket = mySlowPackets.front(); + mySlowPackets.pop_front(); + mySlowPacketsMutex.unlock(); + + command = slowPacket->getCommand(); + if ((it = myDataMap->find(command)) == myDataMap->end()) + { + ArLog::log(ArLog::Terse, + "%sArServerClient got request for command %d which doesn't exist during slow... very odd", + myLogPrefix.c_str(), command); + delete slowPacket; + return false; + } + serverData = (*it).second; + + ArLog::log(myVerboseLogLevel, "Processing slow command %s", + serverData->getName()); + + pushSlowIdleCommand(command); + pushSlowIdleForceTcpFlag(true); + + if (serverData->getFunctor() != NULL) + serverData->getFunctor()->invoke(this, slowPacket); + if (serverData->getRequestOnceFunctor() != NULL) + serverData->getRequestOnceFunctor()->invokeR(this, slowPacket); + + popSlowIdleCommand(); + popSlowIdleForceTcpFlag(); + + delete slowPacket; + mySlowPacketsMutex.lock(); + } + mySlowPacketsMutex.unlock(); + myHaveSlowPackets = false; + return true; +} + +AREXPORT bool ArServerClient::idlePacketCallback(void) +{ + ArNetPacket *idlePacket; + unsigned int command; + std::map::iterator it; + ArServerData *serverData; + + if (mySlowIdleThread == NULL) + mySlowIdleThread = ArThread::self(); + + myIdlePacketsMutex.lock(); + while (!myIdlePackets.empty()) + { + idlePacket = myIdlePackets.front(); + myIdlePackets.pop_front(); + myIdlePacketsMutex.unlock(); + + command = idlePacket->getCommand(); + if ((it = myDataMap->find(command)) == myDataMap->end()) + { + ArLog::log(ArLog::Terse, + "%sArServerClient got request for command %d which doesn't exist during idle... very odd", + myLogPrefix.c_str(), command); + delete idlePacket; + return false; + } + serverData = (*it).second; + + ArLog::log(myVerboseLogLevel, "Processing idle command %s", + serverData->getName()); + + pushSlowIdleCommand(command); + pushSlowIdleForceTcpFlag(true); + + if (serverData->getFunctor() != NULL) + serverData->getFunctor()->invoke(this, idlePacket); + if (serverData->getRequestOnceFunctor() != NULL) + serverData->getRequestOnceFunctor()->invokeR(this, idlePacket); + + popSlowIdleCommand(); + popSlowIdleForceTcpFlag(); + + delete idlePacket; + myIdlePacketsMutex.lock(); + } + myIdlePacketsMutex.unlock(); + + myHaveIdlePackets = false; + return true; +} diff --git a/Legacy/Aria/ArNetworking/src/ArServerData.cpp b/Legacy/Aria/ArNetworking/src/ArServerData.cpp new file mode 100644 index 0000000..2fa89dc --- /dev/null +++ b/Legacy/Aria/ArNetworking/src/ArServerData.cpp @@ -0,0 +1,95 @@ +#include "Aria.h" +#include "ArExport.h" +#include "ArServerData.h" +#include "ArServerClient.h" +#include "ArNetPacket.h" + +AREXPORT ArServerData::ArServerData( + const char *name, const char *description, unsigned int command, + ArFunctor2 *functor, + const char *argumentDescription, const char *returnDescription, + const char *commandGroup, const char *dataFlags, + ArRetFunctor1 *getFrequencyFunctor, + ArFunctor2 *requestChangedFunctor, + ArRetFunctor2 + *requestOnceFunctor) : + myDataFlagsBuilder(512, '|') +{ + myDataMutex.setLogName("ArServerData::myDataMutex"); + myName = name; + myDescription = description; + myReturnDescription = returnDescription; + myArgumentDescription = argumentDescription; + myCommand = command; + myFunctor = functor; + if (commandGroup != NULL) + myCommandGroup = commandGroup; + else + myCommandGroup = ""; + myGetFrequencyFunctor = getFrequencyFunctor; + myRequestChangedFunctor = requestChangedFunctor; + myRequestOnceFunctor = requestOnceFunctor; + if (dataFlags != NULL) + { + myDataFlagsBuilder.add(dataFlags); + } + + mySlowPacket = hasDataFlag("SLOW_PACKET"); + myIdlePacket = hasDataFlag("IDLE_PACKET"); +} + +AREXPORT ArServerData::~ArServerData() +{ + +} + +AREXPORT bool ArServerData::hasDataFlag(const char *dataFlag) +{ + myDataMutex.lock(); + size_t i; + for (i = 0; i < myDataFlagsBuilder.getArgc(); i++) + { + if (strcmp(myDataFlagsBuilder.getArg(i), dataFlag) == 0) + { + myDataMutex.unlock(); + return true; + } + } + + myDataMutex.unlock(); + return false; +} + +AREXPORT bool ArServerData::addDataFlags(const char *dataFlags) +{ + myDataMutex.lock(); + myDataFlagsBuilder.add(dataFlags); + myDataMutex.unlock(); + return true; +} + +AREXPORT bool ArServerData::remDataFlag(const char *dataFlag) +{ + myDataMutex.lock(); + size_t i; + for (i = myDataFlagsBuilder.getArgc(); i < myDataFlagsBuilder.getArgc(); i++) + { + if (strcmp(myDataFlagsBuilder.getArg(i), dataFlag) == 0) + { + myDataFlagsBuilder.removeArg(i); + myDataMutex.unlock(); + return true; + } + } + + myDataMutex.unlock(); + return false; +} + +AREXPORT void ArServerData::callRequestChangedFunctor(void) +{ + if (myGetFrequencyFunctor == NULL || myRequestChangedFunctor == NULL) + return; + myRequestChangedFunctor->invoke( + myGetFrequencyFunctor->invokeR(myCommand), myCommand); +} diff --git a/Legacy/Aria/ArNetworking/src/ArServerFileUtils.cpp b/Legacy/Aria/ArNetworking/src/ArServerFileUtils.cpp new file mode 100644 index 0000000..ee5767c --- /dev/null +++ b/Legacy/Aria/ArNetworking/src/ArServerFileUtils.cpp @@ -0,0 +1,1352 @@ +#ifndef WIN32 +#include "Aria.h" +#include "ArExport.h" +#include "ArServerFileUtils.h" + +#include +#include +#include + + +AREXPORT ArServerFileLister::ArServerFileLister( + ArServerBase *server, const char *topDir, + const char *defaultUploadDownloadDir) : + myGetDirListingCB(this, &ArServerFileLister::getDirListing), + myGetDirListingMultiplePacketsCB(this, &ArServerFileLister::getDirListingMultiplePackets), + myGetDefaultUploadDownloadDirCB( + this, + &ArServerFileLister::getDefaultUploadDownloadDir) +{ + myServer = server; + myServer->addData("getDirListing", + "Gets the directory listing of a given directory (from the current working directory), you should probably use a class from ArClientFileUtils instead of calling this directly", + &myGetDirListingCB, "string: directory to get listing of", + "ubyte2: return code, 0 = good, 1 = tried to go outside allowed area, 2 = no such directory (or can't read); string: directoryListed; IF return was 0 then ubyte2: numDirectories; repeating numDirectories (string: name; ubyte4: access_time; ubyte4: modified_time); ubyte2: numFiles; repeating numFiles (string: name; ubyte4: access_time; ubyte4: modified_time);", + "FileAccess", "RETURN_SINGLE|SLOW_PACKET"); + + myServer->addData("getDirListingMultiplePackets", + "Gets the directory listing of a given directory possibly broken up into multiple packets (from the current working directory), you should probably use a class from ArClientFileUtils instead of calling this directly", + &myGetDirListingMultiplePacketsCB, + "string: directory to get listing of", + "ubyte2: return code, 0 = good, 1 = tried to go outside allowed area, 2 = no such directory (or can't read); string: directoryListed; IF return was 0 then ubyte2: numEntries; repeating numEntries (byte: type (1 for dir or 2 for file) string: name; ubyte4: access_time; ubyte4: modified_time)", + "FileAccess", "RETURN_UNTIL_EMPTY|SLOW_PACKET"); + + if (defaultUploadDownloadDir == NULL) + myDefaultUploadDownloadDir = ""; + else + myDefaultUploadDownloadDir = defaultUploadDownloadDir; + + if (!myDefaultUploadDownloadDir.empty()) + myServer->addData("getDefaultUploadDownloadDir", + "Gets the default directory that should be used for upload/download", + &myGetDefaultUploadDownloadDirCB, "none", + "string: defaultUploadDownloadDir", + "FileAccess", "RETURN_SINGLE|SLOW_PACKET"); + + + // snag our base dir and make sure we have enough room for a / + strncpy(myBaseDir, topDir, sizeof(myBaseDir) - 2); + myBaseDir[sizeof(myBaseDir) - 2] = '\0'; + // make sure it has a slash + ArUtil::appendSlash(myBaseDir, sizeof(myBaseDir)); + // make sure the slashes go the right direction + ArUtil::fixSlashes(myBaseDir, sizeof(myBaseDir)); +} + +AREXPORT ArServerFileLister::~ArServerFileLister() +{ + +} + +AREXPORT void ArServerFileLister::getDirListing(ArServerClient *client, + ArNetPacket *packet) +{ + ArNetPacket sendPacket; + size_t ui; + size_t len; + + bool printing = false; + + char directory[2048]; + packet->bufToStr(directory, sizeof(directory)); + + if (printing) + printf("'%s' requested\n", directory); + len = strlen(directory); + // first advance to the first non space + for (ui = 0; + ui < len && directory[ui] != '\0' && isspace(directory[ui]); + ui++); + + char *dirStr = new char[len + 3]; + + // now copy in the rest + strncpy(dirStr, directory, len - ui); + // make sure its null terminated + dirStr[len - ui] = '\0'; + + if (dirStr[0] == '/' || dirStr[0] == '~' || + dirStr[0] == '\\' || strstr(dirStr, "..") != NULL) + { + ArLog::log(ArLog::Normal, "ArServerFileLister: '%s' tried to access outside allowed area", dirStr); + delete[] dirStr; + sendPacket.uByte2ToBuf(1); + // put in the directory name + sendPacket.strToBuf(directory); + if (client != NULL) + client->sendPacketTcp(&sendPacket); + return; + } + + // if its not empty make sure its set up right + if (strlen(dirStr) > 0) + { + // make sure it has a slash + ArUtil::appendSlash(dirStr, len + 2); + // make sure the slashes go the right direction + ArUtil::fixSlashes(dirStr, len + 2); + } + + // put our base and where we want to go together + std::string wholeDir; + wholeDir = myBaseDir; + wholeDir += dirStr; + + DIR *dir; + struct dirent *ent; + struct stat statBuf; + std::set dirs; + std::map dirToATime; + std::map dirToMTime; + std::map dirToSize; + std::set files; + std::map fileToATime; + std::map fileToMTime; + std::map fileToSize; + std::set::iterator it; + std::string str; + + if ((dir = opendir(wholeDir.c_str())) == NULL) + { + ArLog::log(ArLog::Normal, "ArServerFileLister: No such directory '%s' from base '%s' plus directory '%s'", + directory, myBaseDir, dirStr); + delete[] dirStr; + sendPacket.uByte2ToBuf(2); + // put in the directory name + sendPacket.strToBuf(directory); + if (client != NULL) + client->sendPacketTcp(&sendPacket); + return; + } + while ((ent = readdir(dir)) != NULL) + { + // this works because if the first one goes it short circuits the second + if ((it = dirs.find(ent->d_name)) != dirs.end() || + (it = files.find(ent->d_name)) != files.end()) + { + ArLog::log(ArLog::Normal, + "ArServerFileLister: %s duplicates '%s'", + ent->d_name, (*it).c_str()); + continue; + } + if (ent->d_name[0] == '.') + continue; + str = wholeDir.c_str(); + str += ent->d_name; + if (printing) + printf("name %s\n", str.c_str()); + if (stat(str.c_str(), &statBuf) == 0) + { + if (S_ISREG(statBuf.st_mode)) + { + files.insert(ent->d_name); + fileToATime[ent->d_name] = statBuf.st_atime; + fileToMTime[ent->d_name] = statBuf.st_mtime; + fileToSize[ent->d_name] = statBuf.st_size; + //printf("File %s\n", ent.d_name); + } + if (S_ISDIR(statBuf.st_mode)) + { + dirs.insert(ent->d_name); + dirToATime[ent->d_name] = statBuf.st_atime; + dirToMTime[ent->d_name] = statBuf.st_mtime; + dirToSize[ent->d_name] = statBuf.st_size; + //printf("Dir %s\n", ent.d_name); + } + } + else + { + ArLog::log(ArLog::Normal, "Cannot stat %s in %s", ent->d_name, wholeDir.c_str()); + } + } + // we got here so the return is 0 (good) + sendPacket.uByte2ToBuf(0); + // put in the directory name + sendPacket.strToBuf(directory); + if (printing) + printf("Sending %s\n", directory); + if (printing) + printf("Dirs:\n"); + // put in how many directories we have + sendPacket.uByte2ToBuf(dirs.size()); + for (it = dirs.begin(); it != dirs.end(); it++) + { + sendPacket.strToBuf((*it).c_str()); + sendPacket.uByte4ToBuf(dirToATime[(*it)]); + sendPacket.uByte4ToBuf(dirToMTime[(*it)]); + sendPacket.uByte4ToBuf(dirToSize[(*it)]); + } + + if (printing) + { + printf("\n"); + printf("Files:\n"); + } + sendPacket.uByte2ToBuf(files.size()); + for (it = files.begin(); it != files.end(); it++) + { + sendPacket.strToBuf((*it).c_str()); + sendPacket.uByte4ToBuf(fileToATime[(*it)]); + sendPacket.uByte4ToBuf(fileToMTime[(*it)]); + sendPacket.uByte4ToBuf(fileToSize[(*it)]); + if (printing) + { + time_t atime = fileToATime[(*it)]; + time_t mtime = fileToMTime[(*it)]; + printf("\tname: %s\n", (*it).c_str()); + printf("\t\tlastAccessed: %s", ctime(&atime)); + printf("\t\tlastModified: %s", ctime(&mtime)); + printf("\t\tsize: %d", fileToSize[(*it)]); + } + } + delete[] dirStr; + if (client != NULL) + client->sendPacketTcp(&sendPacket); + closedir(dir); +} + +AREXPORT void ArServerFileLister::getDirListingMultiplePackets( + ArServerClient *client, ArNetPacket *packet) +{ + ArNetPacket sendPacket; + size_t ui; + size_t len; + + bool printing = false; + + char directory[2048]; + packet->bufToStr(directory, sizeof(directory)); + + if (printing) + printf("'%s' requested\n", directory); + len = strlen(directory); + // first advance to the first non space + for (ui = 0; + ui < len && directory[ui] != '\0' && isspace(directory[ui]); + ui++); + + char *dirStr = new char[len + 3]; + + // now copy in the rest + strncpy(dirStr, directory, len - ui); + // make sure its null terminated + dirStr[len - ui] = '\0'; + + if (dirStr[0] == '/' || dirStr[0] == '~' || + dirStr[0] == '\\' || strstr(dirStr, "..") != NULL) + { + ArLog::log(ArLog::Normal, "ArServerFileLister: '%s' tried to access outside allowed area", dirStr); + delete[] dirStr; + sendPacket.uByte2ToBuf(1); + // put in the directory name + sendPacket.strToBuf(directory); + if (client != NULL) + { + client->sendPacketTcp(&sendPacket); + sendPacket.empty(); + client->sendPacketTcp(&sendPacket); + } + return; + } + + // if its not empty make sure its set up right + if (strlen(dirStr) > 0) + { + // make sure it has a slash + ArUtil::appendSlash(dirStr, len + 2); + // make sure the slashes go the right direction + ArUtil::fixSlashes(dirStr, len + 2); + } + + // put our base and where we want to go together + std::string wholeDir; + wholeDir = myBaseDir; + wholeDir += dirStr; + + DIR *dir; + struct dirent *ent; + struct stat statBuf; + std::set dirs; + std::map dirToATime; + std::map dirToMTime; + std::map dirToSize; + std::set files; + std::map fileToATime; + std::map fileToMTime; + std::map fileToSize; + std::set::iterator it; + std::string str; + ArTypes::UByte2 numEntries = 0; + int type; + + if ((dir = opendir(wholeDir.c_str())) == NULL) + { + ArLog::log(ArLog::Normal, "ArServerFileLister: No such directory '%s' from base '%s' plus directory '%s'", + directory, myBaseDir, dirStr); + delete[] dirStr; + sendPacket.uByte2ToBuf(2); + // put in the directory name + sendPacket.strToBuf(directory); + if (client != NULL) + { + client->sendPacketTcp(&sendPacket); + sendPacket.empty(); + client->sendPacketTcp(&sendPacket); + } + return; + } + + // we got here so the return is 0 (good) + sendPacket.uByte2ToBuf(0); + // put in the directory name + sendPacket.strToBuf(directory); + + ArTypes::UByte2 numEntriesLen = sendPacket.getLength(); + ArTypes::UByte2 realLen; + // put in a placeholder for how many directories we have + sendPacket.uByte2ToBuf(0); + + while ((ent = readdir(dir)) != NULL) + { + // this works because if the first one goes it short circuits the second + if ((it = dirs.find(ent->d_name)) != dirs.end() || + (it = files.find(ent->d_name)) != files.end()) + { + ArLog::log(ArLog::Normal, + "ArServerFileLister: %s duplicates '%s'", + ent->d_name, (*it).c_str()); + continue; + } + if (ent->d_name[0] == '.') + continue; + str = wholeDir.c_str(); + str += ent->d_name; + if (printing) + printf("name %s\n", str.c_str()); + if (stat(str.c_str(), &statBuf) == 0) + { + if (S_ISREG(statBuf.st_mode)) + type = 2; + else if (S_ISDIR(statBuf.st_mode)) + type = 1; + else + type = 0; + + if (type == 0) + continue; + + if (sendPacket.getDataLength() + strlen(ent->d_name) + 12 >= + ArNetPacket::MAX_DATA_LENGTH) + { + // put in the number of entries in that packet + realLen = sendPacket.getLength(); + sendPacket.setLength(numEntriesLen); + sendPacket.uByte2ToBuf(numEntries); + sendPacket.setLength(realLen); + + // and send it + if (client != NULL) + client->sendPacketTcp(&sendPacket); + + sendPacket.empty(); + // then rebuild the start of it + sendPacket.uByte2ToBuf(0); + // put in the directory name + sendPacket.strToBuf(directory); + + numEntriesLen = sendPacket.getLength(); + // put in a placeholder for how many directories we have + sendPacket.uByte2ToBuf(0); + + // and reset our counter + numEntries = 0; + } + numEntries++; + sendPacket.byteToBuf(type); + sendPacket.strToBuf(ent->d_name); + sendPacket.uByte4ToBuf(statBuf.st_atime); + sendPacket.uByte4ToBuf(statBuf.st_mtime); + sendPacket.uByte4ToBuf(statBuf.st_size); + } + else + { + ArLog::log(ArLog::Normal, "Cannot stat %s in %s", ent->d_name, wholeDir.c_str()); + } + } + + + // put in the number of entries in that packet + realLen = sendPacket.getLength(); + sendPacket.setLength(numEntriesLen); + sendPacket.uByte2ToBuf(numEntries); + sendPacket.setLength(realLen); + + // and send it + if (client != NULL) + client->sendPacketTcp(&sendPacket); + + delete[] dirStr; + + // then send our empty packet to say we're done + sendPacket.empty(); + if (client != NULL) + client->sendPacketTcp(&sendPacket); + + closedir(dir); +} + +AREXPORT void ArServerFileLister::getDefaultUploadDownloadDir( + ArServerClient *client, ArNetPacket *packet) +{ + ArNetPacket sendPacket; + sendPacket.strToBuf(myDefaultUploadDownloadDir.c_str()); + client->sendPacketTcp(&sendPacket); +} + + + +// ----------------------------------------------------------------------------- +// ArServerFileToClient +// ----------------------------------------------------------------------------- + + +AREXPORT ArServerFileToClient::ArServerFileToClient(ArServerBase *server, + const char *topDir) : + myGetFileCB(this, &ArServerFileToClient::getFile), + myGetFileWithTimestampCB(this, &ArServerFileToClient::getFileWithTimestamp) +{ + myServer = server; + myServer->addData("getFile", + "Gets a file (use ArClientFileToClient instead of calling this directly since this interface may change)", + &myGetFileCB, "string: file to get; byte2: operation, 0 == get, 1 == cancel (these aren't implemented yet but will be)", + "ubyte2: return code, 0 = good (sending file), 1 = tried to go outside allowed area, 2 = no such file (or can't read), 3 = empty file name, 4 = error reading file (can happen after some good values) ; string: fileGotten;IF return was 0 then ubyte4: numBytes (number of bytes in this packet, 0 means end of file; numBytes of data", + "FileAccess", "RETURN_UNTIL_EMPTY|SLOW_PACKET"); + + myServer->addData("getFileWithTimestamp", + "Gets a file (use ArClientFileToClient instead of calling this directly since this interface may change)", + &myGetFileWithTimestampCB, + "string: file to get; byte2: operation, 0 == get, 1 == cancel (these aren't implemented yet but will be)", + "ubyte2: return code, 0 = good (sending file), 1 = tried to go outside allowed area, 2 = no such file (or can't read), 3 = empty file name, 4 = error reading file (can happen after some good values) ; string: fileGotten; IF return was 0 then byte4: time_t that file was last modified; ubyte4: numBytes (number of bytes in the file buffer in this packet, 0 means end of file); data buffer that is numBytes in length", + "FileAccess", "RETURN_UNTIL_EMPTY|SLOW_PACKET"); + + // snag our base dir and make sure we have enough room for a / + strncpy(myBaseDir, topDir, sizeof(myBaseDir) - 2); + myBaseDir[sizeof(myBaseDir) - 2] = '\0'; + // make sure it has a slash + ArUtil::appendSlash(myBaseDir, sizeof(myBaseDir)); + // make sure the slashes go the right direction + ArUtil::fixSlashes(myBaseDir, sizeof(myBaseDir)); +} + +AREXPORT ArServerFileToClient::~ArServerFileToClient() +{ + +} + + + +AREXPORT void ArServerFileToClient::getFile(ArServerClient *client, + ArNetPacket *packet) +{ + doGetFile(client, packet, false); +} + +AREXPORT void ArServerFileToClient::getFileWithTimestamp + (ArServerClient *client, + ArNetPacket *packet) +{ + doGetFile(client, packet, true); +} + + + +AREXPORT void ArServerFileToClient::doGetFile(ArServerClient *client, + ArNetPacket *packet, + bool isSetTimestamp) +{ + ArNetPacket sendPacket; + + char fileNameRaw[2048]; + packet->bufToStr(fileNameRaw, sizeof(fileNameRaw)); + + // should check for operation here, but thats not implemented yet + + char fileNameCooked[2048]; + strcpy(fileNameCooked, fileNameRaw); + ArUtil::fixSlashes(fileNameCooked, sizeof(fileNameCooked)); + + + char fileName[2048]; + if (!ArUtil::matchCase(myBaseDir, fileNameCooked, + fileName, sizeof(fileName))) + { + ArLog::log(ArLog::Normal, + "ArServerFileToClient: can't open file '%s'", fileNameRaw); + sendPacket.uByte2ToBuf(2); + sendPacket.strToBuf(fileNameRaw); + client->sendPacketTcp(&sendPacket); + // send an empty packet so that forwarding knows we're done + sendPacket.empty(); + client->sendPacketTcp(&sendPacket); + return; + } + + size_t len = strlen(fileName); + size_t ui = 0; + + // first advance to the first non space + for (ui = 0; + ui < len && fileName[ui] != '\0' && isspace(fileName[ui]); + ui++); + + char *fileStr = new char[len + 3]; + + // now copy in the rest + strncpy(fileStr, fileName, len - ui); + // make sure its null terminated + fileStr[len - ui] = '\0'; + + if (fileStr[0] == '/' || fileStr[0] == '~' || + fileStr[0] == '\\' || strstr(fileStr, "..") != NULL) + { + ArLog::log(ArLog::Normal, + "ArServerFileToClient: '%s' tried to access outside allowed area", + fileStr); + delete[] fileStr; + sendPacket.uByte2ToBuf(1); + sendPacket.strToBuf(fileNameRaw); + client->sendPacketTcp(&sendPacket); + // send an empty packet so that forwarding knows we're done + sendPacket.empty(); + client->sendPacketTcp(&sendPacket); + return; + } + + if (strlen(fileStr) > 0) + { + ArUtil::fixSlashes(fileStr, len + 2); + } + else + { + ArLog::log(ArLog::Normal, + "ArServerFileToClient: can't get file, empty filename"); + delete[] fileStr; + sendPacket.uByte2ToBuf(3); + sendPacket.strToBuf(fileNameRaw); + client->sendPacketTcp(&sendPacket); + // send an empty packet so that forwarding knows we're done + sendPacket.empty(); + client->sendPacketTcp(&sendPacket); + return; + } + + // walk from our base down and try to find the first by name + // ignoring case + + // put our base and where we want to go together + std::string wholeName; + wholeName = myBaseDir; + wholeName += fileStr; + + delete[] fileStr; + + ArLog::log(ArLog::Verbose, + "ArServerFileToClient: Trying to open %s from base %s", + wholeName.c_str(), myBaseDir); + + struct stat fileStat; + stat(wholeName.c_str(), &fileStat); + + FILE *file = NULL; + if ((file = ArUtil::fopen(wholeName.c_str(), "rb")) == NULL) + { + ArLog::log(ArLog::Normal, + "ArServerFileToClient: can't open file '%s'", fileName); + sendPacket.uByte2ToBuf(2); + sendPacket.strToBuf(fileNameRaw); + + + client->sendPacketTcp(&sendPacket); + // send an empty packet so that forwarding knows we're done + sendPacket.empty(); + client->sendPacketTcp(&sendPacket); + return; + } + + + + char buf[30000]; + size_t ret = 0; + // now send the file + while ((ret = fread(buf, 1, sizeof(buf), file)) == sizeof(buf)) + { + sendPacket.empty(); + sendPacket.uByte2ToBuf(0); + sendPacket.strToBuf(fileNameRaw); + sendPacket.uByte4ToBuf(ret); + if (isSetTimestamp) { + sendPacket.byte4ToBuf(fileStat.st_mtime); + } + sendPacket.dataToBuf(buf, ret); + client->sendPacketTcp(&sendPacket); + //printf("Sent packet with %d\n", ret); + } // end while more to read + + + if (ferror(file)) + { + ArLog::log(ArLog::Normal, "ArServerFileToClient: Error sending file %s", + fileName); + sendPacket.empty(); + sendPacket.uByte2ToBuf(4); + sendPacket.strToBuf(fileNameRaw); + client->sendPacketTcp(&sendPacket); + // send an empty packet so that forwarding knows we're done + sendPacket.empty(); + client->sendPacketTcp(&sendPacket); + return; + } + + // Send the remnants from the last iteration of the while loop above + if (ret != 0) { + + sendPacket.empty(); + sendPacket.uByte2ToBuf(0); + sendPacket.strToBuf(fileNameRaw); + sendPacket.uByte4ToBuf(ret); + if (isSetTimestamp) { + sendPacket.byte4ToBuf(fileStat.st_mtime); + } + sendPacket.dataToBuf(buf, ret); + //printf("Sent packet with %d\n", ret); + client->sendPacketTcp(&sendPacket); + } + + // Send a zero size to indicate that the file is ndone + sendPacket.empty(); + sendPacket.uByte2ToBuf(0); + sendPacket.strToBuf(fileNameRaw); + sendPacket.uByte4ToBuf(0); + if (isSetTimestamp) { + sendPacket.byte4ToBuf(fileStat.st_mtime); + } + + + //printf("Sent packet end\n"); + client->sendPacketTcp(&sendPacket); + + + // send an empty packet so that forwarding knows we're done + sendPacket.empty(); + client->sendPacketTcp(&sendPacket); + + if (feof(file)) + { + ArLog::log(ArLog::Normal, "ArServerFileToClient: Sent file %s to %s", + fileName, client->getIPString()); + } + fclose(file); + +} + +// ----------------------------------------------------------------------------- +// ArServerFileFromClient +// ----------------------------------------------------------------------------- + +AREXPORT ArServerFileFromClient::ArServerFileFromClient(ArServerBase *server, + const char *topDir, + const char *tempDir) : + myPutFileCB(this, &ArServerFileFromClient::putFile), + myPutFileInterleavedCB(this, &ArServerFileFromClient::putFileInterleaved), + myPutFileWithTimestampCB(this, &ArServerFileFromClient::putFileWithTimestamp), + myPutFileWithTimestampInterleavedCB(this, &ArServerFileFromClient::putFileWithTimestampInterleaved) +{ + + myServer = server; + + myServer->addData("putFile", + "Puts a file (use ArClientFileFromClient instead of calling this directly since this interface may change)", + &myPutFileCB, "uByte2: command, 0 = start file, 1 = continue file, 2 done with file, 3 = cancel put; string: file being sent; IF command == 1 then uByte4: numBytes; numBytes of data", + "uByte2: return code, 0 = good (got file), 1 = getting file, 2 = tried to go outside allowed area, 3 = bad directory, 4 = empty file name (or other problem with fileName), 5 = can't write temp file, 6 = error moving file from temp to perm, 7 = another client putting file, 8 = timeout (no activity for 15 seconds) and another client wanted to put the file, 9 = client adding to, finishing, or canceling a file the server doesn't have; string: fileName", + "FileAccess", "RETURN_COMPLEX|SLOW_PACKET|DO_NOT_FORWARD"); + + myServer->addData("putFileInterleaved", + "Puts a file (use ArClientFileFromClient instead of calling this directly since this interface may change)", + &myPutFileInterleavedCB, "uByte2: command, 0 = start file, 1 = continue file, 2 done with file, 3 = cancel put; string: file being sent; IF command == 1 then uByte4: numBytes; numBytes of data", + "uByte2: return code, 0 = good (got file), 1 = getting file, 2 = tried to go outside allowed area, 3 = bad directory, 4 = empty file name (or other problem with fileName), 5 = can't write temp file, 6 = error moving file from temp to perm, 7 = another client putting file, 8 = timeout (no activity for 15 seconds) and another client wanted to put the file, 9 = client adding to, finishing, or canceling a file the server doesn't have, 10 = gotPacket, awaiting next packet, 11 = cancelled put; string: fileName", + "FileAccess", "RETURN_SINGLE|SLOW_PACKET|DO_NOT_FORWARD"); + + myServer->addData("putFileWithTimestamp", + "Puts a file and sets its modified time (use ArClientFileFromClient instead of calling this directly since this interface may change)", + &myPutFileWithTimestampCB, + "uByte2: command, 0 = start file, 1 = continue file, 2 done with file, 3 = cancel put; string: file being sent; IF command == 0 then byte4: time_t last modified; IF command == 1 then uByte4: numBytes; numBytes of data", + "uByte2: return code, 0 = good (got file), 1 = getting file, 2 = tried to go outside allowed area, 3 = bad directory, 4 = empty file name (or other problem with fileName), 5 = can't write temp file, 6 = error moving file from temp to perm, 7 = another client putting file, 8 = timeout (no activity for 15 seconds) and another client wanted to put the file, 9 = client adding to, finishing, or canceling a file the server doesn't have; string: fileName", + "FileAccess", "RETURN_COMPLEX|SLOW_PACKET|DO_NOT_FORWARD"); + + myServer->addData("putFileWithTimestampInterleaved", + "Puts a file and sets its modified time (use ArClientFileFromClient instead of calling this directly since this interface may change)", + &myPutFileInterleavedCB, + "uByte2: command, 0 = start file, 1 = continue file, 2 done with file, 3 = cancel put; string: file being sent; IF command == 0 then byte4: time_t last modified; IF command == 1 then uByte4: numBytes; numBytes of data", + "uByte2: return code, 0 = good (got file), 1 = getting file, 2 = tried to go outside allowed area, 3 = bad directory, 4 = empty file name (or other problem with fileName), 5 = can't write temp file, 6 = error moving file from temp to perm, 7 = another client putting file, 8 = timeout (no activity for 15 seconds) and another client wanted to put the file, 9 = client adding to, finishing, or canceling a file the server doesn't have, 10 = gotPacket, awaiting next packet, 11 = cancelled put; string: fileName", + "FileAccess", "RETURN_SINGLE|SLOW_PACKET|DO_NOT_FORWARD"); + + myFileNumber = 0; + // snag our base dir and make sure we have enough room for a / + strncpy(myBaseDir, topDir, sizeof(myBaseDir) - 2); + myBaseDir[sizeof(myBaseDir) - 2] = '\0'; + // make sure it has a slash + ArUtil::appendSlash(myBaseDir, sizeof(myBaseDir)); + // make sure the slashes go the right direction + ArUtil::fixSlashes(myBaseDir, sizeof(myBaseDir)); + // snag our base dir and make sure we have enough room for a / + strncpy(myTempDir, tempDir, sizeof(myTempDir) - 2); + myTempDir[sizeof(myTempDir) - 2] = '\0'; + // make sure it has a slash + ArUtil::appendSlash(myTempDir, sizeof(myTempDir)); + // make sure the slashes go the right direction + ArUtil::fixSlashes(myTempDir, sizeof(myTempDir)); +} + +AREXPORT ArServerFileFromClient::~ArServerFileFromClient() +{ + +} + + +AREXPORT void ArServerFileFromClient::putFile(ArServerClient *client, + ArNetPacket *packet) +{ + internalPutFile(client, packet, false, false); +} + +AREXPORT void ArServerFileFromClient::putFileInterleaved + (ArServerClient *client, + ArNetPacket *packet) +{ + internalPutFile(client, packet, true, false); +} + +AREXPORT void ArServerFileFromClient::putFileWithTimestamp + (ArServerClient *client, + ArNetPacket *packet) +{ + internalPutFile(client, packet, false, true); +} + +AREXPORT void ArServerFileFromClient::putFileWithTimestampInterleaved + (ArServerClient *client, + ArNetPacket *packet) +{ + internalPutFile(client, packet, true, true); +} + +AREXPORT void ArServerFileFromClient::internalPutFile(ArServerClient *client, + ArNetPacket *packet, + bool interleaved, + bool isSetTimestamp) +{ + ArNetPacket sendPacket; + std::list::iterator fit; + std::map::iterator it; + + FileInfo *info = NULL; + + std::string fileName; + char fileNameRaw[2048]; + fileNameRaw[0] = '\0'; + + ArTypes::UByte2 doing = packet->bufToUByte2(); + + packet->bufToStr(fileNameRaw, sizeof(fileNameRaw)); + if (doing == 0) + { + char directoryRaw[2048]; + directoryRaw[0] = '\0'; + char fileNamePart[2048]; + fileNamePart[0] = '\0'; + if (!ArUtil::getDirectory(fileNameRaw, + directoryRaw, + sizeof(directoryRaw)) || + !ArUtil::getFileName(fileNameRaw, + fileNamePart, + sizeof(fileNamePart))) + { + ArLog::log(ArLog::Normal, + "ArServerFileFromClient: Problem with filename '%s'", + fileNameRaw); + sendPacket.uByte2ToBuf(4); + sendPacket.strToBuf(fileNameRaw); + client->sendPacketTcp(&sendPacket); + // just added this 4/5/06 + return; + } + +// ArUtil::appendSlash(directoryRaw, sizeof(directoryRaw)); + + char directory[2048]; + printf("DirectoryRaw %s\n", directoryRaw); + if (strlen(directoryRaw) == 0) + { + //strcpy(directory, "."); + strcpy(directory, myBaseDir); + } + else if (!ArUtil::matchCase(myBaseDir, + directoryRaw, + directory, + sizeof(directory))) + { + ArLog::log(ArLog::Normal, + "ArServerFileFromClient: Bad directory for '%s'", + fileNameRaw); + sendPacket.uByte2ToBuf(3); + sendPacket.strToBuf(fileNameRaw); + client->sendPacketTcp(&sendPacket); + return; + } + + char tmpDir[2048]; + tmpDir[0] = '\0'; + //sprintf(tmpDir, "%s", tmpDir, directory); + strcpy(tmpDir, directory); + ArUtil::appendSlash(tmpDir, sizeof(tmpDir)); + char matchedFileName[2048]; + + if (ArUtil::matchCase(tmpDir, fileNamePart, + matchedFileName, + sizeof(matchedFileName))) + { + fileName = tmpDir; + fileName += matchedFileName; + //printf("matched from %s %s\n", tmpDir, matchedFileName); + } + else + { + fileName = tmpDir; + fileName += fileNamePart; + //printf("unmatched from %s %s\n", tmpDir, fileNamePart); + } + + ArLog::log(ArLog::Normal, + "ArServerFileFromClient: Checking file %s (as %s)", + fileNameRaw, fileName.c_str()); + + for (it = myMap.begin(); it != myMap.end(); it++) + { + info = (*it).second; + // see if a client is messing with this file + if (ArUtil::strcasecmp(info->myRealFileName, fileName) == 0) + { + // see if the other one messing with this timed out, if so let 'em know + if (info->myLastActivity.secSince() > 15) + { + ArLog::log(ArLog::Normal, + "ArServerFileFromClient: Another client wants to start putting file '%s' and old client was inactive", + (*it).first.c_str()); + if (!interleaved) + { + sendPacket.uByte2ToBuf(8); + sendPacket.strToBuf((*it).first.c_str()); + // NOT_EXCLUDING this isn't excluding anymore because it + // used to cause problems... this may cause some + // problems, but hopefully the event doesn't happen much, + // and at least this way things'll be able to retry easier + myServer->broadcastPacketTcp(&sendPacket, "putFile");//, client); + } + myMap.erase((*it).first); + delete info; + break; + } + // otherwise let this guy know its busy + else + { + ArLog::log(ArLog::Normal, + "ArServerFileFromClient: Another client putting file '%s'", + fileNameRaw); + sendPacket.uByte2ToBuf(7); + sendPacket.strToBuf(fileNameRaw); + client->sendPacketTcp(&sendPacket); + return; + } + } + } + ArLog::log(ArLog::Normal, + "ArServerFileFromClient: Receiving file %s (as %s)", + fileNameRaw, fileName.c_str()); + + char tempFileName[3200]; + tempFileName[0] = '\0'; + sprintf(tempFileName, "%sArServerFileFromClient.%d.%d", myTempDir, getpid(), myFileNumber); + myFileNumber++; + + ArLog::log(ArLog::Normal, + "Using temp file name %s\n", tempFileName); + // see if we can open the temp file + FILE *file; + if ((file = ArUtil::fopen(tempFileName, "wb")) != NULL) + { + info = new FileInfo; + info->myRealFileName = fileName; + info->myTempFileName = tempFileName; + info->myFile = file; + info->myStartedTransfer.setToNow(); + info->myLastActivity.setToNow(); + // We can compare against this client pointer but we cannot + // access anything on it since it could have disconnected and be + // an invalid pointer now + info->myClient = client; + info->myClientCreationTime = client->getCreationTime(); + if (isSetTimestamp) { + info->myFileTimestamp = packet->bufToByte4(); + + char timeBuf[500]; + strftime(timeBuf, sizeof(timeBuf), "%c", localtime(&info->myFileTimestamp)); + + ArLog::log(ArLog::Normal, + "ArServerFileFromClient will set timestamp to %s", + timeBuf); + } + else { + info->myFileTimestamp = -1; + } + + myMap[fileNameRaw] = info; + if (interleaved) + { + //printf("Sending continue\n"); + sendPacket.uByte2ToBuf(10); + sendPacket.strToBuf(fileNameRaw); + client->sendPacketTcp(&sendPacket); + } + } + else + { + ArLog::logErrorFromOS(ArLog::Normal, + "ArServerFileFromClient: Can't open tmp file for '%s' (tried '%s')", + fileNameRaw, tempFileName); + sendPacket.uByte2ToBuf(5); + sendPacket.strToBuf(fileNameRaw); + client->sendPacketTcp(&sendPacket); + return; + } + } + else if (doing == 1) + { + // see if we can find this file + if ((it = myMap.find(fileNameRaw)) == myMap.end()) + { + ArLog::log(ArLog::Normal, + "ArServerFileFromClient: Couldn't find entry for '%s'", + fileNameRaw); + sendPacket.uByte2ToBuf(9); + sendPacket.strToBuf(fileNameRaw); + client->sendPacketTcp(&sendPacket); + return; + } + info = (*it).second; + + // make sure this client is the one sending the file, otherwise + // just ignore it + if (info->myClient != client || + !info->myClientCreationTime.isAt(client->getCreationTime())) + { + ArLog::log(ArLog::Normal, + "ArServerFileFromClient: Got contents packet for file '%s' from the wrong client, ignoring it", + fileNameRaw); + // we don't send back a packet here, because we already did in + // the 0 command (starting send), but the client ignored it + // (probably cause it was doing a fast/stacked file transfer) + return; + } + + // write the data to the file and increment last activity + ArTypes::UByte4 numBytes; + char buf[32000]; + numBytes = packet->bufToUByte4(); + packet->bufToData(buf, numBytes); + fwrite(buf, 1, numBytes, info->myFile); + info->myLastActivity.setToNow(); + + if (interleaved) + { + sendPacket.uByte2ToBuf(10); + sendPacket.strToBuf(fileNameRaw); + client->sendPacketTcp(&sendPacket); + } + ArLog::log(ArLog::Verbose, "Continuing put file %s (%d bytes)", + fileNameRaw, numBytes); + + } + else if (doing == 2) + { + // see if we can find this file + if ((it = myMap.find(fileNameRaw)) == myMap.end()) + { + ArLog::log(ArLog::Normal, "ArUtil: Couldn't find entry for '%s'", fileNameRaw); + sendPacket.uByte2ToBuf(9); + sendPacket.strToBuf(fileNameRaw); + client->sendPacketTcp(&sendPacket); + return; + } + info = (*it).second; + + // make sure this client is the one sending the file, otherwise + // just ignore it + if (info->myClient != client || + !info->myClientCreationTime.isAt(client->getCreationTime())) + { + ArLog::log(ArLog::Normal, + "ArServerFileFromClient: Got end packet for file '%s' from the wrong client, ignoring it", + fileNameRaw); + // we don't send back a packet here, because we already did in + // the 0 command (starting send), but the client ignored it + // (probably cause it was doing a fast/stacked file transfer) + return; + } + + fclose(info->myFile); + info->myFile = NULL; + + char systemBuf[6400]; +#ifndef WIN32 + char *mvName = "mv -f"; +#else + char *mvName = "move"; +#endif + sprintf(systemBuf, "%s \"%s\" \"%s\"", mvName, info->myTempFileName.c_str(), + info->myRealFileName.c_str()); + + + myMovingFileName = info->myRealFileName; + + // call our pre move callbacks + for (fit = myPreMoveCallbacks.begin(); + fit != myPreMoveCallbacks.end(); + fit++) + (*fit)->invoke(); + + // move file + int ret; + if ((ret = system(systemBuf)) == 0) + { + if (isSetTimestamp) { + ArUtil::changeFileTimestamp(info->myRealFileName.c_str(), + info->myFileTimestamp); + } + + sendPacket.uByte2ToBuf(0); + sendPacket.strToBuf(fileNameRaw); + client->sendPacketTcp(&sendPacket); + ArLog::log(ArLog::Normal, "Done with file %s from %s", fileNameRaw, + client->getIPString()); + myMap.erase((*it).first); + delete info; + } + else + { + sendPacket.uByte2ToBuf(6); + sendPacket.strToBuf(fileNameRaw); + client->sendPacketTcp(&sendPacket); + unlink(info->myTempFileName.c_str()); + myMap.erase((*it).first); + delete info; + ArLog::log(ArLog::Normal, "Couldn't move temp file for %s (ret of '%s' is %d)", fileNameRaw, systemBuf, ret); + } + + // call our post move callbacks + for (fit = myPostMoveCallbacks.begin(); + fit != myPostMoveCallbacks.end(); + fit++) { + (*fit)->invoke(); + } + + myMovingFileName = ""; + } + else if (doing == 3) + { + if ((it = myMap.find(fileNameRaw)) == myMap.end()) + { + ArLog::log(ArLog::Normal, "ArUtil: Couldn't find entry to cancel for '%s'", fileNameRaw); + sendPacket.uByte2ToBuf(9); + sendPacket.strToBuf(fileNameRaw); + client->sendPacketTcp(&sendPacket); + return; + } + info = (*it).second; + + // make sure this client is the one sending the file, otherwise + // just ignore it + if (info->myClient != client || + !info->myClientCreationTime.isAt(client->getCreationTime())) + { + ArLog::log(ArLog::Normal, + "ArServerFileFromClient: Got cancel packet for file '%s' from the wrong client, ignoring it", + fileNameRaw); + // we don't send back a packet here, because we already did in + // the 0 command (starting send), but the client ignored it + // (probably cause it was doing a fast/stacked file transfer) + return; + } + + fclose(info->myFile); + info->myFile = NULL; + + unlink(info->myTempFileName.c_str()); + myMap.erase((*it).first); + delete info; + + ArLog::log(ArLog::Normal, "Cancelling file %s", fileNameRaw); + if (interleaved) + { + sendPacket.uByte2ToBuf(11); + sendPacket.strToBuf(fileNameRaw); + client->sendPacketTcp(&sendPacket); + } + } + else + { + ArLog::log(ArLog::Normal, "Unknown command %d for file %s", doing, + fileNameRaw); + } +} + +AREXPORT void ArServerFileFromClient::addPreMoveCallback( + ArFunctor *functor, ArListPos::Pos position) +{ + if (position == ArListPos::FIRST) + myPreMoveCallbacks.push_front(functor); + else if (position == ArListPos::LAST) + myPreMoveCallbacks.push_back(functor); + else + ArLog::log(ArLog::Terse, + "ArServerFileFromClient::addPreMoveCallback: Invalid position."); +} + +AREXPORT void ArServerFileFromClient::remPreMoveCallback( + ArFunctor *functor) +{ + myPreMoveCallbacks.remove(functor); +} + +AREXPORT void ArServerFileFromClient::addPostMoveCallback( + ArFunctor *functor, ArListPos::Pos position) +{ + if (position == ArListPos::FIRST) + myPostMoveCallbacks.push_front(functor); + else if (position == ArListPos::LAST) + myPostMoveCallbacks.push_back(functor); + else + ArLog::log(ArLog::Terse, + "ArServerFileFromClient::addPostMoveCallback: Invalid position."); +} + +AREXPORT void ArServerFileFromClient::remPostMoveCallback( + ArFunctor *functor) +{ + myPostMoveCallbacks.remove(functor); +} + + +AREXPORT ArServerDeleteFileOnServer::ArServerDeleteFileOnServer( + ArServerBase *server, const char *topDir) : + myDeleteFileCB(this, &ArServerDeleteFileOnServer::deleteFile) +{ + myServer = server; + myServer->addData("deleteFile", + "Deletes a file (use ArClientDeleteFileOnServer instead of calling this directly since this interface may change)", + &myDeleteFileCB, "string: file to delete", + "ubyte2: return code, 0 = good (deleted file file), 1 = tried to go outside allowed area, 2 = no such file (or can't read it), 3 = empty file name, string: fileDeleted", + "FileAccess", "RETURN_SINGLE|SLOW_PACKET"); + + // snag our base dir and make sure we have enough room for a / + strncpy(myBaseDir, topDir, sizeof(myBaseDir) - 2); + myBaseDir[sizeof(myBaseDir) - 2] = '\0'; + // make sure it has a slash + ArUtil::appendSlash(myBaseDir, sizeof(myBaseDir)); + // make sure the slashes go the right direction + ArUtil::fixSlashes(myBaseDir, sizeof(myBaseDir)); +} + +AREXPORT ArServerDeleteFileOnServer::~ArServerDeleteFileOnServer() +{ + +} + + + +AREXPORT void ArServerDeleteFileOnServer::deleteFile(ArServerClient *client, + ArNetPacket *packet) +{ + ArNetPacket sendPacket; + size_t ui; + size_t len; + std::list::iterator fit; + char fileNameRaw[2048]; + packet->bufToStr(fileNameRaw, sizeof(fileNameRaw)); + + // should check for operation here, but thats not implemented yet + + char fileNameCooked[2048]; + strcpy(fileNameCooked, fileNameRaw); + ArUtil::fixSlashes(fileNameCooked, sizeof(fileNameCooked)); + + + char fileName[2048]; + if (!ArUtil::matchCase(myBaseDir, fileNameCooked, + fileName, sizeof(fileName))) + { + ArLog::log(ArLog::Normal, + "ArServerDeleteFileOnServer: can't read file '%s'", + fileNameRaw); + sendPacket.uByte2ToBuf(2); + sendPacket.strToBuf(fileNameRaw); + client->sendPacketTcp(&sendPacket); + return; + } + + len = strlen(fileName); + // first advance to the first non space + for (ui = 0; + ui < len && fileName[ui] != '\0' && isspace(fileName[ui]); + ui++); + + char *fileStr = new char[len + 3]; + + // now copy in the rest + strncpy(fileStr, fileName, len - ui); + // make sure its null terminated + fileStr[len - ui] = '\0'; + + if (fileStr[0] == '/' || fileStr[0] == '~' || + fileStr[0] == '\\' || strstr(fileStr, "..") != NULL) + { + ArLog::log(ArLog::Normal, + "ArServerDeleteFileOnServer: '%s' tried to access outside allowed area", + fileStr); + delete[] fileStr; + sendPacket.uByte2ToBuf(1); + sendPacket.strToBuf(fileNameRaw); + client->sendPacketTcp(&sendPacket); + return; + } + + if (strlen(fileStr) > 0) + { + ArUtil::fixSlashes(fileStr, len + 2); + } + else + { + ArLog::log(ArLog::Normal, + "ArServerDeleteFileOnServer: can't delete file, empty filename"); + delete[] fileStr; + sendPacket.uByte2ToBuf(3); + sendPacket.strToBuf(fileNameRaw); + client->sendPacketTcp(&sendPacket); + return; + } + + // walk from our base down and try to find the first by name + // ignoring case + + // put our base and where we want to go together + std::string wholeName; + wholeName = myBaseDir; + wholeName += fileStr; + + delete[] fileStr; + + ArLog::log(ArLog::Verbose, + "ArServerDeleteFileOnServer: Trying to delete %s from base %s", + wholeName.c_str(), myBaseDir); + + myDeletingFileName = fileNameRaw; + + // call our pre delete callbacks + for (fit = myPreDeleteCallbacks.begin(); + fit != myPreDeleteCallbacks.end(); + fit++) + (*fit)->invoke(); + + if (unlink(wholeName.c_str()) == 0) + { + ArLog::log(ArLog::Normal, + "ArServerDeleteFileOnServer: Deleted file %s for %s", + fileName, client->getIPString()); + sendPacket.uByte2ToBuf(0); + sendPacket.strToBuf(fileNameRaw); + client->sendPacketTcp(&sendPacket); + } + else + { + ArLog::log(ArLog::Normal, + "ArServerDeleteFileOnServer: can't unlink file '%s'", fileName); + sendPacket.uByte2ToBuf(2); + sendPacket.strToBuf(fileNameRaw); + client->sendPacketTcp(&sendPacket); + } + + // call our post delete callbacks + for (fit = myPostDeleteCallbacks.begin(); + fit != myPostDeleteCallbacks.end(); + fit++) + (*fit)->invoke(); + + myDeletingFileName = ""; +} + +AREXPORT void ArServerDeleteFileOnServer::addPreDeleteCallback( + ArFunctor *functor, ArListPos::Pos position) +{ + if (position == ArListPos::FIRST) + myPreDeleteCallbacks.push_front(functor); + else if (position == ArListPos::LAST) + myPreDeleteCallbacks.push_back(functor); + else + ArLog::log(ArLog::Terse, + "ArServerDeleteFileOnServer::addPreDeleteCallback: Invalid position."); +} + +AREXPORT void ArServerDeleteFileOnServer::remPreDeleteCallback( + ArFunctor *functor) +{ + myPreDeleteCallbacks.remove(functor); +} + +AREXPORT void ArServerDeleteFileOnServer::addPostDeleteCallback( + ArFunctor *functor, ArListPos::Pos position) +{ + if (position == ArListPos::FIRST) + myPostDeleteCallbacks.push_front(functor); + else if (position == ArListPos::LAST) + myPostDeleteCallbacks.push_back(functor); + else + ArLog::log(ArLog::Terse, + "ArServerDeleteFileOnServer::addPostDeleteCallback: Invalid position."); +} + +AREXPORT void ArServerDeleteFileOnServer::remPostDeleteCallback( + ArFunctor *functor) +{ + myPostDeleteCallbacks.remove(functor); +} + +#endif // WIN32 diff --git a/Legacy/Aria/ArNetworking/src/ArServerHandlerCamera.cpp b/Legacy/Aria/ArNetworking/src/ArServerHandlerCamera.cpp new file mode 100644 index 0000000..6a2b996 --- /dev/null +++ b/Legacy/Aria/ArNetworking/src/ArServerHandlerCamera.cpp @@ -0,0 +1,1306 @@ +#include "Aria.h" +#include "ArExport.h" +#include "ArServerHandlerCamera.h" + +const char *ArServerHandlerCamera::CONTROL_COMMAND_GROUP = "CameraControl"; +const char *ArServerHandlerCamera::INFO_COMMAND_GROUP = "CameraInfo"; +const char *ArServerHandlerCamera::NO_ARGS = "None"; + +//#define DEBUG_ARSERVERHANDLERCAMERA + +#if (defined(_DEBUG) && defined(DEBUG_ARSERVERHANDLERCAMERA)) +#define IFDEBUG(code) {code;} +#else +#define IFDEBUG(code) +#endif + +/** + @param robot The robot we're attached to (mostly used for locking the camera before sending commands) + @param server The server we're putting commands into + @param camera The camera we're going to command and give information from... it can be NULL in which case no commands are added + **/ +AREXPORT ArServerHandlerCamera::ArServerHandlerCamera(ArServerBase *server, + ArRobot *robot, + ArPTZ *camera) : + ArCameraCollectionItem(), + myRobot(robot), + myServer(server), + myCamera(camera), + myCameraName(), + myCameraCollection(NULL), + myCommandToPacketNameMap(), + myCommandToIntervalMap(), + myCommandToCBMap(), + + myUserTaskCB(this, &ArServerHandlerCamera::userTask), + myCameraCB(this, &ArServerHandlerCamera::camera), + myCameraAbsCB(this, &ArServerHandlerCamera::cameraAbs), + myCameraUpdateCB(this, &ArServerHandlerCamera::cameraUpdate), + myCameraInfoCB(this, &ArServerHandlerCamera::cameraInfo) +{ + init(); +} + +AREXPORT ArServerHandlerCamera::ArServerHandlerCamera + (const char *cameraName, + ArServerBase *server, + ArRobot *robot, + ArPTZ *camera, + ArCameraCollection *collection) : + ArCameraCollectionItem(), + myRobot(robot), + myServer(server), + myCamera(camera), + myCameraName(cameraName), + myCameraCollection(collection), + myCommandToPacketNameMap(), + myCommandToIntervalMap(), + myCommandToCBMap(), + + myModeMutex(), + myCameraMode(CAMERA_MODE_POSITION), + myCameraModeNameMap(), + myCameraModePacket(), + myLookAtPoint(), + myPointResetZoom(false), + myGoal(), + myGoalAchieved(true), + myGoalAchievedLast(false), + myGoalResetZoom(false), + + myUserTaskCB(this, &ArServerHandlerCamera::userTask), + myCameraCB(this, &ArServerHandlerCamera::camera), + myCameraAbsCB(this, &ArServerHandlerCamera::cameraAbs), + myCameraUpdateCB(this, &ArServerHandlerCamera::cameraUpdate), + myCameraInfoCB(this, &ArServerHandlerCamera::cameraInfo) +{ + init(); + + if (myCameraCollection != NULL) { + doAddToCameraCollection(*myCameraCollection); + } +} // end ctor + +AREXPORT ArServerHandlerCamera::~ArServerHandlerCamera() +{ + for (std::map *>::iterator iter = + myCommandToCBMap.begin(); + iter != myCommandToCBMap.end(); + iter++) { + + // TODO: REALLY should remove the callback from myServer (but there's currently + // no way to do so... + + delete iter->second; + iter->second = NULL; + + } // end for each callback + + myCommandToCBMap.clear(); + +} // end dtor + + +void ArServerHandlerCamera::init() +{ + myModeMutex.setLogName("ArServerHandlerCamera::myModeMutex"); + + createCommandNames(); + + createCommandCBs(); + + addAllCommandsToServer(); + + myCameraMode = CAMERA_MODE_POSITION; + myGoalAchieved = true; + myUserTaskCB.setName("ArServerHandlerCamera"); + if (myRobot != NULL) + myRobot->addUserTask("ArServerHandlerCamera", 50, &myUserTaskCB); + + myCameraModeNameMap[CAMERA_MODE_POSITION] = "Position"; + myCameraModeNameMap[CAMERA_MODE_LOOK_AT_GOAL] = "LookAtGoal"; + myCameraModeNameMap[CAMERA_MODE_LOOK_AT_POINT] = "LookAtPoint"; + +} // end method init + + +AREXPORT const char *ArServerHandlerCamera::getCameraName() +{ + return myCameraName.c_str(); +} + +void ArServerHandlerCamera::createCommandNames() +{ + myCommandToPacketNameMap[ArCameraCommands::GET_CAMERA_DATA] = "getCameraData"; + myCommandToPacketNameMap[ArCameraCommands::GET_CAMERA_INFO] = "getCameraInfo"; + myCommandToPacketNameMap[ArCameraCommands::SET_CAMERA_ABS] = "setCameraAbs"; + myCommandToPacketNameMap[ArCameraCommands::SET_CAMERA_PCT] = "setCameraPct"; + myCommandToPacketNameMap[ArCameraCommands::SET_CAMERA_REL] = "setCameraRel"; + + myCommandToPacketNameMap[ArCameraCommands::GET_CAMERA_MODE_LIST] = "getCameraModeList"; + myCommandToPacketNameMap[ArCameraCommands::CAMERA_MODE_UPDATED] = "cameraModeUpdated"; + myCommandToPacketNameMap[ArCameraCommands::SET_CAMERA_MODE] = "setCameraMode"; + myCommandToPacketNameMap[ArCameraCommands::RESET_CAMERA] = "resetCamera"; + + if (!myCameraName.empty()) { + + for (std::map::iterator iter = myCommandToPacketNameMap.begin(); + iter != myCommandToPacketNameMap.end(); + iter++) { + + std::string baseCommandName = iter->second; + iter->second = baseCommandName + myCameraName; + + } // end for each command + } // end if camera name specified + + + // Do these afterwards so that the name does NOT get mangled. (??) + // This preserves some aspect of backwards compatibility... + + myCommandToPacketNameMap[ArCameraCommands::GET_CAMERA_DATA_INT] = "cameraUpdate"; + myCommandToPacketNameMap[ArCameraCommands::GET_CAMERA_INFO_INT] = "cameraInfo"; + myCommandToPacketNameMap[ArCameraCommands::SET_CAMERA_ABS_INT] = "cameraAbs"; + myCommandToPacketNameMap[ArCameraCommands::SET_CAMERA_REL_INT] = "camera"; + myCommandToPacketNameMap[ArCameraCommands::SET_CAMERA_PCT_INT] = "cameraPct"; + +} // end method createCommandNames + + +void ArServerHandlerCamera::createCommandCBs() +{ + + myCommandToCBMap[ArCameraCommands::GET_CAMERA_DATA] = + new ArFunctor2C + (this, + &ArServerHandlerCamera::handleGetCameraData); + // Default interval for requesting camera info + myCommandToIntervalMap[ArCameraCommands::GET_CAMERA_DATA] = 100; + + myCommandToCBMap[ArCameraCommands::GET_CAMERA_INFO] = + new ArFunctor2C + (this, + &ArServerHandlerCamera::handleGetCameraInfo); + + myCommandToCBMap[ArCameraCommands::SET_CAMERA_ABS] = + new ArFunctor2C + (this, + &ArServerHandlerCamera::handleSetCameraAbs); + + myCommandToCBMap[ArCameraCommands::SET_CAMERA_PCT] = + new ArFunctor2C + (this, + &ArServerHandlerCamera::handleSetCameraPct); + + myCommandToCBMap[ArCameraCommands::SET_CAMERA_REL] = + new ArFunctor2C + (this, + &ArServerHandlerCamera::handleSetCameraRel); + + myCommandToCBMap[ArCameraCommands::GET_CAMERA_DATA_INT] = + new ArFunctor2C + (this, + &ArServerHandlerCamera::cameraUpdate); + + myCommandToCBMap[ArCameraCommands::GET_CAMERA_INFO_INT] = + new ArFunctor2C + (this, + &ArServerHandlerCamera::cameraInfo); + + myCommandToCBMap[ArCameraCommands::SET_CAMERA_ABS_INT] = + new ArFunctor2C + (this, + &ArServerHandlerCamera::cameraAbs); + + myCommandToCBMap[ArCameraCommands::SET_CAMERA_REL_INT] = + new ArFunctor2C + (this, + &ArServerHandlerCamera::camera); + + myCommandToCBMap[ArCameraCommands::SET_CAMERA_PCT_INT] = + new ArFunctor2C + (this, + &ArServerHandlerCamera::cameraPct); + + myCommandToCBMap[ArCameraCommands::GET_CAMERA_MODE_LIST] = + new ArFunctor2C + (this, + &ArServerHandlerCamera::handleGetCameraModeList); + myCommandToCBMap[ArCameraCommands::CAMERA_MODE_UPDATED] = + new ArFunctor2C + (this, + &ArServerHandlerCamera::handleCameraModeUpdated); + myCommandToCBMap[ArCameraCommands::SET_CAMERA_MODE] = + new ArFunctor2C + (this, + &ArServerHandlerCamera::handleSetCameraMode); + myCommandToCBMap[ArCameraCommands::RESET_CAMERA] = + new ArFunctor2C + (this, + &ArServerHandlerCamera::handleResetCamera); + +} // end method createCommandCBs + + +void ArServerHandlerCamera::addAllCommandsToServer() +{ + if (myServer == NULL) { + ArLog::log(ArLog::Normal, + "ArServerHandlerCamera::addAllCommandsToServer() cannot add to NULL server"); + return; + } + + // + addCommandToServer + (ArCameraCommands::GET_CAMERA_DATA, + "Get \"double\" information about camera position. (factor == 100)", + NO_ARGS, + "byte2: pan * factor, byte2: tilt * factor, byte2: zoomPercent * factor (optional)", + INFO_COMMAND_GROUP); + + addCommandToServer + (ArCameraCommands::GET_CAMERA_INFO, + "Get (\"double\") information about the camera's pan, tilt, and (optional) zoom ranges. (factor == 100)", + NO_ARGS, + "byte2: minPan * factor, byte2: maxPan * factor byte2: minTilt * factor, byte2: maxTilt * factor, byte2: minZoom * factor, byte2: maxZoom * factor, byte: isZoomAvailable", + INFO_COMMAND_GROUP); + + addCommandToServer + (ArCameraCommands::SET_CAMERA_ABS, + "Sends absolute (\"double\") pan, tilt, and zoom (optional) commands to the camera. (factor == 100)", + NO_ARGS, + "byte2: pan * factor, byte2: tilt * factor, byte2: zoom * factor (optional)", + CONTROL_COMMAND_GROUP); + + if ((myCamera != NULL) && (myCamera->canGetFOV())) { + addCommandToServer + (ArCameraCommands::SET_CAMERA_PCT, + "Sends (\"double\") pan, tilt, and zoom (optional) commands to point camera, as percent of visible frame. (factor == 100)", + NO_ARGS, + "byte2: panOffset * factor, byte2: tiltOffset * factor, byte2: zoom * factor (optional)", + CONTROL_COMMAND_GROUP); + } + else { + removeCommand(ArCameraCommands::SET_CAMERA_PCT); + } + + addCommandToServer + (ArCameraCommands::SET_CAMERA_REL, + "Sends (\"double\") pan, tilt, and zoom (optional) commands to the camera, relative to its current position. (factor == 100)", + NO_ARGS, + "byte2: relPan * factor, byte2: relTilt * factor, byte2: relZoom * factor (optional)", + CONTROL_COMMAND_GROUP); + + addCommandToServer(ArCameraCommands::GET_CAMERA_MODE_LIST, + "Gets the list of modes this camera supports", + NO_ARGS, + "ubyte2: numModes; string: modeName", + INFO_COMMAND_GROUP); + + + addCommandToServer(ArCameraCommands::CAMERA_MODE_UPDATED, + "Sent whenever the camera mode is updated", + NO_ARGS, + "string: modeName; ", + INFO_COMMAND_GROUP); + + addCommandToServer(ArCameraCommands::SET_CAMERA_MODE, + "Sets the mode of the camera", + "string: modeName; ", + NO_ARGS, + CONTROL_COMMAND_GROUP); + + addCommandToServer(ArCameraCommands::RESET_CAMERA, + "Resets the camera to 0 0 0 and may reinitialize it (depending on camera)", + NO_ARGS, + NO_ARGS, + CONTROL_COMMAND_GROUP); + + + // Continue to support old-style integer commands for backward compatibility.... + + addCommandToServer + (ArCameraCommands::GET_CAMERA_DATA_INT, + "Get (integer) information about camera position", + NO_ARGS, + "byte2: pan, byte2: tilt, byte2: zoom (optional)", + INFO_COMMAND_GROUP); + + addCommandToServer + (ArCameraCommands::GET_CAMERA_INFO_INT, + "Get (integer) information about the camera's pan, tilt, and (optional) zoom ranges", + NO_ARGS, + "byte2: minPan, byte2: maxPan byte2: minTilt, byte2: maxTilt, byte2: minZoom, byte2: maxZoom, byte: isZoomAvailable", + INFO_COMMAND_GROUP); + + addCommandToServer + (ArCameraCommands::SET_CAMERA_REL_INT, + "Sends (integer) pan, tilt, and zoom (optional) commands to the camera, relative to its current position", + NO_ARGS, + "byte: relPan, byte: relTilt, byte: relZoom (optional)", + CONTROL_COMMAND_GROUP); + + addCommandToServer + (ArCameraCommands::SET_CAMERA_ABS_INT, + "Sends absolute (integer) pan, tilt, and zoom (optional) commands to the camera", + NO_ARGS, + "byte: pan, byte: tilt, byte: zoom (optional)", + CONTROL_COMMAND_GROUP); + + addCommandToServer + (ArCameraCommands::SET_CAMERA_PCT_INT, + "Sends (integer) pan, tilt commands to the camera, as percent of visible frame", + NO_ARGS, + "byte: pan, byte: tilt, byte: zoom (optional)", + CONTROL_COMMAND_GROUP); + +} // end method addToServer + + +void ArServerHandlerCamera::addCommandToServer(const char *command, + const char *description, + const char *argumentDescription, + const char *returnDescription, + const char *commandGroup) +{ + if (command == NULL) { + ArLog::log(ArLog::Normal, + "ArServerHandlerCamera::addCommandToServer() cannot add NULL command"); + return; + } + + std::map::iterator iter = + myCommandToPacketNameMap.find(command); + + if (iter == myCommandToPacketNameMap.end()) { + ArLog::log(ArLog::Normal, + "ArServerHandlerCamera::addCommandToServer() cannot find packet name for command %s", + command); + return; + } + + const char *packetName = iter->second.c_str(); + ArFunctor2 *callback = NULL; + + std::map *>::iterator cbIter = + myCommandToCBMap.find(command); + if (cbIter != myCommandToCBMap.end()) { + callback = cbIter->second; + } + if (callback == NULL) { + ArLog::log(ArLog::Normal, + "ArServerHandlerCamera::addCommandToServer() cannot find callback for command %s", + command); + } + + bool isSuccess = true; + + /** + * It'd be kind of nice if we could do something along the following lines + * so that the PTZ controls do not show up in ME. (Not entirely sure how + * though because - at least in the case of VCC4 - there's a four second + * timeout before the comm is deemed unidirectional.) + if ((myCamera != NULL) && + (!myCamera->isBidirectionalComm()) && + (strcmp(commandGroup, CONTROL_COMMAND_GROUP) == 0)) { + isSuccess = false; + } + **/ + + if (isSuccess) { + isSuccess = myServer->addData + (packetName, + description, + callback, + argumentDescription, + returnDescription, + commandGroup, "RETURN_SINGLE"); + } + if (!isSuccess) { + ArLog::log(ArLog::Normal, + "ArServerHandlerCamera::addCommandToServer() error adding server handler for packet %s", + packetName); + removeCommand(command); + } + +} // end method addCommandToServer + + +void ArServerHandlerCamera::doAddToCameraCollection(ArCameraCollection &collection) +{ + if (myCameraName.empty()) { + + return; + } // end if no camera name + + const char *cameraName = myCameraName.c_str(); + if (!collection.exists(cameraName)) { + + return; + } // end if camera not yet created + + for (std::map::iterator iter = myCommandToPacketNameMap.begin(); + iter != myCommandToPacketNameMap.end(); + iter++) { + + const char *command = iter->first.c_str(); + const char *packetName = iter->second.c_str(); + + int requestInterval = -1; + std::map::iterator nIter = myCommandToIntervalMap.find(command); + if (nIter != myCommandToIntervalMap.end()) { + requestInterval = nIter->second; + } + + bool isSuccess = collection.addCameraCommand(cameraName, + command, + packetName, + requestInterval); + + if (!isSuccess) { + + } // end if error occurred + + } // end for each command +} // end method doAddToCameraCollection + + +void ArServerHandlerCamera::removeCommand(const char *command) +{ + std::map::iterator iter = myCommandToPacketNameMap.find(command); + if (iter != myCommandToPacketNameMap.end()) { + myCommandToPacketNameMap.erase(iter); + } + + std::map *>::iterator cbIter = + myCommandToCBMap.find(command); + if (cbIter != myCommandToCBMap.end()) { + delete cbIter->second; + cbIter->second = NULL; + myCommandToCBMap.erase(cbIter); + } + +} // end method removeCommand + + +AREXPORT void ArServerHandlerCamera::addToCameraCollection(ArCameraCollection &collection) +{ + doAddToCameraCollection(collection); +} + +// ----------------------------------------------------------------------------- +// Packet Handlers: +// ----------------------------------------------------------------------------- + +AREXPORT void ArServerHandlerCamera::handleGetCameraData(ArServerClient *client, + ArNetPacket *packet) +{ + if ((client == NULL) || (myRobot == NULL) || (myCamera == NULL)) { + return; + } + + ArNetPacket sendPacket; + + myRobot->lock(); + double pan = myCamera->getPan(); + double tilt = myCamera->getTilt(); + double zoom = (getCurrentZoomRatio() * 100.0); + + myRobot->unlock(); + + addDoubleToPacket(pan, sendPacket); + addDoubleToPacket(tilt, sendPacket); + addDoubleToPacket(zoom, sendPacket); + + client->sendPacketUdp(&sendPacket); + +} // end method handleGetCameraData + + +AREXPORT void ArServerHandlerCamera::handleGetCameraInfo(ArServerClient *client, + ArNetPacket *packet) +{ + if ((client == NULL) || (myRobot == NULL) || (myCamera == NULL)) { + return; + } + + ArNetPacket sendPacket; + + myRobot->lock(); + + double minPan = myCamera->getMaxNegPan(); + double maxPan = myCamera->getMaxPosPan(); + double minTilt = myCamera->getMaxNegTilt(); + double maxTilt = myCamera->getMaxPosTilt(); + double minZoom = 0; + double maxZoom = 100; + bool isZoomAvailable = myCamera->canZoom(); + + ArLog::log(ArLog::Verbose, + "ArServerHandlerCamera: client requested camera info (my camera name is %s), returning: minPan %f maxPan %f minTilt %f maxTilt %f minZoom %f maxZoom %f isZoomAvailable %d", + myCameraName.c_str(), minPan, maxPan, minTilt, maxTilt, minZoom, maxZoom, isZoomAvailable); + + myRobot->unlock(); + + addDoubleToPacket(minPan, sendPacket); + addDoubleToPacket(maxPan, sendPacket); + addDoubleToPacket(minTilt, sendPacket); + addDoubleToPacket(maxTilt, sendPacket); + addDoubleToPacket(minZoom, sendPacket); + addDoubleToPacket(maxZoom, sendPacket); + + sendPacket.byteToBuf(isZoomAvailable); + + client->sendPacketUdp(&sendPacket); + +} // end method handleGetCameraInfo + + +AREXPORT void ArServerHandlerCamera::handleSetCameraAbs(ArServerClient *client, + ArNetPacket *packet) +{ + if ((packet == NULL) || (myRobot == NULL) || (myCamera == NULL)) { + return; + } + + double pan = getDoubleFromPacket(*packet); + double tilt = getDoubleFromPacket(*packet); + double zoom = getDoubleFromPacket(*packet); + + setCameraAbs(pan, tilt, zoom); + +} // end method handleSetCameraAbs + + +AREXPORT void ArServerHandlerCamera::handleSetCameraRel(ArServerClient *client, + ArNetPacket *packet) +{ + if (packet == NULL) { + return; + } + + //double invAtZoom = 1; + + double pan = getDoubleFromPacket(*packet); + double tilt = getDoubleFromPacket(*packet); + double zoom = getDoubleFromPacket(*packet); + + setCameraRel(pan, tilt, zoom); + +} // end method handleSetCameraRel + + +AREXPORT void ArServerHandlerCamera::handleSetCameraPct(ArServerClient *client, + ArNetPacket *packet) +{ + + if (!myCamera->canGetFOV()) + { + ArLog::log(ArLog::Normal, "ArServerHandlerCamera::cameraPct called when camera can't get the FOV"); + return; + } + // Values range -100 to 100. 0 indicates no change. + //int panPct = packet->bufToByte(); + //int tiltPct = -packet->bufToByte(); + + double panPct = getDoubleFromPacket(*packet); + double tiltPct = -(getDoubleFromPacket(*packet)); + + setCameraPct(panPct, tiltPct); + +} // end method handleSetCameraPct + + +// ---------------------------------------------------------------------------- +// Old Packet Handlers (integers, for backwards compatibility) +// ---------------------------------------------------------------------------- + + +AREXPORT void ArServerHandlerCamera::camera(ArServerClient *client, + ArNetPacket *packet) +{ + + //double invAtZoom = 1; + + int pan = packet->bufToByte(); + int tilt = packet->bufToByte(); + int zoom = packet->bufToByte(); + + setCameraRel(pan, tilt, zoom); + +} // end method camera + + +AREXPORT void ArServerHandlerCamera::cameraAbs(ArServerClient *client, + ArNetPacket *packet) +{ + + int pan = packet->bufToByte(); + int tilt = packet->bufToByte(); + int zoom = packet->bufToByte(); + + setCameraAbs(pan, tilt, zoom); + +} // end method cameraAbs + + +AREXPORT void ArServerHandlerCamera::cameraPct(ArServerClient *client, + ArNetPacket *packet) +{ + + if (!myCamera->canGetFOV()) + { + ArLog::log(ArLog::Normal, "ArServerHandlerCamera::cameraPct called when camera can't get the FOV"); + return; + } + // Values range -100 to 100. 0 indicates no change. + int panPct = packet->bufToByte(); + int tiltPct = -packet->bufToByte(); + + setCameraPct(panPct, tiltPct); + +} // end method cameraPct + + +AREXPORT void ArServerHandlerCamera::cameraUpdate(ArServerClient *client, + ArNetPacket *packet) +{ + ArNetPacket send; + + myRobot->lock(); + int pan = ArMath::roundInt(myCamera->getPan()); + int tilt = ArMath::roundInt(myCamera->getTilt()); + int zoom = ArMath::roundInt(myCamera->getZoom()/((double)(myCamera->getMaxZoom() - myCamera->getMinZoom()) + myCamera->getMinZoom()) * 100.0); + + myRobot->unlock(); + + send.byte2ToBuf(pan); + send.byte2ToBuf(tilt); + send.byte2ToBuf(zoom); + client->sendPacketUdp(&send); + +} // end method cameraUpdate + + +AREXPORT void ArServerHandlerCamera::cameraInfo(ArServerClient *client, + ArNetPacket *packet) +{ + ArNetPacket send; + + myRobot->lock(); + + int minPan = ArMath::roundInt(myCamera->getMaxNegPan()); + int maxPan = ArMath::roundInt(myCamera->getMaxPosPan()); + int minTilt = ArMath::roundInt(myCamera->getMaxNegTilt()); + int maxTilt = ArMath::roundInt(myCamera->getMaxPosTilt()); + int minZoom = 0; + int maxZoom = 100; + bool isZoomAvailable = myCamera->canZoom(); + //ArLog::log(ArLog::Normal, "minPan %d maxPan %d minTilt %d maxTilt %d minZoom %d maxZoom %d isZoomAvailable %d", minPan, maxPan, minTilt, maxTilt, minZoom, maxZoom, isZoomAvailable); + + myRobot->unlock(); + + send.byte2ToBuf(minPan); + send.byte2ToBuf(maxPan); + send.byte2ToBuf(minTilt); + send.byte2ToBuf(maxTilt); + send.byte2ToBuf(minZoom); + send.byte2ToBuf(maxZoom); + send.byteToBuf(isZoomAvailable); + + client->sendPacketUdp(&send); + +} // end method cameraInfo + + +/** + @param pan the degrees to pan to (absolute) + @param tilt the degrees to tilt to (absolute) + @param zoom the percent (number between 0 and 100) to pan to (absolute) + @param lockRobot whether to lock the robot or not +**/ + +AREXPORT void ArServerHandlerCamera::setCameraAbs( + double pan, double tilt, double zoom, bool lockRobot) +{ + if (zoom > 100) + zoom = 100; + else if (zoom < 0) + zoom = 0; + + if (lockRobot) + myRobot->lock(); + + cameraModePosition(); + + myCamera->panTilt(pan, tilt); + + double absZoom = myCamera->getMinZoom() + ((zoom / 100.0) * getZoomRange()); + + IFDEBUG(ArLog::log(ArLog::Normal, + "ArServerHandlerCamera::handleSetCameraAbs() p = %f, t = %f, z = %f, calc absZoom = %f", + pan, tilt, zoom, absZoom)); + + myCamera->zoom(ArMath::roundInt(absZoom)); + + if (lockRobot) + myRobot->unlock(); + +} // end method doSetCameraAbs + + +/** + @param pan the degrees to pan to (relative) + @param tilt the degrees to tilt to (relative) + @param zoom the percent (number between 0 and 100) to change pan by (relative) + @param lockRobot whether to lock the robot or not +**/ + +AREXPORT void ArServerHandlerCamera::setCameraRel( + double pan, double tilt, double zoom, bool lockRobot) +{ + if ((myRobot == NULL) || (myCamera == NULL)) { + return; + } + + IFDEBUG(ArLog::log(ArLog::Normal, + "ArServerHandlerCamera::doSetCameraRel() p = %f, t = %f, z = %f", + pan, tilt, zoom)); + + // The camera mode is set to position only if the pan or tilt changed. + + double invAtZoom = 1; + + if (myCamera->getMaxZoom() - myCamera->getMinZoom() != 0) + { + // see what zoom we're at so we can modify total pan and tilt amounts by it + invAtZoom = 1 - getCurrentZoomRatio(); + + //totalPanAmount /= atZoom / (100 / (double) totalPanAmount); + //totalTiltAmount /= atZoom / (100 / (double) totalTiltAmount); + if (invAtZoom < .01) + invAtZoom = .01; + if (invAtZoom > 1.01) + invAtZoom = 1; + } + else + { + invAtZoom = 1; + } + + if (pan > 0) + pan = ceil(pan * invAtZoom); + else + pan = floor(pan * invAtZoom); + + if (tilt > 0) + tilt = ceil(tilt * invAtZoom); + else + tilt = floor(tilt * invAtZoom); + + if (lockRobot) + myRobot->lock(); + + if (zoom != 0) + { + double newZoomPct = (getCurrentZoomRatio() * 100.0) + zoom; + + double newAbsZoom = myCamera->getMinZoom() + ((newZoomPct / 100.0) * getZoomRange()); + + IFDEBUG(ArLog::log(ArLog::Normal, + "ArServerHandlerCamera::handleSetCameraRel() newZoomPct = %f, newAbsZoom = %f", + newZoomPct, newAbsZoom)); + + myCamera->zoom(ArMath::roundInt(newAbsZoom)); + + } // end if zoom change + + // Only want to pan... + if ((pan == 0) && (tilt != 0)) + { + cameraModePosition(); + myCamera->tiltRel(tilt); + } + // Only want to tilt... + else if ((pan != 0) && (tilt == 0)) + { + cameraModePosition(); + myCamera->panRel(pan); + } + else if (pan != 0 && tilt != 0) + { // pan and tilt... + cameraModePosition(); + myCamera->panTiltRel(pan, tilt); + } + + if (lockRobot) + myRobot->unlock(); + +} // end method doSetCameraRel + + + +/** + @param panPct the double percent offset from the image frame center + by which to pan the camera; values range -100 to 100. 0 indicates + no change. + + @param tiltPct the double percent offset from the image + frame center by which to tilt the camera; values range -100 to 100. + 0 indicates no change. + + @param lockRobot whether to lock the robot or not +**/ + +AREXPORT void ArServerHandlerCamera::setCameraPct( + double panPct, double tiltPct, bool lockRobot) +{ + cameraModePosition(); + + double zoom = getCurrentZoomRatio(); + + IFDEBUG(ArLog::log(ArLog::Normal, + "ArServerHandlerCamera::handleSetCameraPct() panPct = %f, tiltPct = %f curZoomRatio = %f", + panPct, tiltPct, zoom)); + + /* + So first we find the field of view we're at, this is interpolated + from the max and min zooms... with an exponential factor (because + empircally it seemed to be needed + */ + + double exponent = M_PI/2; // found this to be 1.6 so this seems a + // likely guess + double fov = ((myCamera->getFOVAtMinZoom() - myCamera->getFOVAtMaxZoom()) * + pow((1 - zoom), exponent) + + myCamera->getFOVAtMaxZoom()); + + + double oldTilt = myCamera->getTilt(); + double oldPan = myCamera->getPan(); + + + /* + So this whole thing is done as a vector calculations... so first + we find where our old x, y, z value was to start with then we add + in the x, y, z change from the left/right component of the image + click and from the up/down component of the image click to find + our final x, y, z and then we figure out the pan/tilt that points + us there... this is basically all assuming a unit sphere (ie + length 1) + + One thing that could be done to make it more accurate is to remove + some of the error (ie right now from going straight right in the + image at 0 all we do is add x, if we removed a little y too to + normalize it on the unit sphere it'd be more accurate). + **/ + + /* + + Derivation of these equations (for finding the x, y, z from + current pan tilt) + + | , + | /|z + | / | + |/t |y + -)--|------- + / \)p| / + / h\ | / x + / \|/ + + + Where pan and tilt are the values we're panned and tilted at now + and x, y, and z are the coords in the unit sphere that we + have... h is the hypoenuse of the line projected down into the + x/y plane + + + sin tilt = z / 1 (because its the unit sphere) +! sin tilt = z -, + | + tan tilt = z / hyp | + tan tilt = sin tilt / hyp <-' + hyp = sin tilt / tan tilt -, -, + | | + sin pan = x / hyp | | + sin pan * hyp = x | | + x = hyp * sin pan | | +! x = (sin tilt/tan tilt) * sin pan <-' | + | + cos pan = y / hyp | + cos pan * hyp = y | + y = hyp * sin pan | +! y = (sin tilt/tan tilt) * cos pan <-' + + + The old X here should be sin(tilt) + --------- * sin(pan) + tan(tilt) + + The old Y here should be sin(tilt) + --------- * cos(pan) + tan(tilt) + + The old z here should be sin(tilt); + + The funkiness is because of divide by zeros and stuff, this is + supposed to be the hypot though and so it can't really ever be 0 or + infnity so just cap the thing + **/ + double sinTiltOverTanTilt; + if (fabs(oldTilt) < .01) + sinTiltOverTanTilt = 1; + else + sinTiltOverTanTilt = ArMath::sin(oldTilt) / ArMath::tan(oldTilt); + double oldX = sinTiltOverTanTilt * ArMath::sin(oldPan); + double oldY = sinTiltOverTanTilt * ArMath::cos(oldPan); + double oldZ = ArMath::sin(oldTilt); + + // figure out the angle of the left/right point in the image + double lr = panPct / 100.0 * fov/2.0; + + /** + Figure how much the x/y/z components of the left/right vector, + this part is pretty straightforward since its just multiplying + the left/right vector by the cos or sin to get the component in + that direction (which is based on the pan) + + @verbatim + ------------------ y + |\)lr | + | \ | sin lr + | \ | + | \ | + | \| + x + @endverbatim + + That derives the sin lr for the length of the vector... for how + much of that is in which direction + + @verbatim + dx = sin lr * sin pan + ------------------------- y + |\)pan | + | \ | + | \slr | dy = sin lr * cos pan + | \ | + | \ | + | \ | + | \| + x + @endverbatim + + Where slr is the sin lr derived above and pan is the pan angle + (since we're doing vectors the position we calculate these + components from doesn't matter so we just move it back to 0 to + make life easier)... + + The - on the sin is needed, I think its because the camera pans + positive to the right and negative to the left instead of + positive to the right. + + **/ + double lrDx = + ArMath::sin(lr) * ArMath::cos(oldPan); + double lrDy = - ArMath::sin(lr) * ArMath::sin(oldPan); + double lrDz = 0; + + // the angle of the up/down point in the image + double ud = tiltPct / 100.0 * fov/2.0 *.71; + + /** + Figure how much the x/y/z components of the up/down vector, + + So for x and y first we find how much is in the x/y plane + (sin(ud) * sin(oldTilt)) and then we multiply that by the same + sin or cos of the pan to see how much is in which coord... + + For z we just multiply the up/down vector by the cos to find what + the movement in z is. + **/ + double udDx = - (ArMath::sin(ud) * ArMath::sin(oldTilt) * + ArMath::sin(oldPan)); + double udDy = - (ArMath::sin(ud) * ArMath::sin(oldTilt) * + ArMath::cos(oldPan)); + double udDz = ArMath::sin(ud) * ArMath::cos(oldTilt); + + + /** + Now add the original vector, the vector from left/right and the + vector from up/down together. + **/ + double x = oldX + lrDx + udDx; + double y = oldY + lrDy + udDy; + double z = oldZ + lrDz + udDz; + + + /** + Now find where we have to pan and tilt to... + + | , + | /|z + | / | + |/t |y + -)--|------- + / \)p| / + / h\ | / x + / \|/ + + Where x, y, and z are the values we found above and tilt and pan + are the tilt (angle of the line off of the x/y plane) and pan + values (angle of the line within the x/y plain) we need to point + at that point, h is the hypotenuse of the line projected into the + x/y plane. + + + + tan pan = x / y +! pan = atan (x / y) + + cos pan = y / hyp + hyp = y / cos pan + + sin pan = x / hyp + hyp = x / sin pan + + tan tilt = z / hyp + +! tilt = atan (z / hyp) + (substitute in one of the hyps) + **/ + + /** + Pan is easy since its just the atan of x and y. + **/ + double newPan = ArMath::atan2(x, y); + double tiltDenom; + /** + This denom can be either y/cos(pan) or x / sin(pan) depending on + which solution you use and we use them in a way that won't get us + a divide by 0. + **/ + if (fabs(oldPan) < 1) + tiltDenom = y / ArMath::cos(newPan); + else if (fabs(oldPan - 90) < 1) + tiltDenom = x / ArMath::sin(newPan); + else + tiltDenom = (y / ArMath::cos(newPan) + x / ArMath::sin(newPan)) / 2; + double newTilt = ArMath::atan2(z, tiltDenom); + if (lockRobot) + myRobot->lock(); + myCamera->panTilt(newPan, newTilt); + if (lockRobot) + myRobot->unlock(); + /* + ArLog::log(ArLog::Normal, "w %f h %f zoom %f fov %g oldPan %g oldTilt %g oldx %g oldy %g oldz %g x %g y %g z %g newPan %g newTilt %g", + w, h, zoom, fov, oldPan, oldTilt, oldX, oldY, oldZ, x, y, z, newPan, newTilt); + */ + +} // end method doSetCameraPct + +// ---------------------------------------------------------------------------- +// Helper Methods +// ---------------------------------------------------------------------------- + +AREXPORT void ArServerHandlerCamera::handleGetCameraModeList( + ArServerClient *client, ArNetPacket *packet) +{ + ArNetPacket sending; + + myModeMutex.lock(); + sending.uByte2ToBuf(myCameraModeNameMap.size()); + + std::map::iterator it; + for (it = myCameraModeNameMap.begin(); it != myCameraModeNameMap.end(); it++) + { + sending.strToBuf((*it).second.c_str()); + } + myModeMutex.unlock(); + client->sendPacketTcp(&sending); +} + +AREXPORT void ArServerHandlerCamera::handleCameraModeUpdated( + ArServerClient *client, ArNetPacket *packet) +{ + myModeMutex.lock(); + client->sendPacketTcp(&myCameraModePacket); + myModeMutex.unlock(); +} + +AREXPORT void ArServerHandlerCamera::handleSetCameraMode( + ArServerClient *client, ArNetPacket *packet) +{ + char modeName[512]; + packet->bufToStr(modeName, sizeof(modeName)); + + + CameraMode newMode; + std::map::iterator it; + ArPose lookPoint; + + for (it = myCameraModeNameMap.begin(); it != myCameraModeNameMap.end(); it++) + { + if (ArUtil::strcasecmp((*it).second, modeName) == 0) + { + newMode = (*it).first; + if (newMode == CAMERA_MODE_POSITION) + { + cameraModePosition(); + } + else if (newMode == CAMERA_MODE_LOOK_AT_GOAL) + { + cameraModeLookAtGoal(); + } + else if (newMode == CAMERA_MODE_LOOK_AT_POINT) + { + lookPoint.setX(packet->bufToByte4()); + lookPoint.setY(packet->bufToByte4()); + cameraModeLookAtPoint(lookPoint); + } + return; + } + } + + ArLog::log(ArLog::Normal, + "ArServerHandlerCamera::%s: Could not find mode %s to switch to", + myCameraName.c_str(), modeName); +} + +void ArServerHandlerCamera::userTask(void) +{ + myModeMutex.lock(); + if (myCameraMode == CAMERA_MODE_LOOK_AT_GOAL) + { + if (!myGoalResetZoom) + { + myCamera->zoom(0); + myGoalResetZoom = true; + } + if (!myGoalAchieved) + { + myCamera->panTilt(-myRobot->findDeltaHeadingTo(myGoal), 0); + } + else if (!myGoalAchievedLast) + { + myCamera->panTilt(0, 0); + myGoalAchievedLast = true; + } + } + if (myCameraMode == CAMERA_MODE_LOOK_AT_POINT) + { + if (!myPointResetZoom) + { + myCamera->zoom(0); + myPointResetZoom = true; + } + myCamera->panTilt(-myRobot->findDeltaHeadingTo(myLookAtPoint), 0); + } + myModeMutex.unlock(); +} + +void ArServerHandlerCamera::buildModePacket(void) +{ + myCameraModePacket.empty(); + + myCameraModePacket.strToBuf(myCameraModeNameMap[myCameraMode].c_str()); + if (myCameraMode == CAMERA_MODE_LOOK_AT_POINT) + { + myCameraModePacket.byte4ToBuf( + ArMath::roundInt(myLookAtPoint.getX())); + myCameraModePacket.byte4ToBuf( + ArMath::roundInt(myLookAtPoint.getY())); + } +} + +AREXPORT void ArServerHandlerCamera::cameraModePosition(void) +{ + myModeMutex.lock(); + if (myCameraMode != CAMERA_MODE_POSITION) + { + ArLog::log(ArLog::Normal, "Looking by position"); + myCameraMode = CAMERA_MODE_POSITION; + buildModePacket(); + myServer->broadcastPacketTcp( + &myCameraModePacket, + myCommandToPacketNameMap[ + ArCameraCommands::CAMERA_MODE_UPDATED].c_str()); + + } + myModeMutex.unlock(); +} + +AREXPORT void ArServerHandlerCamera::cameraModeLookAtGoal(void) +{ + myModeMutex.lock(); + if (myCameraMode != CAMERA_MODE_LOOK_AT_GOAL) + { + ArLog::log(ArLog::Normal, "Looking at goal"); + myCameraMode = CAMERA_MODE_LOOK_AT_GOAL; + myGoalAchievedLast = myGoalAchieved; + myGoalResetZoom = false; + + buildModePacket(); + myServer->broadcastPacketTcp( + &myCameraModePacket, + myCommandToPacketNameMap[ + ArCameraCommands::CAMERA_MODE_UPDATED].c_str()); + } + myModeMutex.unlock(); +} + +AREXPORT void ArServerHandlerCamera::cameraModeLookAtPoint(ArPose pose, + bool controlZoom) +{ + myModeMutex.lock(); + if (myCameraMode != CAMERA_MODE_LOOK_AT_POINT || + myLookAtPoint.findDistanceTo(pose) > 1) + { + ArLog::log(ArLog::Normal, "Looking at point %.0f %.0f", + pose.getX(), pose.getY()); + if (myCameraMode != CAMERA_MODE_LOOK_AT_POINT && controlZoom) + myPointResetZoom = false; + myCameraMode = CAMERA_MODE_LOOK_AT_POINT; + myLookAtPoint = pose; + buildModePacket(); + myServer->broadcastPacketTcp( + &myCameraModePacket, + myCommandToPacketNameMap[ + ArCameraCommands::CAMERA_MODE_UPDATED].c_str()); + } + myModeMutex.unlock(); +} + +AREXPORT void ArServerHandlerCamera::cameraModeLookAtGoalSetGoal(ArPose pose) +{ + myModeMutex.lock(); + myGoal = pose; + myGoalAchieved = false; + myGoalAchievedLast = false; + myGoalResetZoom = false; + myModeMutex.unlock(); +} + +AREXPORT void ArServerHandlerCamera::cameraModeLookAtGoalClearGoal(void) +{ + myModeMutex.lock(); + myGoalAchieved = true; + myModeMutex.unlock(); +} + +AREXPORT void ArServerHandlerCamera::handleResetCamera( + ArServerClient *client, ArNetPacket *packet) +{ + resetCamera(); +} + +AREXPORT void ArServerHandlerCamera::resetCamera(bool lockRobot) +{ + if (lockRobot) + myRobot->lock(); + myCamera->reset(); + if (lockRobot) + myRobot->unlock(); + cameraModePosition(); +} + diff --git a/Legacy/Aria/ArNetworking/src/ArServerHandlerCameraCollection.cpp b/Legacy/Aria/ArNetworking/src/ArServerHandlerCameraCollection.cpp new file mode 100644 index 0000000..2fb86dd --- /dev/null +++ b/Legacy/Aria/ArNetworking/src/ArServerHandlerCameraCollection.cpp @@ -0,0 +1,300 @@ +#include "Aria.h" +#include "ArExport.h" +#include "ArServerHandlerCameraCollection.h" + + +#include +#include "ArClientArgUtils.h" + +const char *ArServerHandlerCameraCollection::GET_COLLECTION_PACKET_NAME = + "getCameraList"; +const char *ArServerHandlerCameraCollection::COLLECTION_UPDATED_PACKET_NAME = + "cameraListUpdated"; +const char *ArServerHandlerCameraCollection::SET_PARAMS_PACKET_NAME = + "setCameraParams"; +const char *ArServerHandlerCameraCollection::PARAMS_UPDATED_PACKET_NAME = + "cameraParamUpdated"; + +const char *ArServerHandlerCameraCollection::COMMAND_GROUP = + "CameraInfo"; // ?? + + +AREXPORT ArServerHandlerCameraCollection::ArServerHandlerCameraCollection + (ArServerBase *server, + ArCameraCollection *cameraCollection) : + myServer(server), + myCameraCollection(cameraCollection), + myGetCameraListCB(NULL), + mySetParamCB(NULL), + myCollectionModifiedCB(NULL) +{ + if (myServer != NULL) + { + myGetCameraListCB = new ArFunctor2C + (this, + &ArServerHandlerCameraCollection::getCameraList); + + myServer->addData(GET_COLLECTION_PACKET_NAME, + "Gets information about the robot's cameras.", + myGetCameraListCB, + "none", + "byte2: numCameras, repeating for numCameras: { string: cameraName, string: cameraType, string: displayName, string: displayType, byte2: numCommands, repeating for numCommands: {string: command, string: cameraCommandName byte4: requestInterval } byte2: numParams, repeating for numParams: {see ArConfigArg format}}", + COMMAND_GROUP, "RETURN_SINGLE"); // ??? + + + mySetParamCB = new ArFunctor2C + (this, + &ArServerHandlerCameraCollection::setParams); + + myServer->addData(SET_PARAMS_PACKET_NAME, + "Sets the specified camera parameters.", + mySetParamCB, + "string: cameraName, repeating for each param: { string: paramName, }, empty paramName terminates list", + "string: cameraName, repeating for each modified param: { string: paramName, }, empty paramName terminates list", + COMMAND_GROUP, "RETURN_SINGLE"); // ??? + + + myServer->addData(COLLECTION_UPDATED_PACKET_NAME, + "Single packet is sent when the camera collection has been modified.", + NULL, + "none", + "none", + COMMAND_GROUP, "RETURN_SINGLE"); + + myServer->addData(PARAMS_UPDATED_PACKET_NAME, + "Packet is sent when the camera parameters have been modified.", + NULL, + "none", + "string: cameraName, repeating for each modified param: { string: paramName, }, empty paramName terminates list", + COMMAND_GROUP, "RETURN_SINGLE"); // ??? + + } // end if server + + if (myCameraCollection != NULL) { + + myCollectionModifiedCB = new ArFunctorC + (this, + &ArServerHandlerCameraCollection::handleCameraCollectionModified); + + myCameraCollection->addModifiedCB(myCollectionModifiedCB); + + } // end if camera collection + +} // end ctor + +AREXPORT ArServerHandlerCameraCollection::~ArServerHandlerCameraCollection() +{ + if ((myCameraCollection != NULL) && + (myCollectionModifiedCB != NULL)) { + + myCameraCollection->removeModifiedCB(myCollectionModifiedCB); + delete myCollectionModifiedCB; + myCollectionModifiedCB = NULL; + + } // end if camera collection + + // TODO remove and delete server CB + +} // end dtor + + +AREXPORT void ArServerHandlerCameraCollection::getCameraList(ArServerClient *client, + ArNetPacket *packet) +{ + if (client == NULL) { + return; // Something very bad has happened... + } + + ArNetPacket sendPacket; + + if (myCameraCollection == NULL) { + sendPacket.byte2ToBuf(0); + client->sendPacketTcp(&sendPacket); + } + + // This lack of recursive locks is troublesome... Data might + // change between calls... + + std::list cameraNames; + myCameraCollection->getCameraNames(cameraNames); + + sendPacket.byte2ToBuf(cameraNames.size()); + + for (std::list::iterator iter = cameraNames.begin(); + iter != cameraNames.end(); + iter++) { + + const char *curName = iter->c_str(); + + sendPacket.strToBuf(curName); + + // TODO: ArNetPacket will NOT behave correctly if the given str is NULL + // Fix this somehow... + + sendPacket.strToBuf(myCameraCollection->getCameraType(curName)); + sendPacket.strToBuf(myCameraCollection->getDisplayName(curName)); + sendPacket.strToBuf(myCameraCollection->getDisplayType(curName)); + + // Send commands... + + std::list commands; + myCameraCollection->getCameraCommands(curName, commands); + + sendPacket.byte2ToBuf(commands.size()); + + for (std::list::iterator comIter = commands.begin(); + comIter != commands.end(); + comIter++) { + + const char *curCommand = comIter->c_str(); + + sendPacket.strToBuf(curCommand); + sendPacket.strToBuf(myCameraCollection->getCommandName(curName, curCommand)); + sendPacket.byte4ToBuf(myCameraCollection->getRequestInterval(curName, curCommand)); + + } // end for each command + + // Send parameters... + + std::list params; + myCameraCollection->getParameterNames(curName, params); + + sendPacket.byte2ToBuf(params.size()); + + ArConfigArg arg; + ArClientArg clientArg; + + bool isSuccess = true; + + for (std::list::iterator paramIter = params.begin(); + paramIter != params.end(); + paramIter++) { + + const char *paramName = paramIter->c_str(); + + isSuccess = myCameraCollection->getParameter(curName, + paramName, + arg); + if (!isSuccess) { + ArLog::log(ArLog::Normal, + "ArServerHandlerCameraCollection::getCameraList() could not find param %s", paramName); + continue; + } + + // Add the current parameter to the packet + isSuccess = clientArg.createPacket(arg, &sendPacket); + + } // end for each parameter + + } // end for each camera + + client->sendPacketTcp(&sendPacket); + +} // end method getCameraList + + + +AREXPORT void ArServerHandlerCameraCollection::setParams(ArServerClient *client, + ArNetPacket *packet) +{ + if ((packet == NULL) || (myCameraCollection == NULL)) { + return; + } + char buffer[512]; + + packet->bufToStr(buffer, sizeof(buffer)); + std::string cameraName = buffer; + + ArNetPacket paramUpdatedPacket; + paramUpdatedPacket.strToBuf(cameraName.c_str()); + + ArConfigArg arg; + ArClientArg clientArg; + bool isSuccess = true; + bool isParamUpdated = false; + + bool isDone = false; + + while (!isDone) { + + packet->bufToStr(buffer, sizeof(buffer)); + std::string paramName = buffer; + + if (paramName.empty()) { + isDone = true; + break; + } + + isSuccess = myCameraCollection->getParameter(cameraName.c_str(), + paramName.c_str(), + arg); + + if (!isSuccess) { + ArLog::log(ArLog::Verbose, + "ArServerHandlerCameraCollection::setParams() could not find camera %s, param %s", + cameraName.c_str(), paramName.c_str()); + continue; + } + + isSuccess = clientArg.bufToArgValue(packet, arg); + + if (!isSuccess) { + continue; + } + + isSuccess = myCameraCollection->setParameter(cameraName.c_str(), arg); + + if (!isSuccess) { + continue; + } + + paramUpdatedPacket.strToBuf(arg.getName()); + clientArg.argValueToBuf(arg, ¶mUpdatedPacket); + isParamUpdated = true; + + } // end for each param + + // TODO Send a confirmation back, or just use the broadcast packet? (If a, then add + // client to broadcast) + + // Add an empty string to indicate the last parameter... + paramUpdatedPacket.strToBuf(""); + + // Haven't quite decided whether to send the update packet, or a success/error notice... + client->sendPacketTcp(¶mUpdatedPacket); + + + if (isParamUpdated) { + // NOT_EXCLUDING this used to not send it to the client, but no + // longer has that behavior since it causes problems with the + // central server + myServer->broadcastPacketTcp(¶mUpdatedPacket, + PARAMS_UPDATED_PACKET_NAME); + } + + /** + // TODO: Add error message? + ArNetPacket retPacket; + retPacket->strToBuf(""); + client->sendPacketTcp(&retPacket); + **/ + +} // end method setParams + + +AREXPORT void ArServerHandlerCameraCollection::handleCameraCollectionModified() +{ + if (myServer == NULL) { + return; + } + ArNetPacket emptyPacket; + myServer->broadcastPacketTcp(&emptyPacket, COLLECTION_UPDATED_PACKET_NAME); + +} // end method handleCameraCollectionModified + + + diff --git a/Legacy/Aria/ArNetworking/src/ArServerHandlerCommMonitor.cpp b/Legacy/Aria/ArNetworking/src/ArServerHandlerCommMonitor.cpp new file mode 100644 index 0000000..2b2c805 --- /dev/null +++ b/Legacy/Aria/ArNetworking/src/ArServerHandlerCommMonitor.cpp @@ -0,0 +1,138 @@ +#include "Aria.h" +#include "ArExport.h" +#include "ArServerHandlerCommMonitor.h" + +const char *ArServerHandlerCommMonitor::HEARTBEAT_TCP_PACKET_NAME = "heartbeatTcp"; +const char *ArServerHandlerCommMonitor::HEARTBEAT_UDP_PACKET_NAME = "heartbeatUdp"; + +const char *ArServerHandlerCommMonitor::GET_HEARTBEAT_INTERVAL_PACKET_NAME = "getHeartbeatInterval"; +const char *ArServerHandlerCommMonitor::ACK_COMM_TCP_PACKET_NAME = "ackCommTcp"; +const char *ArServerHandlerCommMonitor::ACK_COMM_UDP_PACKET_NAME = "ackCommUdp"; +const char *ArServerHandlerCommMonitor::COMMAND_GROUP = "RobotInfo"; +const char *ArServerHandlerCommMonitor::NO_ARGS = "None"; + + +ArServerHandlerCommMonitor::ArServerHandlerCommMonitor + (ArServerBase *server, + int heartbeatInterval) : + myServer(server), + myHeartbeatInterval(heartbeatInterval), + myLastHeartbeatTime(), + myGetHeartbeatIntervalCB(this, &ArServerHandlerCommMonitor::handleGetHeartbeatInterval), + myAckCommUdpCB(this, &ArServerHandlerCommMonitor::handleAckCommUdp), + myAckCommTcpCB(this, &ArServerHandlerCommMonitor::handleAckCommTcp), + myCycleCB(this, &ArServerHandlerCommMonitor::cycleCallback) +{ + // Do not allow intervals too small... + if (myHeartbeatInterval < MIN_HEARTBEAT_INTERVAL) { + myHeartbeatInterval = DEFAULT_HEARTBEAT_INTERVAL; + } + + myServer->addData(HEARTBEAT_TCP_PACKET_NAME, + "Packet is broadcast (TCP) at regular intervals to confirm that server is alive.", + NULL, + NO_ARGS, + NO_ARGS, + COMMAND_GROUP, "RETURN_SINGLE"); + + myServer->addData(HEARTBEAT_UDP_PACKET_NAME, + "Packet is broadcast (UDP) at regular intervals to confirm that server is alive.", + NULL, + NO_ARGS, + NO_ARGS, + COMMAND_GROUP, "RETURN_SINGLE"); + + myServer->addData(GET_HEARTBEAT_INTERVAL_PACKET_NAME, + "Gets the expected heartbeat interval (msecs); this is an approximate value depending on the server cycle time.", + &myGetHeartbeatIntervalCB, + NO_ARGS, + "uByte4: expected heartbeat interval (msecs)", + COMMAND_GROUP, "RETURN_SINGLE"); + + myServer->addData(ACK_COMM_TCP_PACKET_NAME, + "Acknowledges two-way communication over TCP", + &myAckCommTcpCB, + NO_ARGS, + NO_ARGS, + COMMAND_GROUP, "RETURN_SINGLE"); + + myServer->addData(ACK_COMM_UDP_PACKET_NAME, + "Acknowledges two-way communication over UDP", + &myAckCommUdpCB, + NO_ARGS, + NO_ARGS, + COMMAND_GROUP, "RETURN_SINGLE"); + + + myServer->addCycleCallback(&myCycleCB); + +} // end ctor + + +ArServerHandlerCommMonitor::~ArServerHandlerCommMonitor() +{ + // TODO Remove CBs from server? +} + + +AREXPORT void ArServerHandlerCommMonitor::handleGetHeartbeatInterval + (ArServerClient *client, + ArNetPacket *packet) +{ + if (client == NULL) { + return; // Something very bad has happened... + } + + ArNetPacket sendPacket; + sendPacket.uByte4ToBuf(myHeartbeatInterval); + + client->sendPacketTcp(&sendPacket); + +} // end method handleGetHeartbeatInterval + + +AREXPORT void ArServerHandlerCommMonitor::handleAckCommTcp(ArServerClient *client, + ArNetPacket *packet) +{ + if (client == NULL) { + return; // Something very bad has happened... + } + + ArNetPacket sendPacket; + + client->sendPacketTcp(&sendPacket); + +} // end method handleAckCommTcp + + +AREXPORT void ArServerHandlerCommMonitor::handleAckCommUdp(ArServerClient *client, + ArNetPacket *packet) +{ + if (client == NULL) { + return; // Something very bad has happened... + } + + ArNetPacket sendPacket; + + client->sendPacketUdp(&sendPacket); + +} // end method handleAckCommUdp + + +AREXPORT void ArServerHandlerCommMonitor::cycleCallback() +{ + if (myLastHeartbeatTime.mSecSince() < myHeartbeatInterval) { + return; + } + + ArNetPacket sendPacket; + + myServer->broadcastPacketTcp(&sendPacket, HEARTBEAT_TCP_PACKET_NAME); + myServer->broadcastPacketUdp(&sendPacket, HEARTBEAT_UDP_PACKET_NAME); + + myLastHeartbeatTime.setToNow(); + +} // end method cycleCallback + + + diff --git a/Legacy/Aria/ArNetworking/src/ArServerHandlerCommands.cpp b/Legacy/Aria/ArNetworking/src/ArServerHandlerCommands.cpp new file mode 100644 index 0000000..af28f58 --- /dev/null +++ b/Legacy/Aria/ArNetworking/src/ArServerHandlerCommands.cpp @@ -0,0 +1,296 @@ +#include "Aria.h" +#include "ArExport.h" +#include "ArServerHandlerCommands.h" + +AREXPORT ArServerHandlerCommands::ArServerHandlerCommands( + ArServerBase *server) : + myNetListCommandsCB(this, &ArServerHandlerCommands::netListCommands), + myNetListStringCommandsCB(this, + &ArServerHandlerCommands::netListStringCommands) +{ + myServer = server; + myTextServer = NULL; + if (myServer != NULL) + { + myServer->addData("listCommands", + "Gets a list of simple commands that can be sent to the server", + &myNetListCommandsCB, "none", "byte2: numberOfCommands, string: name, string: description", + "CustomCommands", "RETURN_SINGLE"); + + myServer->addData("listStringCommands", + "Gets a list of commands that can be sent to the server with string arguments", + &myNetListStringCommandsCB, "none", "byte2: numberOfCommands, string: name, string: description", "CustomCommands", "RETURN_SINGLE"); + } + +} + +AREXPORT ArServerHandlerCommands::~ArServerHandlerCommands() +{ + ArUtil::deleteSet(myFunctors.begin(), myFunctors.end()); + myFunctors.clear(); + ArUtil::deleteSet(myStringFunctors.begin(), myStringFunctors.end()); + myStringFunctors.clear(); +} + +/** + @param name the name of the command to add + @param description the description used for this command + @param functor the functor to call + @param commandGroup the command group this should be in, if NULL defaults + to CustomCommands + **/ +AREXPORT bool ArServerHandlerCommands::addCommand( + const char *name, const char *description, ArFunctor *functor, + const char *commandGroup) +{ + std::string realName; + + if (myPrefix.size() != 0) + realName = myPrefix; + + realName += name; + + ArFunctor3 *fun = + new ArFunctor3C(this, + &ArServerHandlerCommands::netParseCommand, + NULL, NULL, functor); + + std::string group; + if (myServer == NULL) + { + ArLog::log(ArLog::Normal, "Commands::addCommand: server is NULL"); + delete fun; + return false; + } + if (commandGroup != NULL) + group = commandGroup; + else + group = "CustomCommands"; + if (myServer->addData(realName.c_str(), description, fun, "none", "none", + group.c_str(), "RETURN_NONE")) + { + myCommands.push_back(realName.c_str()); + myCommandDescriptions.push_back(description); + myFunctors.push_back(fun); + ArLog::log(ArLog::Verbose, "Added simple command %s", realName.c_str()); + + if (myTextServer != NULL) { + std::string temp = "CustCmd"; + std::string custCmd = temp + name; + + ArFunctor4 *custFun = + new ArFunctor4C(this, + &ArServerHandlerCommands::textParseCommand, + NULL, 0, NULL, functor); + + std::string desc = description; + std::string trimmedDesc = desc.substr(0, desc.find("\n",0)); + + myTextServer->addCommand (custCmd.c_str(), custFun, + trimmedDesc.c_str()); + + } + + + return true; + } + else + { + delete fun; + ArLog::log(ArLog::Normal, + "Could not add simple command %s", realName.c_str()); + return false; + } + +} + +/** + @param name the name of the command to add + @param description the description used for this command + @param functor the functor to call (takes an argument builder) + @param commandGroup the command group this should be in, if NULL defaults + to CustomCommands + **/ +AREXPORT bool ArServerHandlerCommands::addStringCommand( + const char *name, const char *description, + ArFunctor1 *functor, const char *commandGroup) +{ + std::string realName; + + if (myPrefix.size() != 0) + realName = myPrefix; + + realName += name; + + ArFunctor3 *> *fun = new + ArFunctor3C *>(this, + &ArServerHandlerCommands::netParseStringCommand, + NULL, NULL, functor); + + if (myServer == NULL) + { + ArLog::log(ArLog::Normal, "Commands::addStringCommand: server is NULL"); + delete fun; + return false; + } + std::string group; + if (commandGroup != NULL) + group = commandGroup; + else + group = "CustomCommands"; + if (myServer->addData(realName.c_str(), description, fun, + "string: argumentToCommand", "none", group.c_str(), + "RETURN_NONE")) + { + myStringCommands.push_back(realName.c_str()); + myStringCommandDescriptions.push_back(description); + myStringFunctors.push_back(fun); + ArLog::log(ArLog::Verbose, "Added simple command with string %s", + realName.c_str()); + + + if (myTextServer != NULL) { + std::string temp = "CustCmd"; + std::string custCmd = temp + name; + + ArFunctor4 *> *custFun = + new ArFunctor4C *>(this, + &ArServerHandlerCommands::textParseStringCommand, + NULL, 0, NULL, functor); + + std::string desc = description; + std::string trimmedDesc = desc.substr(0, desc.find("\n",0)); + + myTextServer->addCommand (custCmd.c_str(), custFun, + trimmedDesc.c_str()); + + } + + return true; + } + else + { + delete fun; + ArLog::log(ArLog::Normal, + "Could not add simple command with string %s", + realName.c_str()); + return false; + } +} + +void ArServerHandlerCommands::netParseCommand(ArServerClient *client, + ArNetPacket *packet, + ArFunctor *functor) +{ + if (functor == NULL) + { + ArLog::log(ArLog::Terse, "Command has NULL functor"); + return; + } + functor->invoke(); +} + +void ArServerHandlerCommands::netParseStringCommand( + ArServerClient *client, ArNetPacket *packet, + ArFunctor1 *functor) +{ + char buf[1024]; + if (packet == NULL) + { + ArLog::log(ArLog::Terse, "String command has NULL packet"); + return; + } + if (functor == NULL) + { + ArLog::log(ArLog::Terse, "String command has NULL functor"); + return; + } + packet->bufToStr(buf, sizeof(buf)); + ArArgumentBuilder arg; + arg.add(buf); + arg.setFullString(buf); + functor->invoke(&arg); +} + + +void ArServerHandlerCommands::textParseCommand( + char **argv, int argc, + ArSocket *socket, + ArFunctor *functor) +{ + + if (functor == NULL) + { + ArLog::log(ArLog::Terse, "Command has NULL functor"); + return; + } + functor->invoke(); + +} + + +void ArServerHandlerCommands::textParseStringCommand( + char **argv, int argc, + ArSocket *socket, + ArFunctor1 *functor) +{ + + if (functor == NULL) + { + ArLog::log(ArLog::Terse, "String command has NULL functor"); + return; + } + ArArgumentBuilder arg; + arg.addStrings(argc - 1, &argv[1]); + functor->invoke(&arg); +} + +AREXPORT void ArServerHandlerCommands::netListCommands(ArServerClient *client, + ArNetPacket *packet) +{ + ArNetPacket sendPacket; + std::list::iterator commIt; + std::list::iterator descIt; + sendPacket.byte2ToBuf(myCommands.size()); + for (commIt = myCommands.begin(), descIt = myCommandDescriptions.begin(); + commIt != myCommands.end() && descIt != myCommandDescriptions.end(); + commIt++, descIt++) + { + sendPacket.strToBuf((*commIt).c_str()); + sendPacket.strToBuf((*descIt).c_str()); + } + client->sendPacketTcp(&sendPacket); +} + +AREXPORT void ArServerHandlerCommands::netListStringCommands( + ArServerClient *client, ArNetPacket *packet) +{ + ArNetPacket sendPacket; + std::list::iterator commIt; + std::list::iterator descIt; + sendPacket.byte2ToBuf(myStringCommands.size()); + for (commIt = myStringCommands.begin(), + descIt = myStringCommandDescriptions.begin(); + commIt != myStringCommands.end() && + descIt != myStringCommandDescriptions.end(); + commIt++, descIt++) + { + sendPacket.strToBuf((*commIt).c_str()); + sendPacket.strToBuf((*descIt).c_str()); + } + client->sendPacketTcp(&sendPacket); +} + +AREXPORT void ArServerHandlerCommands::setPrefix(const char *prefix) +{ + myPrefix = prefix; +} + +AREXPORT const char *ArServerHandlerCommands::getPrefix(void) +{ + return myPrefix.c_str(); +} diff --git a/Legacy/Aria/ArNetworking/src/ArServerHandlerConfig.cpp b/Legacy/Aria/ArNetworking/src/ArServerHandlerConfig.cpp new file mode 100644 index 0000000..0a59599 --- /dev/null +++ b/Legacy/Aria/ArNetworking/src/ArServerHandlerConfig.cpp @@ -0,0 +1,1618 @@ +#include "Aria.h" +#include "ArExport.h" +#include "ArServerHandlerConfig.h" + +#include "ArClientArgUtils.h" + +//#define ARDEBUG_SERVERHANDLERCONFIG + +#if (defined(_DEBUG) && defined(ARDEBUG_SERVERHANDLERCONFIG)) +#define IFDEBUG(code) {code;} +#else +#define IFDEBUG(code) +#endif + +/** +@param server the server to add data to + +@param config the config to serve up + +@param defaultFile if this is given the config will try to copy the +config given and then load the default file into that config and +then serve data so clients can get those defaults + +@param defaultFileBaseDirectory base directory for the default file +**/ +AREXPORT ArServerHandlerConfig::ArServerHandlerConfig( + ArServerBase *server, ArConfig *config, const char *defaultFile, + const char *defaultFileBaseDirectory, bool allowFactory, + const char *robotName, bool preventChanges, + const char *preventChangesString) : + myRobotName((robotName != NULL) ? robotName : ""), + myLogPrefix(""), + myServer(server), + myConfig(config), + myDefault(NULL), + myPreWriteCallbacks(), + myPostWriteCallbacks(), + myRestartSoftwareCB(NULL), + myRestartSoftwareCBSet(false), + myRestartHardwareCB(NULL), + myRestartHardwareCBSet(false), + myGetConfigBySectionsCB(this, &ArServerHandlerConfig::getConfigBySections), + myGetConfigBySectionsV2CB(this, &ArServerHandlerConfig::getConfigBySectionsV2), + myGetConfigBySectionsV3CB(this, &ArServerHandlerConfig::getConfigBySectionsV3), + myGetConfigCB(this, &ArServerHandlerConfig::getConfig), + mySetConfigCB(this, &ArServerHandlerConfig::setConfig), + mySetConfigBySectionsCB(this, &ArServerHandlerConfig::setConfigBySections), + mySetConfigBySectionsV2CB(this, &ArServerHandlerConfig::setConfigBySectionsV2), + myReloadConfigCB(this, &ArServerHandlerConfig::reloadConfig), + myGetConfigDefaultsCB(this, &ArServerHandlerConfig::getConfigDefaults), + myGetConfigSectionFlagsCB(this, + &ArServerHandlerConfig::getConfigSectionFlags), + myGetLastEditablePriorityCB(this, + &ArServerHandlerConfig::getLastEditablePriority) +{ + myPermissionAllowFactory = allowFactory; + myPreventChanges = preventChanges; + if (preventChangesString != NULL) + myPreventChangesString = preventChangesString; + else + myPreventChangesString = "Changes prevented for unspecified reason"; + + if (!myRobotName.empty()) { + myLogPrefix = myRobotName + ": "; + } + myDefaultConfigMutex.setLogName( + "ArServerHandlerConfig::myDefaultConfigMutex"); + myConfigMutex.setLogName("ArServerHandlerConfig::myConfigMutex"); + myAddedDefaultServerCommands = false; + + myServer->addData("getConfigBySectionsV3", + "Gets the complete configuration information from the server", + &myGetConfigBySectionsV3CB, + "none", + "Advanced configuration retrieval, including handling of very big sections. Use ArClientHandlerConfig if desired.", + "ConfigEditing", "RETURN_UNTIL_EMPTY"); + + + myServer->addData("getConfigBySectionsV2", + "Gets the complete configuration information from the server", + &myGetConfigBySectionsV2CB, + "none", + "Advanced configuration retrieval, including restart level and list objects. Use ArClientHandlerConfig if desired.", + "ConfigEditing", "RETURN_UNTIL_EMPTY"); + + myServer->addData("getConfigBySections", + "Gets the configuration information from the server", + &myGetConfigBySectionsCB, + "none", + "A single packet is sent for each config section. Too complex to describe here. Use ArClientHandlerConfig if desired.", + "ConfigEditing", "RETURN_UNTIL_EMPTY"); + + myServer->addData("getConfig", + "gets the configuration information from the server", + &myGetConfigCB, + "none", + "deprecated (getConfigBySections is preferred). Too complex to describe here. Use ArClientHandlerConfig if desired.", + "ConfigEditing", "RETURN_SINGLE"); + + myServer->addData("setConfig", + "takes a config back from the client to use", + &mySetConfigCB, + "Repeating pairs of strings which are parameter name and value to parse", + "string: if empty setConfig worked, if the string isn't empty then it is the first error that occured (all non-error parameters are parsed, and only the first error is reported)", + "ConfigEditing", "RETURN_SINGLE|IDLE_PACKET"); + + myServer->addData("setConfigBySections", + "Saves the configuration received from the client, with each section in an individual packet", + &mySetConfigBySectionsCB, + "Section; string: section name; Repeating pairs of strings which are parameter name and value to parse", + "string: if empty setConfig worked, if the string isn't empty then it is the first error that occured (all non-error parameters are parsed, and only the first error is reported)", + "ConfigEditing", "RETURN_SINGLE|IDLE_PACKET"); + + myServer->addData("setConfigBySectionsV2", + "Saves the configuration received from the client, with each section in an individual packet", + &mySetConfigBySectionsV2CB, + "Section; string: section name; Repeating pairs of strings which are parameter name and value to parse", + "string: sectionName, or empty if end marker; string: if empty setConfig worked, if the string isn't empty then it is the first error that occured (all non-error parameters are parsed, and only the first error is reported)", + "ConfigEditing", "RETURN_SINGLE|IDLE_PACKET"); + + myServer->addData("reloadConfig", + "reloads the configuration file last loaded", + &myReloadConfigCB, "none", "none", + "ConfigEditing", "RETURN_SINGLE|IDLE_PACKET"); + + myServer->addData("configUpdated", + "gets sent when the config is updated", + NULL, "none", "none", + "ConfigEditing", "RETURN_SINGLE"); + + myServer->addData("getConfigSectionFlags", + "gets the flags for each section of the config", + &myGetConfigSectionFlagsCB, + "none", + "byte4: number of sections; repeating for number of sections (string: section; string: flags (separated by |))", + "ConfigEditing", "RETURN_SINGLE"); + + myServer->addData("getLastEditablePriority", + "Returns the last priority that may be edited by the user; e.g. EXPERT or FACTORY", + &myGetLastEditablePriorityCB, + "none", + "byte: the last ArPriority::Priority value for which parameters may be edited", + "ConfigEditing", "RETURN_SINGLE"); + + myServer->addData("configCausingRestart", + "When a config parameter that causes a restart is broadcast 1 second before the restart...", + NULL, "none", + "byte: 1 == software restart, 2 == hardware restart", + "RobotInfo", "RETURN_NONE"); + + if (defaultFile != NULL) + myDefaultFile = defaultFile; + if (defaultFileBaseDirectory != NULL) + myDefaultFileBaseDir = defaultFileBaseDirectory; + loadDefaultsFromFile(); +} + +AREXPORT ArServerHandlerConfig::~ArServerHandlerConfig() +{ + if (myDefault != NULL) + delete myDefault; +} + +AREXPORT bool ArServerHandlerConfig::loadDefaultsFromFile(void) +{ + bool ret = true; + + lockConfig(); + if (myDefault != NULL) + { + delete myDefault; + myDefault = NULL; + } + + if (!myDefaultFile.empty()) + { + ArLog::log(ArLog::Normal, "%sWill attempt to load default file '%s'", + myLogPrefix.c_str(), myDefaultFile.c_str()); + createDefaultConfig(myDefaultFileBaseDir.c_str()); + myDefault->clearAllValueSet(); + // now fill in that copy + myDefault->setPermissions(true, false); + if (myDefault->parseFile(myDefaultFile.c_str())) + { + addDefaultServerCommands(); + } + else + { + ret = false; + ArLog::log(ArLog::Normal, + "%sDid not load default file '%s' successfully, not allowing getDefault", + myLogPrefix.c_str(), + myDefaultFile.c_str()); + delete myDefault; + myDefault = NULL; + } + if (myDefault != NULL) + myDefault->removeAllUnsetValues(); + } + unlockConfig(); + ArNetPacket emptyPacket; + myServer->broadcastPacketTcp(&emptyPacket, "configDefaultsUpdated"); + return ret; +} + +AREXPORT bool ArServerHandlerConfig::loadDefaultsFromPacket( + ArNetPacket *packet) +{ + bool ret = true; + + lockConfig(); + if (myDefault != NULL) + { + delete myDefault; + myDefault = NULL; + } + + createDefaultConfig(NULL); + myDefault->clearAllValueSet(); + // now fill in that copy + if (internalSetConfig(NULL, packet, 0)) + { + addDefaultServerCommands(); + } + else + { + ArLog::log(ArLog::Normal, + "%sDid not load default from packet successfully, not allowing getDefault", + myLogPrefix.c_str()); + delete myDefault; + myDefault = NULL; + } + if (myDefault != NULL) + myDefault->removeAllUnsetValues(); + unlockConfig(); + ArNetPacket emptyPacket; + myServer->broadcastPacketTcp(&emptyPacket, "configDefaultsUpdated"); + return ret; +} + +AREXPORT void ArServerHandlerConfig::createEmptyConfigDefaults(void) +{ + lockConfig(); + if (myDefault != NULL) + { + delete myDefault; + myDefault = NULL; + } + + addDefaultServerCommands(); + unlockConfig(); + ArNetPacket emptyPacket; + myServer->broadcastPacketTcp(&emptyPacket, "configDefaultsUpdated"); +} + +/** + @internal + + doesn't delete the old one, do that if you're going to call this + yourself and make sure you lock around all that (okay, it deletes + it now, but the stuff that calls it should still take care of it) +**/ +void ArServerHandlerConfig::createDefaultConfig(const char *defaultFileBaseDir) +{ + if (myDefault != NULL) + { + delete myDefault; + myDefault = NULL; + } + // copy that config (basedir will be NULL if we're not loading from + // a file)... don't have the default save unknown values + myDefault = new ArConfig(defaultFileBaseDir, false, false, false, false); + + std::list::iterator sectionIt; + std::list::iterator paramIt; + ArConfigSection *section = NULL; + std::list *params = NULL; + ArConfigArg param; + for (sectionIt = myConfig->getSections()->begin(); + sectionIt != myConfig->getSections()->end(); + sectionIt++) + { + section = (*sectionIt); + params = section->getParams(); + + + for (paramIt = params->begin(); paramIt != params->end(); paramIt++) + { + param.copyAndDetach(*paramIt); + + myDefault->addParam(param); + + + // switch (param.getType()) { + // case ArConfigArg::INT: + //myDefault->addParam( + // ArConfigArg(param.getName(), param.getInt(), + // param.getDescription(), + // param.getMinInt(), param.getMaxInt()), + // section->getName(), + // param.getConfigPriority(), + // param.getDisplayHint()); + //break; + // case ArConfigArg::DOUBLE: + //myDefault->addParam( + // ArConfigArg(param.getName(), param.getDouble(), + // param.getDescription(), + // param.getMinDouble(), param.getMaxDouble()), + // section->getName(), + // param.getConfigPriority(), + // param.getDisplayHint()); + //break; + // + // case ArConfigArg::BOOL: + //myDefault->addParam( + // ArConfigArg(param.getName(), param.getBool(), + // param.getDescription()), + // section->getName(), + // param.getConfigPriority(), + // param.getDisplayHint()); + //break; + // + // case ArConfigArg::STRING: + //myDefault->addParam( + // ArConfigArg(param.getName(), (char *)param.getString(), + // param.getDescription(), 0), + // section->getName(), + // param.getConfigPriority(), + // param.getDisplayHint()); + //break; + // + // case ArConfigArg::SEPARATOR: + // myDefault->addParam( + // ArConfigArg(ArConfigArg::SEPARATOR), + // section->getName(), + // param.getConfigPriority(), + // param.getDisplayHint()); + //break; + // default: + //break; + // } // end switch param type + } // end for each param + } // end for each section +} // create default config + +void ArServerHandlerConfig::addDefaultServerCommands(void) +{ + if (myAddedDefaultServerCommands) + return; + + myServer->addData("getConfigDefaults", + "Gets the config default values ", + &myGetConfigDefaultsCB, + "string: section to load, empty string means get the whole thing", + "repeating strings that are the parameters and arguments to parse, but use ArClientHandlerConfig to handle this if you want", + "ConfigEditing"); + myServer->addData("configDefaultsUpdated", + "Gets sent when the config defaults are updated", + NULL, "none", "none", + "ConfigEditing", "RETURN_SINGLE"); + myAddedDefaultServerCommands = true; +} + +/** + * @param client the ArServerClient * to which to send the config + * @param packet the ArNetPacket * which accompanied the client's request + * @param isMultiplePackets a bool set to true if the server should send a + * packet for each config section followed by the empty packet; false if + * the server should send the entire config in one packet (i.e. the old style) + * @param lastPriority the last ArPriority::Priority that should be sent + * to the client (this is the greatest numerical value and the least + * semantic priority). +**/ +AREXPORT void ArServerHandlerConfig::handleGetConfig + (ArServerClient *client, + ArNetPacket *packet, + bool isMultiplePackets, + ArPriority::Priority lastPriority, + bool isSendIneditablePriorities, + int version) +{ + + ArConfigArg param; + + // The multiple packets method also sends display hints with the parameters; + // the old single packet method does not. + ArClientArg clientArg(isMultiplePackets, + lastPriority, + version); + + + std::set sent; + + ArNetPacket sending; + ArLog::log(ArLog::Normal, + "%sConfig requested.", + myLogPrefix.c_str()); + + std::list *sections = myConfig->getSections(); + for (std::list::iterator sIt = sections->begin(); + sIt != sections->end(); + sIt++) + { + // Clear the packet... + if (isMultiplePackets) { + sending.empty(); + } + + // clear out the sent list between sections + sent.clear(); + + ArConfigSection *section = (*sIt); + if (section == NULL) { + continue; + } + std::list *params = section->getParams(); + +bool isSectionSuccess = handleGetConfigSection(sending, + client, + packet, + isMultiplePackets, + lastPriority, + isSendIneditablePriorities, + version, + section, + 0, + params->size(), + 1, + sent); + + + //sending.byteToBuf('S'); + //sending.strToBuf(section->getName()); + //sending.strToBuf(section->getComment()); + //if (version >= 2) { + // sending.strToBuf(section->getCategoryName()); + //} + + //ArLog::log(ArLog::Verbose, + // "%sSending config section %s...", + // myLogPrefix.c_str(), + // section->getName()); + + ////printf("S %s %s\n", section->getName(), section->getComment()); + //std::list *params = section->getParams(); + //for (std::list::iterator pIt = params->begin(); + // pIt != params->end(); + // pIt++) + //{ + // param = (*pIt); + + // if ((!isSendIneditablePriorities) && + // (param.getConfigPriority() > lastEditablePriority)) { + // ArLog::log(ArLog::Verbose, + // "%sNot sending parameter %s priority %s ineditable", + // myLogPrefix.c_str(), + // param.getName(), + // ArPriority::getPriorityName(param.getConfigPriority())); + // continue; + // } // end if ineditable param + + + // bool isCheckableName = + // (param.getType() != ArConfigArg::DESCRIPTION_HOLDER && + // param.getType() != ArConfigArg::SEPARATOR && + // param.getType() != ArConfigArg::STRING_HOLDER); + + // // if we've already sent it don't send it again + // if (isCheckableName && + // sent.find(param.getName()) != sent.end()) { + // continue; + // } + // else if (isCheckableName) { + // sent.insert(param.getName()); + // } + + // if (clientArg.isSendableParamType(param)) + // { + // sending.byteToBuf('P'); + + // bool isSuccess = clientArg.createPacket(param, + // &sending); + + // } + //} // end for each parameter + + //if (!sending.isValid()) { + + // ArLog::log(ArLog::Terse, + // "%sConfig section %s cannot be sent; packet size exceeded", + // myLogPrefix.c_str(), + // section->getName()); + + //} // end if length exceeded... + //else if (isMultiplePackets) { + + // client->sendPacketTcp(&sending); + + //} // end else send in chunks... + + } // end for each section + + // If sending each section in individual packets, then send an empty packet + // to indicate the end of the config data. + if (isMultiplePackets) { + + sending.empty(); + client->sendPacketTcp(&sending); + } + else { // send the entire config in one packet + + // If the config is too big to fit in the packet, then just send an empty + // packet (to try to prevent an older client from crashing) + // TODO: Is there any better way to notify the user of an error.... + if (!sending.isValid()) { + ArLog::log(ArLog::Terse, + "%sError sending config; packet size exceeded", + myLogPrefix.c_str()); + sending.empty(); + } + + client->sendPacketTcp(&sending); + + } // end else send the entire packet + +} // end method getConfigBySections + + +AREXPORT bool ArServerHandlerConfig::handleGetConfigSection + (ArNetPacket &sending, + ArServerClient *client, + ArNetPacket *packet, + bool isMultiplePackets, + ArPriority::Priority lastPriority, + bool isSendIneditablePriorities, + int version, + ArConfigSection *section, + int startIndex, + int paramCount, + int sectionIndex, + std::set &sentParams) +{ + // The multiple packets method also sends display hints with the parameters; + // the old single packet method does not. + ArClientArg clientArg(isMultiplePackets, + lastPriority, + version); + + ArPriority::Priority lastEditablePriority = findLastEditablePriority(); + + sending.byteToBuf('S'); + sending.strToBuf(section->getName()); + sending.strToBuf(section->getComment()); + if (version >= 2) { + sending.strToBuf(section->getCategoryName()); + } + if (version >= 3) { + sending.uByte2ToBuf(sectionIndex); + } + + ArLog::log(ArLog::Verbose, + "%sSending config section %s...", + myLogPrefix.c_str(), + section->getName()); + bool isSuccess = true; + + std::list *params = section->getParams(); + + + int successCount = 0; + int curIndex = 0; + int count = 0; + //printf("S %s %s\n", section->getName(), section->getComment()); + for (std::list::iterator pIt = params->begin(); + ((pIt != params->end()) && (isSuccess)); + pIt++, curIndex++) + { + if (curIndex < startIndex) { + continue; + } + count++; + if (count > paramCount) { + break; + } + ArConfigArg ¶m = (*pIt); + + if ((!isSendIneditablePriorities) && + (param.getConfigPriority() > lastEditablePriority)) { + ArLog::log(ArLog::Verbose, + "%sNot sending parameter %s priority %s ineditable", + myLogPrefix.c_str(), + param.getName(), + ArPriority::getPriorityName(param.getConfigPriority())); + continue; + } // end if ineditable param + + + bool isCheckableName = + (param.getType() != ArConfigArg::DESCRIPTION_HOLDER && + param.getType() != ArConfigArg::SEPARATOR && + param.getType() != ArConfigArg::STRING_HOLDER); + + // if we've already sent it don't send it again + if (isCheckableName && + sentParams.find(param.getName()) != sentParams.end()) { + continue; + } + else if (isCheckableName) { + sentParams.insert(param.getName()); + } + + + if (clientArg.isSendableParamType(param)) + { + sending.byteToBuf('P'); + + isSuccess = clientArg.createPacket(param, + &sending); + if (isSuccess && sending.isValid()) { + IFDEBUG(ArLog::log(ArLog::Normal, + "ArServerHandlerConfig added param %s to packet", + param.getName())); + successCount++; + } + + } + } // end for each parameter + + + if ((!sending.isValid()) || (!isSuccess)) { + + if (version >= 3) { + + if (successCount == 0) { + ArLog::log(ArLog::Normal, + "ArServerHandlerConfig No successful param sent for section %s", + section->getName()); + return false; + } + + sentParams.clear(); + + + IFDEBUG(ArLog::log(ArLog::Normal, + "ArServerHandlerConfig About to send front for section %s", + section->getName())); + + sending.empty(); + bool isFrontSuccess = handleGetConfigSection + (sending, + client, + packet, + isMultiplePackets, + lastPriority, + isSendIneditablePriorities, + version, + section, + startIndex, + successCount, + sectionIndex, + sentParams); + + IFDEBUG(ArLog::log(ArLog::Normal, + "ArServerHandlerConfig About to send rear for section %s", + section->getName())); + + sending.empty(); + bool isRearSuccess = handleGetConfigSection + (sending, + client, + packet, + isMultiplePackets, + lastPriority, + isSendIneditablePriorities, + version, + section, + startIndex + successCount, + count - successCount, + sectionIndex + 1, + sentParams); + IFDEBUG(ArLog::log(ArLog::Normal, + "ArServerHandlerConfig Finished sending %s", + section->getName())); + return (isFrontSuccess && isRearSuccess); + + } + else { + + + ArLog::log(ArLog::Terse, + "%sConfig section %s cannot be sent; packet size exceeded", + myLogPrefix.c_str(), + section->getName()); + + return false; + } + + } // end if length exceeded... + else if (isMultiplePackets) { + + IFDEBUG(ArLog::log(ArLog::Normal, + "ArServerHandlerConfig sending packet to client")); + + client->sendPacketTcp(&sending); + + return true; + + } // end else send in chunks... + + return true; + +} // end method handleGetConfigSection + +AREXPORT void ArServerHandlerConfig::getConfigBySectionsV3(ArServerClient *client, + ArNetPacket *packet) +{ + doGetConfigBySections(client, packet, 3); + +} // end method getConfigBySectionsV2 + +AREXPORT void ArServerHandlerConfig::getConfigBySectionsV2(ArServerClient *client, + ArNetPacket *packet) +{ + doGetConfigBySections(client, packet, 2); + +} // end method getConfigBySectionsV2 + +AREXPORT void ArServerHandlerConfig::getConfigBySections(ArServerClient *client, + ArNetPacket *packet) +{ + doGetConfigBySections(client, packet, 1); + +} // end method getConfigBySections + +AREXPORT void ArServerHandlerConfig::doGetConfigBySections(ArServerClient *client, + ArNetPacket *packet, + int version) +{ + // The default value of lastPriority is DETAILED because that was the + // original last value and some of the older clients cannot handle + // anything greater. + ArPriority::Priority lastPriority = ArPriority::DETAILED; + + bool isSendIneditablePriorities = false; + ArPriority::Priority lastEditablePriority = findLastEditablePriority(); + + // Newer clients insert a priority value into the packet. This is + // the last priority (i.e. greatest numerical value) that the client + // can handle. + if ((packet != NULL) && + (packet->getDataReadLength() < packet->getDataLength())) { + + char priorityVal = packet->bufToByte(); + ArLog::log(ArLog::Verbose, + "%sSending config with maximum priority value set to %i", + myLogPrefix.c_str(), + priorityVal); + + lastPriority = convertToPriority(priorityVal, lastPriority); + + /*** + if ((priorityVal >= 0) && (priorityVal <= ArPriority::LAST_PRIORITY)) { + lastPriority = (ArPriority::Priority) priorityVal; + } + else if (priorityVal > ArPriority::LAST_PRIORITY) { + // This is just to handle the unlikely case that more priorities + // are added. That is, both the server and client can handle more + // than DETAILED -- and the client can handle even more than the + // server. + lastPriority = ArPriority::LAST_PRIORITY; + } + ***/ + + // If the packet contains more information, it is the last priority + // that may be edited by the client; this means that the client + // is relatively new and can handle editable versus display-only + // (or hidden) priorities; send the ineditable priorities too + if (packet->getDataReadLength() < packet->getDataLength()) { + + priorityVal = packet->bufToByte(); + lastEditablePriority = convertToPriority(priorityVal, + ArPriority::LAST_PRIORITY); + + ArLog::log(ArLog::Verbose, + "%sReceived last editable priority %s in config request", + myLogPrefix.c_str(), + ArPriority::getPriorityName(lastEditablePriority)); + + if (lastEditablePriority != findLastEditablePriority()) { + // Not sure whether this is really a critical error... + ArLog::log(ArLog::Normal, + "%sReceived unexpected last editable priority %s (expected %s)", + myLogPrefix.c_str(), + ArPriority::getPriorityName(lastEditablePriority), + ArPriority::getPriorityName(findLastEditablePriority())); + } + + isSendIneditablePriorities = true; + + } // end if packet contains last editable priority + + } // end if packet is not empty + + handleGetConfig(client, + packet, + true, // multiple packets + lastPriority, + isSendIneditablePriorities, + version); + +} // end method getConfigBySections + + + + +ArPriority::Priority ArServerHandlerConfig::findLastEditablePriority() +{ + // KMC 10/26/12 Changed from EXPERT to CALIBRATION + ArPriority::Priority lastPriority = ArPriority::CALIBRATION; + // KMC 10/26/12 ...and removed this because I'm under the impression that + // we're not currently supporting the (not) "allow factory" permission +// if (myPermissionAllowFactory) { +// lastPriority = ArPriority::CALIBRATION; +// } + return lastPriority; +} + + +ArPriority::Priority ArServerHandlerConfig::convertToPriority + (int priorityVal, + ArPriority::Priority defaultPriority) +{ + ArPriority::Priority priority = defaultPriority; + + if ((priorityVal >= 0) && (priorityVal <= ArPriority::LAST_PRIORITY)) { + priority = (ArPriority::Priority) priorityVal; + } + else if (priorityVal > ArPriority::LAST_PRIORITY) { + // This is just to handle the unlikely case that more priorities + // are added. That is, both the server and client can handle more + // than DETAILED -- and the client can handle even more than the + // server. + priority = ArPriority::LAST_PRIORITY; + } + + return priority; + +} // end method converToPriority + + +AREXPORT void ArServerHandlerConfig::getConfig(ArServerClient *client, + ArNetPacket *packet) +{ + handleGetConfig(client, + packet, + false, // single packet + ArPriority::DETAILED, // older clients can't handle greater priorities + false, // older clients don't have ineditable priorities + false); // older clients also don't have restart levels +} + + + +AREXPORT void ArServerHandlerConfig::setConfig(ArServerClient *client, + ArNetPacket *packet) +{ + // MPL 9/13/12 added this lock when I added the setPreventChanges + // function call + myConfigMutex.lock(); + if (myPreventChanges) + { + ArNetPacket retPacket; + retPacket.strToBuf(myPreventChangesString.c_str()); + ArLog::log(ArLog::Normal, "SetConfig prevented because '%s'", + myPreventChangesString.c_str()); + if (client != NULL) + { + client->sendPacketTcp(&retPacket); + ArNetPacket emptyPacket; + emptyPacket.setCommand(myServer->findCommandFromName("configUpdated")); + client->sendPacketTcp(&emptyPacket); + } + return; + } + myConfigMutex.unlock(); + + internalSetConfig(client, packet, 0); +} + +AREXPORT void ArServerHandlerConfig::setConfigBySections(ArServerClient *client, + ArNetPacket *packet) +{ + // MPL 9/13/12 added this lock when I added the setPreventChanges + // function call + myConfigMutex.lock(); + if (myPreventChanges) + { + ArNetPacket retPacket; + retPacket.strToBuf(myPreventChangesString.c_str()); + ArLog::log(ArLog::Normal, "SetConfigBySections prevented because '%s'", + myPreventChangesString.c_str()); + if (client != NULL) + { + client->sendPacketTcp(&retPacket); + ArNetPacket emptyPacket; + emptyPacket.setCommand(myServer->findCommandFromName("configUpdated")); + client->sendPacketTcp(&emptyPacket); + } + return; + } + myConfigMutex.unlock(); + + internalSetConfig(client, packet, 1, true); +} + +AREXPORT void ArServerHandlerConfig::setConfigBySectionsV2(ArServerClient *client, + ArNetPacket *packet) +{ + // MPL 9/13/12 added this lock when I added the setPreventChanges + // function call + myConfigMutex.lock(); + if (myPreventChanges) + { + ArNetPacket retPacket; + retPacket.strToBuf(myPreventChangesString.c_str()); + ArLog::log(ArLog::Normal, "SetConfigBySections prevented because '%s'", + myPreventChangesString.c_str()); + if (client != NULL) + { + client->sendPacketTcp(&retPacket); + ArNetPacket emptyPacket; + emptyPacket.setCommand(myServer->findCommandFromName("configUpdated")); + client->sendPacketTcp(&emptyPacket); + } + return; + } + myConfigMutex.unlock(); + + internalSetConfig(client, packet, 2, true); +} + +/** + @param client If client is NULL it means use the default config + @param packet request packet containing config options +**/ + +bool ArServerHandlerConfig::internalSetConfig(ArServerClient *client, + ArNetPacket *packet, + int version, + bool isMultiplePackets) +{ + char param[1024]; + char argument[1024]; + char errorBuffer[1024]; + char firstError[1024]; + ArNetPacket retPacket; + ArConfig *config; + bool ret = true; + + if (client != NULL) + config = myConfig; + else + config = myDefault; + + if (client != NULL) + lockConfig(); + + if (client != NULL) + config->setPermissions(myPermissionAllowFactory, false); + else + config->setPermissions(true, false); + + ArArgumentBuilder *builder = NULL; + if (client != NULL) + ArLog::log(ArLog::Normal, "%sGot new config from client %s", + myLogPrefix.c_str(), + client->getIPString()); + else + ArLog::log(ArLog::Verbose, + "%sNew default config", + myLogPrefix.c_str()); + errorBuffer[0] = '\0'; + firstError[0] = '\0'; + std::string sectionName; + + if (!isMultiplePackets) { + config->resetRestartLevelNeeded(); + } + + bool isEmptyPacket = true; + + while (packet->getDataReadLength() < packet->getDataLength()) + { + isEmptyPacket = false; + + packet->bufToStr(param, sizeof(param)); + packet->bufToStr(argument, sizeof(argument)); + + builder = new ArArgumentBuilder; + builder->setExtraString(param); + builder->addPlain(argument); + + ArLog::log(ArLog::Verbose, "Config: \"%s\" \"%s\"", param, argument); + + // if the param name here is "Section" we need to parse sections, + // otherwise we parse the argument + if (strcasecmp(param, "Section") == 0) { + + if (builder->getArgc() > 0) { +// ArLog::log(ArLog::Normal, +// "***** Receiving config section %s", +// builder->getArg(0)); + sectionName = builder->getArg(0); + } + if (!config->parseSection(builder, errorBuffer, sizeof(errorBuffer))) { + if (firstError[0] == '\0') { + strcpy(firstError, errorBuffer); + } // end if no error yet + } // end if error parsing section + + } + else if (strcasecmp(param, ArConfigArg::LIST_BEGIN_TAG) == 0) { + + if (!config->parseListBegin(builder, errorBuffer, sizeof(errorBuffer))) { + if (firstError[0] == '\0') + strcpy(firstError, errorBuffer); + } + + } + else if (strcasecmp(param, ArConfigArg::LIST_END_TAG) == 0) { + + if (!config->parseListEnd(builder, errorBuffer, sizeof(errorBuffer))) { + if (firstError[0] == '\0') + strcpy(firstError, errorBuffer); + } + + } + else if ((strcasecmp(param, "Section") != 0 && + !config->parseArgument(builder, errorBuffer, sizeof(errorBuffer)))) + { + if (firstError[0] == '\0') + strcpy(firstError, errorBuffer); + } + delete builder; + builder = NULL; + } + if (version >= 2) { + + // ArLog::log(ArLog::Normal, + // " ----- adding %s to retPacket", + // sectionName.c_str()); + + retPacket.strToBuf(sectionName.c_str()); + } // end if version >= 2 + + if (isMultiplePackets && !isEmptyPacket) { + if (firstError[0] != '\0') + { + ret = false; + if (client != NULL) + ArLog::log(ArLog::Normal, + "%sNew config from client %s had at least this problem: %s", + myLogPrefix.c_str(), + client->getIPString(), firstError); + else + ArLog::log(ArLog::Normal, + "%sNew default config had at least this problem: %s", + myLogPrefix.c_str(), + firstError); + + retPacket.strToBuf(firstError); + } + //printf("Sending "); + //retPacket.log(); + if (client != NULL) + client->sendPacketTcp(&retPacket); + if (client != NULL) + unlockConfig(); + // MPL 12/9/2012 don't update the config since it's only partial so far + // if (client != NULL) + // configUpdated(client); + + return ret; + + } + + // KMC 1/22/13 To only log some of the config, substitute the commented + // lines below for the following config->log statement. + + IFDEBUG(config->log(false, NULL, myLogPrefix.c_str())); + /*** + std::list sectionNameList; + sectionNameList.push_back("Data Log Settings"); + IFDEBUG(config->log(false, §ionNameList, myLogPrefix.c_str())); + ***/ + + if (firstError[0] == '\0') + { + if (config->callProcessFileCallBacks(true, + errorBuffer, + sizeof(errorBuffer))) + { + if (client != NULL) + ArLog::log(ArLog::Normal, + "%sNew config from client %s was fine.", + myLogPrefix.c_str(), + client->getIPString()); + else + ArLog::log(ArLog::Verbose, + "%sNew default config was fine.", + myLogPrefix.c_str()); + retPacket.strToBuf(""); + writeConfig(); + } + else // error processing config callbacks + { + ret = false; + if (firstError[0] == '\0') + strcpy(firstError, errorBuffer); + // if its still empty it means we didn't have anything good in the errorBuffer + if (firstError[0] == '\0') + strcpy(firstError, "Error processing"); + + if (client != NULL) + ArLog::log(ArLog::Normal, + "%sNew config from client %s had errors processing ('%s').", + myLogPrefix.c_str(), + client->getIPString(), firstError); + + else + ArLog::log(ArLog::Normal, + "%sNew default config had errors processing ('%s').", + myLogPrefix.c_str(), + firstError); + retPacket.strToBuf(firstError); + } + } + // } + // KMC Not sure about this.... Seems like it would be good to return the + // error as soon as possible -- but what affect on client? + else // if (firstError[0] != '\0') + { + ret = false; + if (client != NULL) + ArLog::log(ArLog::Normal, + "%sNew config from client %s had at least this problem: %s", + myLogPrefix.c_str(), + client->getIPString(), firstError); + else + ArLog::log(ArLog::Normal, + "%sNew default config had at least this problem: %s", + myLogPrefix.c_str(), + firstError); + + retPacket.strToBuf(firstError); + } + //printf("Sending "); + //retPacket.log(); + if (client != NULL) + client->sendPacketTcp(&retPacket); + if (client != NULL) + unlockConfig(); + if (client != NULL) + configUpdated(client); + + ArConfigArg::RestartLevel restartLevel = config->getRestartLevelNeeded(); + + config->resetRestartLevelNeeded(); + + // if we're changing main config then we need to do more + if (config == myConfig) + { + if (ret) + { + if (restartLevel == ArConfigArg::RESTART_CLIENT) + { + ArLog::log(ArLog::Normal, "%sRequesting client restart because RESTART_CLIENT (%d) config param(s) changed", + myLogPrefix.c_str(), restartLevel); + ArNetPacket clientRestartPacket; + clientRestartPacket.byteToBuf(1); + clientRestartPacket.strToBuf( + "Client restart requested because of config change"); + + myServer->broadcastPacketTcp(&clientRestartPacket, + "requestClientRestart"); + } + else if (restartLevel == ArConfigArg::RESTART_IO) + { + restartIO("RESTART_IO config param(s) changed"); + } + else if (restartLevel == ArConfigArg::RESTART_SOFTWARE) + { + restartSoftware("RESTART_SOFTWARE config param(s) changed"); + } + else if (restartLevel == ArConfigArg::RESTART_HARDWARE) + { + restartHardware("RESTART_HARDWARE config param(s) changed"); + } + } + // if we couldn't successfully load the config... then reload a new + // config (since otherwise some values can linger when they + // shouldn't) + else + { + ArLog::log(ArLog::Normal, + "%sReloading config.", + myLogPrefix.c_str()); + reloadConfig(NULL, NULL); + } + } + + config->resetRestartLevelNeeded(); + return ret; +} + +AREXPORT void ArServerHandlerConfig::reloadConfig(ArServerClient *client, + ArNetPacket *packet) +{ + if (client != NULL) + ArLog::log(ArLog::Normal, "%sReloading config for %s.", + myLogPrefix.c_str(), client->getIPString()); + + bool isNotify = true; + + lockConfig(); + myConfig->setPermissions(myPermissionAllowFactory, false); + // this isn't going to cause any restarts ever, but that's + // intentional since by definition if we're reloading the config + // we're actively using we don't need a restart + if (!myConfig->parseFile(myConfig->getFileName(), true)) { + ArLog::log(ArLog::Normal, + "ArServerHandlerConfig::reloadConfig() error parsing config file %s", + myConfig->getFileName()); + + // reloadConfig is called by internalSetConfig when the received configuration + // fails to load. In this case, the client and packet are both set to NULL. + // If the received configuration and the file both fail to load, then the + // configUpdated packet should be suppressed. Otherwise, the robot and the + // central server can enter a nasty infinite loop of perpetual config downloads. + // (See Bug 13306.) + if ((client == NULL) && (packet == NULL)) { + + isNotify = false; + ArLog::log(ArLog::Normal, + "ArServerHandlerConfig::reloadConfig() suppressing configUpdated() because received config also in error "); + + } + + } // end if error occurred parsing config file + + if (isNotify) { + configUpdated(); + } + + unlockConfig(); +} + +AREXPORT void ArServerHandlerConfig::getConfigDefaults(ArServerClient *client, + ArNetPacket *packet) +{ + char sectionRequested[512]; + sectionRequested[0] = '\0'; + ArNetPacket sending; + + if (myDefault == NULL) + { + ArLog::log(ArLog::Normal, + "%sArServerHandlerConfig::getConfigDefaults: No default config to get", + myLogPrefix.c_str()); + client->sendPacketTcp(&sending); + return; + } + myConfigMutex.lock(); + // if we have a section name pick it up, otherwise we send everything + if (packet->getDataReadLength() < packet->getDataLength()) + packet->bufToStr(sectionRequested, sizeof(sectionRequested)); + + //ArConfigArg param; + + ArClientArg clientArg; + + if (sectionRequested[0] == '\0') + ArLog::log(ArLog::Normal, + "%sSending all defaults to client", + myLogPrefix.c_str()); + else + ArLog::log(ArLog::Normal, + "%sSending defaults for section '%s' to client", + myLogPrefix.c_str(), + sectionRequested); + + + std::list *sections = myDefault->getSections(); + + for (std::list::iterator sIt = sections->begin(); + sIt != sections->end(); + sIt++) + { + ArConfigSection *section = (*sIt); + + if (section == NULL) { + continue; // Should never happen... + } + + // if we're not sending them all and not in the right section just cont + if (sectionRequested[0] != '\0' && + ArUtil::strcasecmp(sectionRequested, section->getName()) != 0) { + continue; + } + + sending.strToBuf("Section"); + sending.strToBuf(section->getName()); + + std::list *params = section->getParams(); + + for (std::list::iterator pIt = params->begin(); + pIt != params->end(); + pIt++) + { + ArConfigArg ¶m = (*pIt); + + if (!clientArg.isSendableParamType(param)) { + continue; + } + + sending.strToBuf(param.getName()); + clientArg.argTextToBuf(param, &sending); + + } // end for each param + } // end for each section + myConfigMutex.unlock(); + + client->sendPacketTcp(&sending); +} + + +AREXPORT void ArServerHandlerConfig::addPreWriteCallback( + ArFunctor *functor, ArListPos::Pos position) +{ + if (position == ArListPos::FIRST) + myPreWriteCallbacks.push_front(functor); + else if (position == ArListPos::LAST) + myPreWriteCallbacks.push_back(functor); + else + ArLog::log(ArLog::Terse, + "%sArServerHandlerConfig::addPreWriteCallback: Invalid position.", + myLogPrefix.c_str()); +} + +AREXPORT void ArServerHandlerConfig::remPreWriteCallback( + ArFunctor *functor) +{ + myPreWriteCallbacks.remove(functor); +} + +AREXPORT void ArServerHandlerConfig::addPostWriteCallback( + ArFunctor *functor, ArListPos::Pos position) +{ + if (position == ArListPos::FIRST) + myPostWriteCallbacks.push_front(functor); + else if (position == ArListPos::LAST) + myPostWriteCallbacks.push_back(functor); + else + ArLog::log(ArLog::Terse, + "%sArServerHandlerConfig::addPostWriteCallback: Invalid position.", + myLogPrefix.c_str()); +} + +AREXPORT void ArServerHandlerConfig::remPostWriteCallback( + ArFunctor *functor) +{ + myPostWriteCallbacks.remove(functor); +} + +AREXPORT void ArServerHandlerConfig::addConfigUpdatedCallback( + ArFunctor *functor, ArListPos::Pos position) +{ + if (position == ArListPos::FIRST) + myConfigUpdatedCallbacks.push_front(functor); + else if (position == ArListPos::LAST) + myConfigUpdatedCallbacks.push_back(functor); + else + ArLog::log(ArLog::Terse, + "%sArServerHandlerConfig::addConfigUpdatedCallback: Invalid position.", + myLogPrefix.c_str()); +} + +AREXPORT void ArServerHandlerConfig::remConfigUpdatedCallback( + ArFunctor *functor) +{ + myConfigUpdatedCallbacks.remove(functor); +} + +AREXPORT bool ArServerHandlerConfig::writeConfig(void) +{ + bool ret; + std::list::iterator fit; + + if (myConfig->getFileName() != NULL && + strlen(myConfig->getFileName()) > 0) + { + // call our pre write callbacks + for (fit = myPreWriteCallbacks.begin(); + fit != myPreWriteCallbacks.end(); + fit++) + { + IFDEBUG(ArLog::log(ArLog::Normal, + "ArServerHandlerConfig::writeConfig() invoking pre-write callback %s", + (%fit)->getName())); + + (*fit)->invoke(); + } + +//ArLog::logBacktrace(ArLog::Normal); + // write it + ArLog::log(ArLog::Normal, + "%sWriting config file %s", + myLogPrefix.c_str(), + myConfig->getFileName()); + ret = myConfig->writeFile(myConfig->getFileName()); + + + // call our post write callbacks + for (fit = myPostWriteCallbacks.begin(); + fit != myPostWriteCallbacks.end(); + fit++) + { + IFDEBUG(ArLog::log(ArLog::Normal, + "ArServerHandlerConfig::writeConfig() invoking post-write callback %s", + (%fit)->getName())); + (*fit)->invoke(); + } + } + else + { + ArLog::log(ArLog::Normal, "%sCannot write config since myConfig has no filename", + myLogPrefix.c_str()); + } + return ret; +} + +AREXPORT bool ArServerHandlerConfig::configUpdated(ArServerClient *client) +{ + ArNetPacket emptyPacket; + + std::list::iterator fit; + + // call our post write callbacks + for (fit = myConfigUpdatedCallbacks.begin(); + fit != myConfigUpdatedCallbacks.end(); + fit++) + { + (*fit)->invoke(); + } + // this one is okay to exclude, because if the central server is + // managing the config then its handling those updates and what not + return myServer->broadcastPacketTcpWithExclusion(&emptyPacket, + "configUpdated", client); +} + +AREXPORT void ArServerHandlerConfig::getConfigSectionFlags( + ArServerClient *client, ArNetPacket *packet) +{ + ArLog::log(ArLog::Normal, + "%sConfig section flags requested.", + myLogPrefix.c_str()); + + ArNetPacket sending; + + std::list *sections = myConfig->getSections(); + std::list::iterator sIt; + sending.byte4ToBuf(sections->size()); + + for (sIt = sections->begin(); sIt != sections->end(); sIt++) + { + + ArConfigSection *section = (*sIt); + if (section == NULL) + { + sending.strToBuf(""); + sending.strToBuf(""); + } + else + { + sending.strToBuf(section->getName()); + sending.strToBuf(section->getFlags()); + } + } + client->sendPacketTcp(&sending); +} + + +AREXPORT void ArServerHandlerConfig::getLastEditablePriority + (ArServerClient *client, + ArNetPacket *packet) +{ + + ArPriority::Priority lastPriority = ArPriority::EXPERT; + if (myPermissionAllowFactory) { + lastPriority = ArPriority::FACTORY; + } + ArLog::log(ArLog::Verbose, + "%sArServerHandlerConfig::getLastEditablePriority returning %s", + myLogPrefix.c_str(), + ArPriority::getPriorityName(lastPriority)); + + ArNetPacket sending; + sending.byteToBuf(lastPriority); + + client->sendPacketTcp(&sending); + +} // end method getLastEditablePriority + +AREXPORT void ArServerHandlerConfig::setRestartSoftwareCB( + ArFunctor *restartServerCB) +{ + myRestartSoftwareCB = restartServerCB; + myRestartSoftwareCBSet = true; +} + +AREXPORT ArFunctor *ArServerHandlerConfig::getRestartSoftwareCB(void) +{ + return myRestartSoftwareCB; +} + +AREXPORT void ArServerHandlerConfig::setRestartHardwareCB(ArFunctor *restartRobotCB) +{ + myRestartHardwareCB = restartRobotCB; + myRestartHardwareCBSet = true; +} + +AREXPORT ArFunctor *ArServerHandlerConfig::getRestartHardwareCB(void) +{ + return myRestartHardwareCB; +} + +/// Changes the variables that prevent changes +AREXPORT void ArServerHandlerConfig::setPreventChanges(bool preventChanges, const char *preventChangesString) +{ + myConfigMutex.lock(); + myPreventChanges = preventChanges; + if (preventChangesString != NULL) + myPreventChangesString = preventChangesString; + else + myPreventChangesString = "Changes prevented for unspecified reason"; + myConfigMutex.unlock(); +} + +AREXPORT void ArServerHandlerConfig::restartIO(const char *reason) +{ + ArLog::log(ArLog::Normal, "%sRequesting restartIO because '%s'", + myLogPrefix.c_str(), reason); + myRestartIOCBList.invoke(); +} + +AREXPORT void ArServerHandlerConfig::restartSoftware(const char *reason) +{ + ArLog::log(ArLog::Normal, "%sAbout to broadcast configCausingRestart (software)", + myLogPrefix.c_str()); + + ArNetPacket sendPacket; + sendPacket.byteToBuf(1); + + myServer->broadcastPacketTcp(&sendPacket, + "configCausingRestart"); + + + myServer->sleepAfterSend(1000); +// ArUtil::sleep(1* 1000); + + // if the functor was set to a value, call it + if (myRestartSoftwareCB != NULL) + { + ArLog::log(ArLog::Normal, "%sRestarting software because '%s'", + myLogPrefix.c_str(), reason); + myRestartSoftwareCB->invoke(); + } + // if it was never set then just exit + else if (!myRestartSoftwareCBSet) + { + ArLog::log(ArLog::Normal, "%sExiting because '%s' but no restartServer functor set", + myLogPrefix.c_str(), reason); + Aria::exit(0); + } + // if it was explicitly set to NULL we do nothing (mostly for + // the central server) +} + +AREXPORT void ArServerHandlerConfig::restartHardware(const char *reason) +{ + ArLog::log(ArLog::Normal, "%sAbout to broadcast configCausingRestart (hardware)", + myLogPrefix.c_str()); + + ArNetPacket sendPacket; + sendPacket.byteToBuf(2); + myServer->broadcastPacketTcp(&sendPacket, + "configCausingRestart"); + + myServer->sleepAfterSend(1000); +// ArUtil::sleep(1* 1000); + + // if the functor was set to a value, call it + if (myRestartHardwareCB != NULL) + { + ArLog::log(ArLog::Normal, "%sRestarting entire robot because '%s'", + myLogPrefix.c_str(), reason); + myRestartHardwareCB->invoke(); + } + // if it was never set then just exit + else if (!myRestartHardwareCBSet) + { + ArLog::log(ArLog::Normal, "%sExiting because '%s' but no restartRobot functor set", + myLogPrefix.c_str(), reason); + Aria::exit(0); + } + // if it was explicitly set to NULL we do nothing (mostly for + // the central server) +} diff --git a/Legacy/Aria/ArNetworking/src/ArServerHandlerMap.cpp b/Legacy/Aria/ArNetworking/src/ArServerHandlerMap.cpp new file mode 100644 index 0000000..37fc8d1 --- /dev/null +++ b/Legacy/Aria/ArNetworking/src/ArServerHandlerMap.cpp @@ -0,0 +1,890 @@ +#include "Aria.h" +#include "ArExport.h" +#include "ArServerHandlerMap.h" +#ifdef WIN32 +#include +#include +#endif + +#include "ArMap.h" + +/** + @param server the server to add our data too + + @param arMap If this points to a map file then this will simply + serve up that map file and add in a map changed cb for that map, + otherwise it'll operate via the Aria::getConfig. + + @param dataToSend Which data to send, just the lines, the points, + or both + **/ +AREXPORT ArServerHandlerMap::ArServerHandlerMap(ArServerBase *server, + ArMapInterface *arMap, + DataToSend dataToSend) : + myGetMapIdCB(this, &ArServerHandlerMap::serverGetMapId), + myGetMapNameCB(this, &ArServerHandlerMap::serverGetMapName), + myGetMapCB(this, &ArServerHandlerMap::serverGetMap), + myGetMapBinaryCB(this, &ArServerHandlerMap::serverGetMapBinary), + myGetMapMultiScansCB(this, &ArServerHandlerMap::serverGetMapMultiScans), + myGetMapMaxCategoryCB(this, &ArServerHandlerMap::serverGetMapWithMaxCategory), + myGetGoalsCB(this, &ArServerHandlerMap::serverGetGoals), + myCheckMapCB(this, &ArServerHandlerMap::handleCheckMap), + myProcessFileCB(this, &ArServerHandlerMap::processFile), + myMapChangedCB(this, &ArServerHandlerMap::mapChanged) +{ + myServer = server; + myOwnMap = false; + myMap = arMap; + setDataToSend(dataToSend); + myMapChangedCB.setName("ArServerHandlerMap"); + myProcessFileCB.setName("ArServerHandlerMap"); + if (myMap != NULL) + { + strcpy(myMapFileName, myMap->getFileName()); + myAlreadyLoaded = false; + myOwnMap = false; + myMap->addMapChangedCB(&myMapChangedCB, ArListPos::FIRST); + } + else + { + myMapFileName[0] = '\0'; + Aria::getConfig()->addParam(ArConfigArg("Map", myMapFileName, + "map file to load", + sizeof(myMapFileName)), + "Files", + ArPriority::IMPORTANT); + Aria::getConfig()->setSectionComment("Files", + "The files where important data is stored"); + Aria::getConfig()->addProcessFileCB(&myProcessFileCB, 95); + } + + + if (myServer != NULL) + { + myServer->addData("getMapId", "Gets the ID of the map being used", + &myGetMapIdCB, + "none", + "string: map name (empty string if no maps)", // TODO! + "Map", + "RETURN_SINGLE"); + + myServer->addData("getMapName", "gets the name of the map being used", + &myGetMapNameCB, "none", "string: map name (empty string if no maps)", "Map", "RETURN_SINGLE"); + + // The "getMapBinary" request replaces the old text-based "getMap" request. + myServer->addData("getMapBinary", "gets the map objects as ascii and the data points as binary", + &myGetMapBinaryCB, + "none", + "packets of ': line' for header, followed by packets of ': numPtsInPacket, (:x, :y)*' until numPtsInPacket == 0", + "Map", "RETURN_UNTIL_EMPTY"); + + // + myServer->addData("getMapMultiScans", + "Deprecated; getMapWithMaxCategory is preferred", + &myGetMapMultiScansCB, + "none", + "packets of ': line' for header, followed by packets of ': numPtsInPacket, (:x, :y)*' until numPtsInPacket == 0", + "Map", "RETURN_UNTIL_EMPTY"); + + myServer->addData("getMapWithMaxCategory", + "Requests the map with the specified maximum features; header and info are ascii, data points and lines are binary", + &myGetMapMaxCategoryCB, + "string: category (one of the constants defined in ArMapInterface)", + "packets of ': line' for header, followed by packets of ': numPtsInPacket, (:x, :y)*' until numPtsInPacket == 0", + "Map", "RETURN_UNTIL_EMPTY"); + + + + myServer->addData("getMap", "gets the map as a set of ascii lines", + &myGetMapCB, "none", + "packets of ': line' followed by a packet with an empty string to denote end (if only empty string then no map)", + "Map", "RETURN_UNTIL_EMPTY"); + myServer->addData("mapUpdated", "a single packet is sent to this when the map is updated and this denotes a new getMap and getMapName should be requested", + NULL, "none", "none", + "Map", "RETURN_SINGLE"); + myServer->addData("getGoals", "gets the list of goals", + &myGetGoalsCB, "none", + " string: goal", "Map", "RETURN_SINGLE"); + myServer->addData("goalsUpdated", "a single packet is sent to this when the goals are updated and this denotes a new getGoals should be requested", + NULL, "none", "none", + "Map", "RETURN_SINGLE"); + + myServer->addData("checkMap", + "Requests that the server check whether the map needs to be read", + &myCheckMapCB, + "none", + "none", + "Map", + "RETURN_NONE|IDLE_PACKET"); + + + } +} + +AREXPORT ArServerHandlerMap::~ArServerHandlerMap() +{ + +} + +AREXPORT bool ArServerHandlerMap::loadMap(const char *mapFile) +{ + ArLog::log(ArLog::Normal, + "ArServerHandlerMap::loadMap(%s)", + mapFile); + + ArNetPacket emptyPacket; + if (myMap != NULL) + { + if (myOwnMap) + delete myMap; + myMap = NULL; + } + myMap = new ArMapSimple(NULL); + + myMapName = mapFile; + myOwnMap = true; + bool ret = myMap->readFile(mapFile); + + myServer->broadcastPacketTcp(&emptyPacket, "mapUpdated"); + myServer->broadcastPacketTcp(&emptyPacket, "goalsUpdated"); + + return ret; +} + + +/** + Use the map object given, note that this will not take ownership of the map unless you tell + **/ +AREXPORT void ArServerHandlerMap::useMap(ArMapInterface *mapObj, + bool takeOwnershipOfMap) +{ + ArNetPacket emptyPacket; + if (myMap != NULL) + { + if (myOwnMap) + delete myMap; + myMap = NULL; + } + myMap = mapObj; + myMapName = myMap->getFileName(); + myOwnMap = takeOwnershipOfMap; + myServer->broadcastPacketTcp(&emptyPacket, "mapUpdated"); + myServer->broadcastPacketTcp(&emptyPacket, "goalsUpdated"); +} + +AREXPORT ArMapInterface *ArServerHandlerMap::getMap(void) +{ + return myMap; +} + + +/** @internal */ +AREXPORT void ArServerHandlerMap::serverGetMapId(ArServerClient *client, + ArNetPacket *packet) +{ + ArLog::log(ArLog::Normal, + "ArServerHandlerMap::serverGetMapId() map ID requested by %s", + ((client != NULL) ? client->getIPString() : "NULL")); + + // To force the problem described in Bug 11160 to become reproducible + // instead of highly intermittent, uncomment the following sleep. + // ArUtil::sleep(1000); + + + ArNetPacket sendPacket; + ArMapId mapId; + if (myMap != NULL) + { + bool isSuccess = myMap->getMapId(&mapId); + if (isSuccess) { + } + else { + mapId = ArMapId(); + ArLog::log(ArLog::Normal, + "ArServerHandlerMap::serverGetMapId() error getting map ID from map"); + } + } + else { + ArLog::log(ArLog::Normal, + "ArServerHandlerMap::serverGetMapId() map is NULL"); + + } + + mapId.log("ArServerHandlerMap::serverGetMapId"); + + + ArMapId::toPacket(mapId, + &sendPacket); + + + client->sendPacketTcp(&sendPacket); + + +} // end method serverGetMapId + + +/** @internal */ +AREXPORT void ArServerHandlerMap::serverGetMapName(ArServerClient *client, + ArNetPacket *packet) +{ + ArNetPacket sendPacket; + if (myMap == NULL) + { + sendPacket.strToBuf(""); + client->sendPacketTcp(&sendPacket); + } + else + { + sendPacket.strToBuf(myMap->getFileName()); + client->sendPacketTcp(&sendPacket); + } +} + +/** @internal */ +AREXPORT void ArServerHandlerMap::writeMapToClient(const char *line, + ArServerClient *client) +{ + ArNetPacket sendPacket; + sendPacket.strToBuf(line); + client->sendPacketTcp(&sendPacket); +} + +/** @internal */ +AREXPORT void ArServerHandlerMap::writePointsToClient( + int pointCount, + std::vector *points, + ArServerClient *client) +{ + ArNetPacket sendPacket; + + // Should never happen... + if (points == NULL) { + // Send 0 points just so the client doesn't hang + sendPacket.byte4ToBuf(0); + client->sendPacketTcp(&sendPacket); + return; + } + + ArLog::log(ArLog::Verbose, + "ArServerHandlerMap::writePointsToClient() pointCount = %i, vector size = %i", + pointCount, (int) points->size()); + + // Neither should this, but just in case... + if (pointCount > (int) points->size()) { + pointCount = points->size(); + } + + int maxInPacketCount = 1000; // Maximum number of points sent in a packet + int currentCount = 0; // Number put into the current packet + int remainingCount = pointCount; // Total number of points remaining to be sent + bool isStartPacket = true; // Whether a new packet is being started + + int totalCount = 0; + + for (std::vector::iterator pointIt = points->begin(); + pointIt != points->end(); + pointIt++) { + + // Start a new packet if the previous one was sent (or there is no + // previous one) + if (isStartPacket) { + + isStartPacket = false; + + sendPacket.empty(); + currentCount = 0; + + // Leftover points... + if (maxInPacketCount > remainingCount) { + maxInPacketCount = remainingCount; + } + + // The first item in the packet is the number of points contained + sendPacket.byte4ToBuf(maxInPacketCount); + + } // end if starting a new packet + + // Add the current point to the packet (think that the test should + // always be true) + if (currentCount < maxInPacketCount) { + + currentCount++; + remainingCount--; + + sendPacket.byte4ToBuf( + ArMath::roundInt((*pointIt).getX())); + sendPacket.byte4ToBuf( + ArMath::roundInt((*pointIt).getY())); + } + + // If the packet is full, send it and then start a new one + if (currentCount == maxInPacketCount) { + + totalCount += currentCount; + + client->sendPacketTcp(&sendPacket); + //ArUtil::sleep(1); + + isStartPacket = true; + } + + } // end for each point + + ArLog::log(ArLog::Verbose, + "ArServerHandlerMap::writePointsToClient() totalCount = %i", + totalCount); + + // Send 0 points to indicate that all have been sent + if (false) { + sendPacket.empty(); + sendPacket.byte4ToBuf(0); + client->sendPacketTcp(&sendPacket); + } + +} // end writePointsToClient + +/** @internal */ +AREXPORT void ArServerHandlerMap::writeLinesToClient( + int lineCount, + std::vector *lines, + ArServerClient *client) +{ + ArNetPacket sendPacket; + + // Should never happen... + if (lines == NULL) { + // Send 0 points just so the client doesn't hang + sendPacket.byte4ToBuf(0); + client->sendPacketTcp(&sendPacket); + return; + } + + ArLog::log(ArLog::Verbose, + "ArServerHandlerMap::writeLinesToClient() pointCount = %i, vector size = %i", + lineCount, (int) lines->size()); + + // Neither should this, but just in case... + if (lineCount > (int) lines->size()) { + lineCount = lines->size(); + } + + int maxInPacketCount = 1000; // Maximum number of points sent in a packet + int currentCount = 0; // Number put into the current packet + int remainingCount = lineCount; // Total number of points remaining to be sent + bool isStartPacket = true; // Whether a new packet is being started + + int totalCount = 0; + + for (std::vector::iterator lineIt = lines->begin(); + lineIt != lines->end(); + lineIt++) + { + + // Start a new packet if the previous one was sent (or there is no + // previous one) + if (isStartPacket) { + + isStartPacket = false; + + sendPacket.empty(); + currentCount = 0; + + // Leftover points... + if (maxInPacketCount > remainingCount) { + maxInPacketCount = remainingCount; + } + + // The first item in the packet is the number of points contained + sendPacket.byte4ToBuf(maxInPacketCount); + + } // end if starting a new packet + + // Add the current point to the packet (think that the test should + // always be true) + if (currentCount < maxInPacketCount) { + + currentCount++; + remainingCount--; + + sendPacket.byte4ToBuf( + ArMath::roundInt((*lineIt).getX1())); + sendPacket.byte4ToBuf( + ArMath::roundInt((*lineIt).getY1())); + sendPacket.byte4ToBuf( + ArMath::roundInt((*lineIt).getX2())); + sendPacket.byte4ToBuf( + ArMath::roundInt((*lineIt).getY2())); + } + + // If the packet is full, send it and then start a new one + if (currentCount == maxInPacketCount) { + + totalCount += currentCount; + + client->sendPacketTcp(&sendPacket); + //ArUtil::sleep(1); + + isStartPacket = true; + } + + } // end for each point + + ArLog::log(ArLog::Verbose, + "ArServerHandlerMap::writePointsToClient() totalCount = %i", + totalCount); + + // Send 0 points to indicate that all have been sent + if (false) { + sendPacket.empty(); + sendPacket.byte4ToBuf(0); + client->sendPacketTcp(&sendPacket); + } + +} // end writePointsToClient + + +/** @internal */ +AREXPORT void ArServerHandlerMap::serverGetMap(ArServerClient *client, + ArNetPacket *packet) +{ + ArLog::log(ArLog::Verbose, "Starting sending map to client"); + if (myMap == NULL) + { + writeMapToClient("", client); + return; + } + + myMap->lock(); + // This functor is used to send the entire map in text format. + ArFunctor1 *functor = + new ArFunctor2C + (this, + &ArServerHandlerMap::writeMapToClient, + NULL, + client); + // Send the map + myMap->writeToFunctor(functor, ""); + + delete functor; + // Send an empty packet to indicate the end of the map. + writeMapToClient("", client); + + // send an empty packet to say we're done + ArNetPacket emptyPacket; + client->sendPacketTcp(&emptyPacket); + + myMap->unlock(); + ArLog::log(ArLog::Verbose, "Finished sending map to client"); + +} + +AREXPORT void ArServerHandlerMap::serverGetMapBinary(ArServerClient *client, + ArNetPacket *packet) +{ + ArLog::log(ArLog::Verbose, "Starting sending map (binary) to client"); + if (myMap == NULL) + { + writeMapToClient("", client); + return; + } + + myMap->lock(); + // This functor is used to send the map header and objects in text format. + ArFunctor1 *textFunctor = + new ArFunctor2C + (this, + &ArServerHandlerMap::writeMapToClient, + NULL, + client); + + // This functor is used to send the map data lines in binary format (since + // it is faster). + ArFunctor2 *> *linesFunctor = + new ArFunctor3C *, ArServerClient *> + (this, + &ArServerHandlerMap::writeLinesToClient, + 0, + NULL, + client); + + // This functor is used to send the map data points in binary format (since + // it is faster). + ArFunctor2 *> *pointsFunctor = + new ArFunctor3C *, ArServerClient *> + (this, + &ArServerHandlerMap::writePointsToClient, + 0, + NULL, + client); + + // Send the map up to but not including the DATA tag. + myMap->writeObjectsToFunctor(textFunctor, + "", + true, // Only send one scan type + ArMapInterface::MAP_CATEGORY_2D); + + std::list scanTypeList = myMap->getScanTypes(); + + bool isAnyLinesExist = false; + + for (std::list::iterator iter = scanTypeList.begin(); + iter != scanTypeList.end(); + iter++) { + const char *scanType = (*iter).c_str(); + if ((myMap->getLines(scanType) != NULL) && + (!myMap->getLines(scanType)->empty())) { + isAnyLinesExist = true; + break; + } + } // end for each scan type + + // see if we want to send the lines and make sure we have lines + if ((myDataToSend == LINES || myDataToSend == BOTH) && + isAnyLinesExist) + { + writeMapToClient("LINES", client); + + /*** + myMap->writeLinesToFunctor(linesFunctor, + NULL, + ARMAP_SUMMARY_SCAN_TYPE); + + ***/ + for (std::list::iterator iter = scanTypeList.begin(); + iter != scanTypeList.end(); + iter++) { + const char *scanType = (*iter).c_str(); + ArLog::log(ArLog::Normal, + "ArServerHandlerMap::serverGetMapBinary() sending lines for %s", + scanType); + + myMap->writeLinesToFunctor(linesFunctor, scanType, NULL); + + } // end for each scan type + + ArNetPacket sendPacket; + sendPacket.empty(); + sendPacket.byte4ToBuf(0); + client->sendPacketTcp(&sendPacket); + + /****/ + } + + // Always write the points (even if empty) because this signifies + // the end of the map for the client. + //if (myMap->getPoints()->begin() != myMap->getPoints()->end()) + //{ + writeMapToClient("DATA", client); + // if we want to send points then send 'em + if (myDataToSend == POINTS || myDataToSend == BOTH) + { + // myMap->writePointsToFunctor(pointsFunctor, NULL, sendScanType); + /**/ + for (std::list::iterator iter = scanTypeList.begin(); + iter != scanTypeList.end(); + iter++) { + const char *scanType = (*iter).c_str(); + ArLog::log(ArLog::Normal, + "ArServerHandlerMap::serverGetMapBinary() sending points for %s", + scanType); + myMap->writePointsToFunctor(pointsFunctor, scanType, NULL); + } // end for each scan type + /**/ + ArNetPacket sendPacket; + sendPacket.empty(); + sendPacket.byte4ToBuf(0); + client->sendPacketTcp(&sendPacket); + } + // if not just say we're done + else + writeMapToClient("", client); + //} + + // send an empty packet to say we're done + ArNetPacket emptyPacket; + client->sendPacketTcp(&emptyPacket); + + myMap->unlock(); + ArLog::log(ArLog::Verbose, "Finished sending map (binary) to client"); + + // delete textFunctor; + + delete textFunctor; + textFunctor = NULL; + delete linesFunctor; + linesFunctor = NULL; + delete pointsFunctor; + pointsFunctor = NULL; + +} + +AREXPORT void ArServerHandlerMap::serverGetMapMultiScans(ArServerClient *client, + ArNetPacket *packet) +{ + + sendMapWithMaxCategory(client, ArMapInterface::MAP_CATEGORY_2D_MULTI_SOURCES); + +} // end method serverGetMapMultiScans + + +/// Requests that the server send the map with the specified maximum features. +AREXPORT void ArServerHandlerMap::serverGetMapWithMaxCategory(ArServerClient *client, + ArNetPacket *packet) +{ + + std::string category = ArMapInterface::MAP_CATEGORY_2D; + if (packet != NULL) { + + char tempBuf[512]; + packet->bufToStr(tempBuf, sizeof(tempBuf)); + category = tempBuf; + + ArLog::log(ArLog::Normal, + "ArServerHandlerMap::serverGetMapWithMaxCategory() %s requested", + tempBuf); + } + + if ((category.empty()) || + (ArUtil::strcasecmp(category, ArMapInterface::MAP_CATEGORY_2D) == 0) ) { + + serverGetMapBinary(client, packet); + + } + else if ((ArUtil::strcasecmp(category, ArMapInterface::MAP_CATEGORY_2D_MULTI_SOURCES) == 0) || + (ArUtil::strcasecmp(category, ArMapInterface::MAP_CATEGORY_2D_EXTENDED) == 0)) { + + sendMapWithMaxCategory(client, category.c_str()); + } + else { // unrecognized request + + ArLog::log(ArLog::Normal, + "ArServerHandlerMap does not recognize request for %s, sending max known map (%s)", + category.c_str(), + ArMapInterface::MAP_CATEGORY_2D_EXTENDED); + + sendMapWithMaxCategory(client, ArMapInterface::MAP_CATEGORY_2D_EXTENDED); + } + +} // end method serverGetMapWithMaxCategory + + +AREXPORT void ArServerHandlerMap::sendMapWithMaxCategory(ArServerClient *client, + const char *maxCategory) +{ + ArLog::LogLevel level = ArLog::Verbose; + + ArLog::log(level, + "Starting sending map (%s) to client", maxCategory); + + if (myMap == NULL) + { + ArLog::log(level, + "ArServerHandlerMap::sendMapWithMaxCategory() NULL map"); + + writeMapToClient("", client); + return; + } + + myMap->lock(); + // This functor is used to send the map header and objects in text format. + ArFunctor1 *textFunctor = + new ArFunctor2C + (this, + &ArServerHandlerMap::writeMapToClient, + NULL, + client); + + // This functor is used to send the map data lines in binary format (since + // it is faster). + ArFunctor2 *> *linesFunctor = + new ArFunctor3C *, ArServerClient *> + (this, + &ArServerHandlerMap::writeLinesToClient, + 0, + NULL, + client); + + // This functor is used to send the map data points in binary format (since + // it is faster). + ArFunctor2 *> *pointsFunctor = + new ArFunctor3C *, ArServerClient *> + (this, + &ArServerHandlerMap::writePointsToClient, + 0, + NULL, + client); + + // Send the map up to but not including the DATA tag. + myMap->writeObjectsToFunctor(textFunctor, + "", + false, + maxCategory); + + std::list scanTypeList = myMap->getScanTypes(); + + if (!scanTypeList.empty()) { + + // see if we want to send the lines and make sure we have lines + if (myDataToSend == LINES || myDataToSend == BOTH) { + + for (std::list::iterator iter = scanTypeList.begin(); + iter != scanTypeList.end(); + iter++) { + const char *scanType = (*iter).c_str(); + if ((myMap->getLines(scanType) != NULL) && + (!myMap->getLines(scanType)->empty())) { + + myMap->writeLinesToFunctor(linesFunctor, + scanType, + textFunctor); + ArNetPacket sendPacket; + sendPacket.empty(); + sendPacket.byte4ToBuf(0); + client->sendPacketTcp(&sendPacket); + } + } + } + if (myDataToSend == POINTS || myDataToSend == BOTH) { + + // TODO This is different than getMapBinary -- in that DATA is not necessarily + // always sent. Is this going to be a problem? + + for (std::list::iterator iter = scanTypeList.begin(); + iter != scanTypeList.end(); + iter++) { + const char *scanType = (*iter).c_str(); + if ((myMap->getPoints(scanType) != NULL) && + (!myMap->getPoints(scanType)->empty())) { + + myMap->writePointsToFunctor(pointsFunctor, + scanType, + textFunctor); + ArNetPacket sendPacket; + sendPacket.empty(); + sendPacket.byte4ToBuf(0); + client->sendPacketTcp(&sendPacket); + } + } + } + } // end if scan types + + // send an empty packet to say we're done + ArNetPacket emptyPacket; + client->sendPacketTcp(&emptyPacket); + + myMap->unlock(); + ArLog::log(level, "Finished sending map (%s) to client", maxCategory); + + // delete textFunctor; + + delete textFunctor; + textFunctor = NULL; + delete linesFunctor; + linesFunctor = NULL; + delete pointsFunctor; + pointsFunctor = NULL; + +} // end method sendMapWithMaxCategory + + + +/** @internal */ +AREXPORT void ArServerHandlerMap::serverGetGoals(ArServerClient *client, + ArNetPacket *packet) +{ + std::list::iterator objIt; + ArMapObject* obj; + ArPose goal; + ArNetPacket sendPacket; + + for (objIt = myMap->getMapObjects()->begin(); + objIt != myMap->getMapObjects()->end(); + objIt++) + { + // + // Get the forbidden lines and fill the occupancy grid there. + // + obj = (*objIt); + if (obj == NULL) + break; + if (strcasecmp(obj->getType(), "GoalWithHeading") == 0 || + strcasecmp(obj->getType(), "Goal") == 0) + { + sendPacket.strToBuf(obj->getName()); + } + } + client->sendPacketTcp(&sendPacket); +} + +AREXPORT void ArServerHandlerMap::mapChanged(void) +{ + ArNetPacket emptyPacket; + ArLog::log(ArLog::Normal, + "ArServerHandlerMap::mapChanged() orig = %s new = %s", + myMapFileName, + myMap->getFileName()); + + strncpy(myMapFileName, myMap->getFileName(), 512); + myMapFileName[511] = 0; + myServer->broadcastPacketTcp(&emptyPacket, "mapUpdated"); + myServer->broadcastPacketTcp(&emptyPacket, "goalsUpdated"); +} + + +AREXPORT void ArServerHandlerMap::handleCheckMap(ArServerClient *client, + ArNetPacket *packet) +{ + + if (!myOwnMap) { + ArLog::log(ArLog::Normal, "ArServerHandlerMap::handleCheckMap map not owned"); + myMap->refresh(); + + } + else { + ArLog::log(ArLog::Normal, "ArServerHandlerMap::handleCheckMap map is owned, checking config"); + processFile(); + } + +} // end method handleCheckMap + + +/** @internal */ +AREXPORT bool ArServerHandlerMap::processFile(void) +{ + struct stat mapFileStat; + + if (myMapFileName[0] == '\0') + { + ArLog::log(ArLog::Normal, "ArServerHandlerMap::processFile: No map file"); + return true; + } + + if (stat(myMapFileName, &mapFileStat) != 0) + { + ArLog::log(ArLog::Terse, "Cannot stat file"); + return false; + } + // see if we need to load the map file + if (!myAlreadyLoaded || + strcmp(myMapFileName, myLastMapFile) != 0 || + mapFileStat.st_mtime != myLastMapFileStat.st_mtime || + mapFileStat.st_ctime != myLastMapFileStat.st_ctime) + { + myAlreadyLoaded = true; + strcpy(myLastMapFile, myMapFileName); + memcpy(&myLastMapFileStat, &mapFileStat, sizeof(mapFileStat)); + + ArLog::log(ArLog::Terse, "Loading map %s", myMapFileName); + if (!loadMap(myMapFileName)) + { + ArLog::log(ArLog::Terse, "Failed loading map %s", myMapFileName); + return false; + } + ArLog::log(ArLog::Terse, "Loaded map %s", myMapFileName); + return true; + } + myAlreadyLoaded = true; + ArLog::log(ArLog::Normal, "ArServerHandlerMapConfig: File did not need reloading"); + return true; +} + diff --git a/Legacy/Aria/ArNetworking/src/ArServerHandlerMapping.cpp b/Legacy/Aria/ArNetworking/src/ArServerHandlerMapping.cpp new file mode 100644 index 0000000..9a2e36a --- /dev/null +++ b/Legacy/Aria/ArNetworking/src/ArServerHandlerMapping.cpp @@ -0,0 +1,713 @@ +#include "Aria.h" +#include "ArExport.h" +#include "ArServerHandlerMapping.h" + +/** + @param server the server to add the handlers too + + @param robot the robot to map from + + @param laser the laser to map with + + @param baseDirectory the directory to put the map file into when + its done, NULL or an empty string means into the working directory + + @param tempDirectory the directory to put the map file into while + its being created, if this is NULL or empty it'll use the base directory + **/ +AREXPORT ArServerHandlerMapping::ArServerHandlerMapping( + ArServerBase *server, ArRobot *robot, ArLaser *laser, + const char *baseDirectory, const char *tempDirectory, + bool useReflectorValues, ArLaser *laser2, + const char *suffix, const char *suffix2, + std::list *extraLasers) : + myTempDirectoryHelper(baseDirectory, tempDirectory), + myZipFile(NULL), + mySnapshotZipFile(NULL), + myMappingStartCB(this, &ArServerHandlerMapping::serverMappingStart), + myMappingEndCB(this, &ArServerHandlerMapping::serverMappingEnd), + myMappingStatusCB(this, &ArServerHandlerMapping::serverMappingStatus), + myPacketHandlerCB(this, &ArServerHandlerMapping::packetHandler), + myLoopStartCB(this, &ArServerHandlerMapping::simpleLoopStart), + myLoopEndCB(this, &ArServerHandlerMapping::simpleLoopEnd) +{ + myServer = server; + myRobot = robot; + myLaser = laser; + myUseReflectorValues = useReflectorValues; + + myLaser2 = laser2; + if (suffix != NULL) + mySuffix = suffix; + if (suffix2 != NULL) + mySuffix2 = suffix2; + + myExtraLasers = extraLasers; + + if (myServer != NULL) + { + myServer->addData("mappingStart", "Starts making a map", + &myMappingStartCB, "string: name of map file", + "byte: 0 (started mapping), 1 (already mapping), 2 (could not start map)", + "Mapping", "RETURN_SINGLE"); + myServer->addData("mappingEnd", "Stops making a map", + &myMappingEndCB, "none", + "byte: 0 (ended mapping), 1 (no mapping to end), 2 (could not move temporary file to permanent file)", + "Mapping", "RETURN_SINGLE"); + myServer->addData("mappingStatus", "Gets the status of mapping", + &myMappingStatusCB, "none", + "string: mapName if mapping, empty string if not mapping", + "RobotInfo", "RETURN_SINGLE"); + myServer->addData("mappingStatusBroadcast", "Gets the status of mapping, also sent when mapping starts or ends (this is a new/better mappingStatus)", + &myMappingStatusCB, "none", + "string: mapName if mapping, empty string if not mapping", + "RobotInfo", "RETURN_SINGLE"); + } + myLaserLogger = NULL; + myLaserLogger2 = NULL; + myMapName = ""; + myFileName = ""; + myHandlerCommands = NULL; + + myPacketHandlerCB.setName("ArServerHandlerMapping"); + if (myRobot != NULL) + myRobot->addPacketHandler(&myPacketHandlerCB); +} + +AREXPORT ArServerHandlerMapping::~ArServerHandlerMapping() +{ + if (myLaserLogger != NULL) + { + delete myLaserLogger; + myLaserLogger = NULL; + } + + if (myLaserLogger2 != NULL) + { + delete myLaserLogger; + myLaserLogger = NULL; + } +} + +AREXPORT void ArServerHandlerMapping::serverMappingStart( + ArServerClient *client, ArNetPacket *packet) +{ + ArNetPacket sendPacket; + char buf[512]; + packet->bufToStr(buf, sizeof(buf)); + + // see if we're already mapping + if (myLaserLogger != NULL) + { + ArLog::log(ArLog::Normal, "MappingStart: Map already being made"); + sendPacket.byteToBuf(1); + if (client != NULL) + client->sendPacketTcp(&sendPacket); + return; + } + + + myRobot->lock(); + + // lower case everything (to avoid case conflicts) + ArUtil::lower(buf, buf, sizeof(buf)); + myMapName = buf; + + myFileName = myMapName; + if (!mySuffix.empty()) + myFileName += mySuffix; + if (strstr(myMapName.c_str(), ".2d") == NULL) + myFileName += ".2d"; + + if (myLaser2 != NULL) + { + myFileName2 = myMapName; + if (!mySuffix2.empty()) + myFileName2 += mySuffix2; + if (strstr(myMapName.c_str(), ".2d") == NULL) + myFileName2 += ".2d"; + } + + + // call our mapping started callbacks + std::list::iterator fit; + ArFunctor *functor; + for (fit = myMappingStartCallbacks.begin(); + fit != myMappingStartCallbacks.end(); + fit++) + { + functor = (*fit); + functor->invoke(); + } + + + myLaserLogger = new ArLaserLogger(myRobot, myLaser, 300, 25, myFileName.c_str(), + true, Aria::getJoyHandler(), + myTempDirectoryHelper.getTempDirectory(), + myUseReflectorValues, + Aria::getRobotJoyHandler(), + &myLocationDataMap, + myExtraLasers); + if (myLaserLogger == NULL) + { + ArLog::log(ArLog::Normal, "MappingStart: myLaserLogger == NULL"); + sendPacket.byteToBuf(2); + if (client != NULL) + client->sendPacketTcp(&sendPacket); + myMapName = ""; + myFileName = ""; + myRobot->unlock(); + return; + } + if (!myLaserLogger->wasFileOpenedSuccessfully()) + { + ArLog::log(ArLog::Normal, "MappingStart: Cannot open map file %s", + myFileName.c_str()); + sendPacket.byteToBuf(2); + if (client != NULL) + client->sendPacketTcp(&sendPacket); + myMapName = ""; + myFileName = ""; + delete myLaserLogger; + myLaserLogger = NULL; + myRobot->unlock(); + return; + } + + if (myLaser2 != NULL) + { + myLaserLogger2 = new ArLaserLogger(myRobot, myLaser2, 300, 25, + myFileName2.c_str(), + true, Aria::getJoyHandler(), + myTempDirectoryHelper.getTempDirectory(), + myUseReflectorValues, + Aria::getRobotJoyHandler(), + &myLocationDataMap); + } + + // toss our strings for the start on there + std::list::iterator it; + + for (it = myStringsForStartOfLog.begin(); + it != myStringsForStartOfLog.end(); + it++) + { + myLaserLogger->addInfoToLogPlain((*it).c_str()); + if (myLaserLogger2 != NULL) + myLaserLogger2->addInfoToLogPlain((*it).c_str()); + } + + // call our mapping started callbacks + for (fit = myMappingBegunCallbacks.begin(); + fit != myMappingBegunCallbacks.end(); + fit++) + { + functor = (*fit); + functor->invoke(); + } + + + myRobot->unlock(); + + + ArLog::log(ArLog::Normal, "MappingStart: Map %s started", + myMapName.c_str()); + sendPacket.byteToBuf(0); + if (client != NULL) + client->sendPacketTcp(&sendPacket); + + ArNetPacket broadcastPacket; + broadcastPacket.strToBuf(myFileName.c_str()); + myServer->broadcastPacketTcp(&broadcastPacket, "mappingStatusBroadcast"); +} + + +AREXPORT void ArServerHandlerMapping::serverMappingEnd( + ArServerClient *client, ArNetPacket *packet) +{ + std::list::iterator fit; + + ArNetPacket sendPacket; + if (myLaserLogger == NULL) + { + ArLog::log(ArLog::Normal, "MappingEnd: No map being made"); + sendPacket.byteToBuf(1); + if (client != NULL) + client->sendPacketTcp(&sendPacket); + return; + } + + myRobot->lock(); + + delete myLaserLogger; + myLaserLogger = NULL; + + bool haveFile2 = false; + + if (myLaserLogger2 != NULL) + { + haveFile2 = true; + delete myLaserLogger2; + myLaserLogger2 = NULL; + } + + + std::list sourceFileNameList; + sourceFileNameList.push_back(myFileName); + if (haveFile2) { + sourceFileNameList.push_back(myFileName2); + } + + bool isSuccess = myTempDirectoryHelper.moveFilesToBaseDirectory + (sourceFileNameList); + + if (isSuccess) { + sendPacket.uByte2ToBuf(0); + } + else { + sendPacket.uByte2ToBuf(2); + } + + + ArLog::log(ArLog::Normal, "MappingEnd: Stopped mapping %s", + myFileName.c_str()); + + // call our mapping end callbacks + for (fit = myMappingEndCallbacks.begin(); + fit != myMappingEndCallbacks.end(); + fit++) + (*fit)->invoke(); + + + // Call the mapping ended callbacks + for (fit = myMappingEndedCallbacks.begin(); + fit != myMappingEndedCallbacks.end(); + fit++) { + (*fit)->invoke(); + } + + // Clear the internal file names + myMapName = ""; + myFileName = ""; + + myRobot->unlock(); + if (client != NULL) + client->sendPacketTcp(&sendPacket); + + ArNetPacket broadcastPacket; + broadcastPacket.strToBuf(myFileName.c_str()); + myServer->broadcastPacketTcp(&broadcastPacket, "mappingStatusBroadcast"); +} + + +AREXPORT void ArServerHandlerMapping::serverMappingStatus( + ArServerClient *client, ArNetPacket *packet) +{ + ArNetPacket sendPacket; + sendPacket.strToBuf(myMapName.c_str()); + client->sendPacketTcp(&sendPacket); +} + +AREXPORT void ArServerHandlerMapping::addStringForStartOfLogs( + const char *str, ArListPos::Pos position) +{ + if (position == ArListPos::FIRST) + myStringsForStartOfLog.push_front(str); + else if (position == ArListPos::LAST) + myStringsForStartOfLog.push_back(str); + else + ArLog::log(ArLog::Terse, "ArServerHandlerMapping::addStringForStartOfLogs: Invalid position."); +} + +AREXPORT void ArServerHandlerMapping::remStringForStartOfLogs( + const char *str) +{ + myStringsForStartOfLog.remove(str); +} + +AREXPORT void ArServerHandlerMapping::addMappingStartCallback( + ArFunctor *functor, ArListPos::Pos position) +{ + if (position == ArListPos::FIRST) + myMappingStartCallbacks.push_front(functor); + else if (position == ArListPos::LAST) + myMappingStartCallbacks.push_back(functor); + else + ArLog::log(ArLog::Terse, + "ArServerHandlerMapping::addMappingStartCallback: Invalid position."); +} + +AREXPORT void ArServerHandlerMapping::remMappingStartCallback( + ArFunctor *functor) +{ + myMappingStartCallbacks.remove(functor); +} + +AREXPORT void ArServerHandlerMapping::addMappingBegunCallback( + ArFunctor *functor, ArListPos::Pos position) +{ + if (position == ArListPos::FIRST) + myMappingBegunCallbacks.push_front(functor); + else if (position == ArListPos::LAST) + myMappingBegunCallbacks.push_back(functor); + else + ArLog::log(ArLog::Terse, + "ArServerHandlerMapping::addMappingBegunCallback: Invalid position."); +} + +AREXPORT void ArServerHandlerMapping::remMappingBegunCallback( + ArFunctor *functor) +{ + myMappingBegunCallbacks.remove(functor); +} + +AREXPORT void ArServerHandlerMapping::addMappingEndCallback( + ArFunctor *functor, ArListPos::Pos position) +{ + if (position == ArListPos::FIRST) + myMappingEndCallbacks.push_front(functor); + else if (position == ArListPos::LAST) + myMappingEndCallbacks.push_back(functor); + else + ArLog::log(ArLog::Terse, + "ArServerHandlerMapping::addMappingEndCallback: Invalid position."); +} + +AREXPORT void ArServerHandlerMapping::remMappingEndCallback( + ArFunctor *functor) +{ + myMappingEndCallbacks.remove(functor); +} + + +AREXPORT void ArServerHandlerMapping::addMappingEndedCallback( + ArFunctor *functor, ArListPos::Pos position) +{ + if (position == ArListPos::FIRST) + myMappingEndedCallbacks.push_front(functor); + else if (position == ArListPos::LAST) + myMappingEndedCallbacks.push_back(functor); + else + ArLog::log(ArLog::Terse, + "ArServerHandlerMapping::addMappingEndedCallback: Invalid position."); +} + +AREXPORT void ArServerHandlerMapping::remMappingEndedCallback( + ArFunctor *functor) +{ + myMappingEndedCallbacks.remove(functor); +} + + + + +AREXPORT void ArServerHandlerMapping::addPreMoveCallback( + ArFunctor *functor, ArListPos::Pos position) +{ + myTempDirectoryHelper.addPreMoveCallback(functor, position); +} + +AREXPORT void ArServerHandlerMapping::remPreMoveCallback( + ArFunctor *functor) +{ + myTempDirectoryHelper.remPreMoveCallback(functor); +} + +AREXPORT void ArServerHandlerMapping::addPostMoveCallback( + ArFunctor *functor, ArListPos::Pos position) +{ + myTempDirectoryHelper.addPostMoveCallback(functor, position); +} + +AREXPORT void ArServerHandlerMapping::remPostMoveCallback( + ArFunctor *functor) +{ + myTempDirectoryHelper.remPostMoveCallback(functor); +} + + + +AREXPORT void ArServerHandlerMapping::addSimpleCommands( + ArServerHandlerCommands *handlerCommands) +{ + myHandlerCommands = handlerCommands; + myHandlerCommands->addStringCommand( + "mappingLoopStart", + "If mapping is happening it starts a new loop with the tag of the given string", + &myLoopStartCB); + + myHandlerCommands->addStringCommand( + "mappingLoopEnd", + "If mapping is happening it ends a loop with the tag of the given string", + &myLoopEndCB); +} + +AREXPORT void ArServerHandlerMapping::simpleLoopStart(ArArgumentBuilder *arg) +{ + if (myLaserLogger != NULL) + myLaserLogger->addTagToLog("loop start %s", arg->getFullString()); + if (myLaserLogger2 != NULL) + myLaserLogger2->addTagToLog("loop start %s", arg->getFullString()); +} + +AREXPORT void ArServerHandlerMapping::simpleLoopEnd(ArArgumentBuilder *arg) +{ + if (myLaserLogger != NULL) + myLaserLogger->addTagToLog("loop stop %s", arg->getFullString()); + if (myLaserLogger2 != NULL) + myLaserLogger2->addTagToLog("loop stop %s", arg->getFullString()); +} + +/// The packet handler for starting/stopping scans from the lcd +AREXPORT bool ArServerHandlerMapping::packetHandler(ArRobotPacket *packet) +{ + // we return these as processed to help out the ArLaserLogger class + if (packet->getID() == 0x96) + return true; + + if (packet->getID() != 0x97) + return false; + + myRobot->unlock(); + char argument = packet->bufToByte(); + if (argument == 1) + { + // see if we're already mapping + if (myLaserLogger != NULL) + { + ArLog::log(ArLog::Normal, + "ArServerHandlerMapping::packetHandler: Start scan requested when already mapping"); + } + else + { + // build a name + time_t now; + struct tm nowStruct; + now = time(NULL); + char buf[1024]; + + if (ArUtil::localtime(&now, &nowStruct)) + { + sprintf(buf, "%02d%02d%02d_%02d%02d%02d", + (nowStruct.tm_year%100), nowStruct.tm_mon+1, nowStruct.tm_mday, + nowStruct.tm_hour, nowStruct.tm_min, nowStruct.tm_sec); + } + else + { + ArLog::log(ArLog::Normal, + "ArServerHandlerMapping::packetHandler: Could not make good packet name (error getting time), so just naming it \"lcd\""); + sprintf(buf, "lcd"); + } + + ArLog::log(ArLog::Normal, "Starting scan '%s' from LCD", buf); + ArNetPacket fakePacket; + fakePacket.strToBuf(buf); + fakePacket.finalizePacket(); + serverMappingStart(NULL, &fakePacket); + } + } + else if (argument == 0) + { + if (myLaserLogger == NULL) + { + ArLog::log(ArLog::Normal, + "ArServerHandlerMapping::packetHandler: Stop scan requested when not mapping"); + } + else + { + ArLog::log(ArLog::Normal, "Stopping scan from LCD"); + serverMappingEnd(NULL, NULL); + } + } + else + { + ArLog::log(ArLog::Normal, "ArServerHandlerMapping::packetHandler: Unknown scan argument %d", argument); + } + myRobot->lock(); + return true; +} + +AREXPORT void ArServerHandlerMapping::addTagToLog(const char *str) +{ + if (myLaserLogger != NULL) + myLaserLogger->addTagToLogPlain(str); + if (myLaserLogger2 != NULL) + myLaserLogger2->addTagToLogPlain(str); +} + +AREXPORT void ArServerHandlerMapping::addInfoToLog(const char *str) +{ + if (myLaserLogger != NULL) + myLaserLogger->addInfoToLogPlain(str); + if (myLaserLogger2 != NULL) + myLaserLogger2->addInfoToLogPlain(str); +} + +AREXPORT const char * ArServerHandlerMapping::getFileName(void) +{ + return myFileName.c_str(); +} + +AREXPORT const char * ArServerHandlerMapping::getMapName(void) +{ + return myMapName.c_str(); +} + +AREXPORT bool ArServerHandlerMapping::isMapping(void) +{ + if (myLaserLogger != NULL) + return true; + else + return false; +} + +AREXPORT bool ArServerHandlerMapping::addLocationData( + const char *name, + ArRetFunctor3 *functor) +{ + if (myLocationDataMap.find(name) != myLocationDataMap.end()) + { + ArLog::log(ArLog::Normal, "ArServerHandlerMapping::addLocationData: Already have location data for %s", name); + return false; + } + ArLog::log(ArLog::Normal, "ArServerHandlerMapping: Added location data %s", + name); + myLocationDataMap[name] = functor; + return true; +} + + /// Get location data map (mostly for internal things) +AREXPORT const std::map *, + ArStrCaseCmpOp> * +ArServerHandlerMapping::getLocationDataMap(void) +{ + return &myLocationDataMap; +} + + +AREXPORT void ArServerHandlerMapping::addStringsForStartOfLogToMap( + ArMap *arMap) +{ + std::list::iterator it; + std::string str; + ArArgumentBuilder *builder; + + for (it = myStringsForStartOfLog.begin(); + it != myStringsForStartOfLog.end(); + it++) + { + str = (*it); + builder = new ArArgumentBuilder; + builder->add(str.c_str()); + if (strcasecmp(builder->getArg(0), "LogInfoStrip:") == 0) + { + builder->removeArg(0, true); + printf("lis %s\n", builder->getFullString()); + + } + std::list infoNames = arMap->getInfoNames(); + for (std::list::iterator iter = infoNames.begin(); + iter != infoNames.end(); + iter++) + { + const char *curName = (*iter).c_str(); + + if (strcasecmp(builder->getArg(0), curName) == 0) + { + builder->removeArg(0, true); + arMap->getInfo(curName)->push_back(builder); + builder = NULL; + break; + } + } + if (builder != NULL) + delete builder; + } +} + + +/** + * When the optional zip file feature is used, this method should be called with + * a valid file in the context of a "mapping start" callback. The file should + * have been opened in ZIP_MODE, and should remain open until after all of the + * "mapping end" callbacks have completed. The file should be closed and this + * method should be called with a NULL pointer within the context of a "mapping + * ended" callback. + * + * It is the application's responsibility to create and manage the zip file. + * Not all applications will use this feature. + * + * @param zipFile a pointer to the optional ArZippable instance in which + * scan results can be stored +**/ +AREXPORT void ArServerHandlerMapping::setZipFile(ArZippable *zipFile) +{ + myZipFile = zipFile; +} + +/** + * If snapshots are enabled when the optional zip file feature is used, this + * method should be called with a valid file in the context of a "mapping start" + * callback. The file should have been opened in ZIP_MODE, and should remain + * open until after all of the "mapping end" callbacks have completed. The file + * should be closed and this method should be called with a NULL pointer within + * the context of a "mapping ended" callback. The file should then be added to + * the main mapping zip file. + * + * It is the application's responsibility to create and manage the zip file. + * Not all applications will use this feature. + * + * @param zipFile a pointer to the optional ArZippable instance in which + * snapshots can be stored +**/ +AREXPORT void ArServerHandlerMapping::setSnapshotZipFile(ArZippable *zipFile) +{ + mySnapshotZipFile = zipFile; +} + +/** + * This method returns a pointer to the optional zip file associated with the + * mapping session. The file should be opened before the "mapping begun" + * callbacks are invoked, and should be closed after the "mapping end" callbacks are + * invoked. + * + * It is the application's responsibility to create and manage the zip file. + * Not all applications will use this feature. + * + * @param zipFile a pointer to the optional ArZippable instance in which + * scan results can be stored; NULL if there is no active zip file +**/ +AREXPORT ArZippable *ArServerHandlerMapping::getZipFile() +{ + return myZipFile; + +} // end method getZipFile + +/** + * This method returns a pointer to a second optional zip file associated with the + * mapping session. It contains the snapshot images, and is eventually added to the + * main mapping zip file. The file should be opened before the "mapping begun" + * callbacks are invoked, and should be closed after the "mapping end" callbacks are + * invoked. + * + * It is the application's responsibility to create and manage the zip file. + * Not all applications will use this feature. + * + * @param zipFile a pointer to the optional ArZippable instance in which + * scan results can be stored; NULL if there is no active zip file +**/ +AREXPORT ArZippable *ArServerHandlerMapping::getSnapshotZipFile() +{ + return mySnapshotZipFile; + +} // end method getZipFile + + +AREXPORT void ArServerHandlerMapping::forceReading(void) +{ + if (myLaserLogger != NULL) + myLaserLogger->takeReading(); + if (myLaserLogger2 != NULL) + myLaserLogger2->takeReading(); +} diff --git a/Legacy/Aria/ArNetworking/src/ArServerHandlerPopup.cpp b/Legacy/Aria/ArNetworking/src/ArServerHandlerPopup.cpp new file mode 100644 index 0000000..bb71666 --- /dev/null +++ b/Legacy/Aria/ArNetworking/src/ArServerHandlerPopup.cpp @@ -0,0 +1,413 @@ +#include "Aria.h" +#include "ArExport.h" +#include "ArServerHandlerPopup.h" + +ArServerHandlerPopup::PopupData::PopupData( + ArServerHandlerPopupInfo *popupInfo, ArTypes::Byte4 id, + ArFunctor2 *callback) +{ + myPopupInfo = new ArServerHandlerPopupInfo(*popupInfo); + myID = id; + myCallback = callback; + myStarted.setToNow(); +} + +ArServerHandlerPopup::PopupData::~PopupData() +{ + delete myPopupInfo; +} + +AREXPORT ArServerHandlerPopup::ArServerHandlerPopup(ArServerBase *server) : + myNetPopupClickedCB(this, &ArServerHandlerPopup::netPopupClicked), + myNetPopupListCB(this, &ArServerHandlerPopup::netPopupList), + myServerCycleCB(this, &ArServerHandlerPopup::serverCycleCallback) +{ + myDataMutex.setLogName("ArServerHandlerPopup::myDataMutex"); + myServer = server; + myServer->addData( + "popupCreate", + "Tells the gui to create a new popup", + NULL, + "none (you can't send this command to the server)", + "byte4: id of this particular popup; string: ignoreIdentifier; string: title; string: message; byte: popupType (0 = NoIcon, 1 = Information, 2 = Warning, 3 = Critical, 4 = Question); string: button0Label; string: button1Label; string: button2Label; byte: defaultButton; byte: escapeButton", + "PopupGui", "RETURN_SINGLE"); + myServer->addData( + "popupClose", + "Closes a popup that was created", + NULL, + "none (you can't send this command to the server)", + "byte4: id of the popup to close; string: string to display", + "PopupGui", "RETURN_SINGLE"); + myServer->addData( + "popupClicked", + "Returns the clicked data of a popup ", + &myNetPopupClickedCB, + "byte4: id of the popup that was clicked; byte: buttonClicked", + "no response", + "PopupGui", "RETURN_NONE"); + myServer->addData( + "popupList", + "Resends all the popupCreates to this client that asked for this", + &myNetPopupListCB, + "none", + "technically none, but it resends all the popupCreate events that are active", + "PopupGui", "RETURN_NONE"); + myServer->addCycleCallback(&myServerCycleCB); + myLastTimeCheck.setToNow(); + myLastID = 0; + +} + + +AREXPORT ArServerHandlerPopup::~ArServerHandlerPopup() +{ + +} + + +/** + Creates a popup, for information about whats in the popup see + ArServerHandlerPopupInfo... this just describes what happens with + the popup... + + So you pass in a popupInfo for the popup you want and a functor to + call when buttons in the popup are pushed, this returns an id for + that popup, which you can use to cancel the popup and so you know + which popup this is.... the callback (if there is one) will be + called when the popup has a button pushed with the id and the + number of the button or -1 if the popup timed out or -2 if it was + canceled. The popup has a timeout, so that if no clients are + connected watching for popups or if no one is paying attention that + things can move on easily. + + @param popupInfo the information that describes the popup... this + class makes a copy of the information so you can do whatever you + want with the information after you've called this function (ie + change the button and call it again or whatever) + + @param callback The class will call this function when one of the + buttons is pressed in the popup on one of the clients, the callback + will be called with the long int being the ID, and the int being + the button that is pushed (or -1 if the timeout happened or -2 if + it was closed) + **/ +AREXPORT ArTypes::Byte4 ArServerHandlerPopup::createPopup( + ArServerHandlerPopupInfo *popupInfo, + ArFunctor2 *callback) +{ + PopupData *popupData; + ArTypes::Byte4 retID; + + myDataMutex.lock(); + // first find a good id + myLastID++; + if (myLastID < 0) + myLastID = 1; + //printf("Checking if id %u is good\n", myLastID); + while (myMap.find(myLastID) != myMap.end()) + { + myLastID++; + if (myLastID < 0) + myLastID = 1; + } + //printf("Got id %d\n", myLastID); + popupData = new PopupData(popupInfo, myLastID, callback); + myMap[myLastID] = popupData; + + ArNetPacket sendingPacket; + buildPacket(&sendingPacket, popupData); + + /* + printf("!!! %s %s %s\n", + popupData->myPopupInfo->getButton0Label(), + popupData->myPopupInfo->getButton1Label(), + popupData->myPopupInfo->getButton2Label()); + */ + myServer->broadcastPacketTcp(&sendingPacket, "popupCreate"); + retID = myLastID; + myDataMutex.unlock(); + return retID; +} + +void ArServerHandlerPopup::buildPacket(ArNetPacket *sendingPacket, + PopupData *popupData) +{ + sendingPacket->byte4ToBuf(popupData->myID); + sendingPacket->strToBuf(popupData->myPopupInfo->getIgnoreIdentifier()); + sendingPacket->strToBuf(popupData->myPopupInfo->getTitle()); + sendingPacket->strToBuf(popupData->myPopupInfo->getMessage()); + sendingPacket->byteToBuf((ArTypes::Byte) + popupData->myPopupInfo->getPopupType()); + sendingPacket->strToBuf(popupData->myPopupInfo->getButton0Label()); + sendingPacket->strToBuf(popupData->myPopupInfo->getButton1Label()); + sendingPacket->strToBuf(popupData->myPopupInfo->getButton2Label()); + sendingPacket->byteToBuf(popupData->myPopupInfo->getDefaultButtonNumber()); + sendingPacket->byteToBuf(popupData->myPopupInfo->getEscapeButtonNumber()); +} + +AREXPORT void ArServerHandlerPopup::closePopup(ArTypes::Byte4 id, + const char *closeMessage) +{ + ArNetPacket sendingPacket; + PopupData *popupData; + std::map::iterator it; + + myDataMutex.lock(); + if ((it = myMap.find(id)) == myMap.end()) + { + ArLog::log(ArLog::Verbose, + "Cannot close popup %u as it doesn't exist (anymore at least)", + id); + myDataMutex.unlock(); + } + else + { + popupData = (*it).second; + sendingPacket.byte4ToBuf(id); + sendingPacket.strToBuf(closeMessage); + myMap.erase(id); + myDataMutex.unlock(); + delete popupData; + if (popupData->myCallback != NULL) + popupData->myCallback->invoke(popupData->myID, -2); + myServer->broadcastPacketTcp(&sendingPacket, "popupClose"); + } +} + +AREXPORT void ArServerHandlerPopup::netPopupClicked(ArServerClient *client, + ArNetPacket *packet) +{ + ArNetPacket sendingPacket; + PopupData *popupData; + std::map::iterator it; + + ArTypes::Byte4 id; + ArTypes::Byte button; + + id = packet->bufToByte4(); + button = packet->bufToByte(); + + myDataMutex.lock(); + if ((it = myMap.find(id)) == myMap.end()) + { + ArLog::log(ArLog::Verbose, + "Cannot close popup %u for client %s as it doesn't exist (anymore at least)", + id, client->getIPString()); + myDataMutex.unlock(); + } + else + { + popupData = (*it).second; + sendingPacket.byte4ToBuf(id); + if (button == 0) + sendingPacket.strToBuf(popupData->myPopupInfo->getButton0Pressed()); + else if (button == 1) + sendingPacket.strToBuf(popupData->myPopupInfo->getButton1Pressed()); + else if (button == 2) + sendingPacket.strToBuf(popupData->myPopupInfo->getButton2Pressed()); + else + sendingPacket.strToBuf("Popup closed because of odd click"); + myMap.erase(id); + myDataMutex.unlock(); + if (popupData->myCallback != NULL) + popupData->myCallback->invoke(popupData->myID, button); + delete popupData; + myServer->broadcastPacketTcp(&sendingPacket, "popupClose"); + } + + +} + +AREXPORT void ArServerHandlerPopup::netPopupList(ArServerClient *client, + ArNetPacket *packet) +{ + ArLog::log(ArLog::Normal, "Sending popup list"); + + std::map::iterator it; + ArNetPacket sendingPacket; + PopupData *popupData; + + myDataMutex.lock(); + for (it = myMap.begin(); it != myMap.end(); it++) + { + popupData = (*it).second; + sendingPacket.empty(); + + ArLog::log(ArLog::Normal, "Sending popup %d", popupData->myID); + buildPacket(&sendingPacket, popupData); + sendingPacket.setCommand(myServer->findCommandFromName("popupCreate")); + + client->sendPacketTcp(&sendingPacket); + } + + sendingPacket.empty(); + client->sendPacketTcp(&sendingPacket); + ArLog::log(ArLog::Normal, "Sent popups"); + myDataMutex.unlock(); +} + +AREXPORT void ArServerHandlerPopup::serverCycleCallback(void) +{ + std::map::iterator it; + ArNetPacket sendingPacket; + PopupData *popupData; + int timeout; + + std::list doneIDs; + std::list donePopups; + myDataMutex.lock(); + // only check it if we haven't checked it lately + if (myLastTimeCheck.mSecSince() > 1000) + { + myLastTimeCheck.setToNow(); + for (it = myMap.begin(); it != myMap.end(); it++) + { + popupData = (*it).second; + if ((timeout = popupData->myPopupInfo->getTimeout()) > 0 && + popupData->myStarted.secSince() >= timeout) + { + sendingPacket.empty(); + sendingPacket.byte4ToBuf((*it).first); + sendingPacket.strToBuf(popupData->myPopupInfo->getTimeoutString()); + myServer->broadcastPacketTcp(&sendingPacket, "popupClose"); + doneIDs.push_back((*it).first); + donePopups.push_back(popupData); + + } + } + } + while (doneIDs.begin() != doneIDs.end()) + { + myMap.erase((*doneIDs.begin())); + doneIDs.pop_front(); + } + myDataMutex.unlock(); + + std::list::iterator donePopupIt; + while ((donePopupIt = donePopups.begin()) != donePopups.end()) + { + popupData = (*donePopupIt); + if (popupData->myCallback != NULL) + popupData->myCallback->invoke(popupData->myID, -1); + delete popupData; + donePopups.pop_front(); + } +} + + +AREXPORT ArServerHandlerPopupInfo::ArServerHandlerPopupInfo( + const char *ignoreIdentifier, const char *title, const char *message, + ArServerHandlerPopup::PopupType popupType, + ArTypes::Byte defaultButtonNumber, ArTypes::Byte escapeButtonNumber, + int timeoutInSeconds, const char *timeoutString, + const char *button0Label, const char *button0Pressed, + const char *button1Label, const char *button1Pressed, + const char *button2Label, const char *button2Pressed) +{ + if (ignoreIdentifier != NULL) + myIgnoreIdentifier = ignoreIdentifier; + else + myIgnoreIdentifier = ""; + if (title != NULL) + myTitle = title; + else + myTitle = ""; + if (message != NULL) + myMessage = message; + else + myMessage = ""; + myPopupType = popupType; + myDefaultButtonNumber = defaultButtonNumber; + myEscapeButtonNumber = escapeButtonNumber; + myTimeout = timeoutInSeconds; + if (timeoutString != NULL) + myTimeoutString = timeoutString; + else + myTimeoutString = ""; + + if (button0Label != NULL) + myButton0Label = button0Label; + else + myButton0Label = ""; + if (button0Pressed != NULL) + myButton0Pressed = button0Pressed; + else + myButton0Pressed = ""; + if (button1Label != NULL) + myButton1Label = button1Label; + else + myButton1Label = ""; + if (button1Pressed != NULL) + myButton1Pressed = button1Pressed; + else + myButton1Pressed = ""; + if (button2Label != NULL) + myButton2Label = button2Label; + else + myButton2Label = ""; + if (button2Pressed != NULL) + myButton2Pressed = button2Pressed; + else + myButton2Pressed = ""; + + /* + printf("@@ 0l %s 0p %s 1l %s 1p %s 2l %s 2p%s\n", + myButton0Label.c_str(), myButton0Pressed.c_str(), + myButton1Label.c_str(), myButton1Pressed.c_str(), + myButton2Label.c_str(), myButton2Pressed.c_str()); + */ +} + +AREXPORT ArServerHandlerPopupInfo::~ArServerHandlerPopupInfo() +{ + +} + +AREXPORT ArServerHandlerPopupInfo::ArServerHandlerPopupInfo( + const ArServerHandlerPopupInfo &popupInfo) +{ + myIgnoreIdentifier = popupInfo.myIgnoreIdentifier; + myTitle = popupInfo.myTitle; + myMessage = popupInfo.myMessage; + myPopupType = popupInfo.myPopupType; + myDefaultButtonNumber = popupInfo.myDefaultButtonNumber; + myEscapeButtonNumber = popupInfo.myEscapeButtonNumber; + myTimeout = popupInfo.myTimeout; + myTimeoutString = popupInfo.myTimeoutString; + myButton0Label = popupInfo.myButton0Label; + myButton0Pressed = popupInfo.myButton0Pressed; + myButton1Label = popupInfo.myButton1Label; + myButton1Pressed = popupInfo.myButton1Pressed; + myButton2Label = popupInfo.myButton2Label; + myButton2Pressed = popupInfo.myButton2Pressed; + /* + printf("## 0l %s 0p %s 1l %s 1p %s 2l %s 2p%s\n", + myButton0Label.c_str(), myButton0Pressed.c_str(), + myButton1Label.c_str(), myButton1Pressed.c_str(), + myButton2Label.c_str(), myButton2Pressed.c_str()); + */ +} + + +AREXPORT ArServerHandlerPopupInfo &ArServerHandlerPopupInfo::operator=( + const ArServerHandlerPopupInfo &popupInfo) +{ + if (this != &popupInfo) + { + myIgnoreIdentifier = popupInfo.myIgnoreIdentifier; + myTitle = popupInfo.myTitle; + myMessage = popupInfo.myMessage; + myPopupType = popupInfo.myPopupType; + myDefaultButtonNumber = popupInfo.myDefaultButtonNumber; + myEscapeButtonNumber = popupInfo.myEscapeButtonNumber; + myTimeout = popupInfo.myTimeout; + myTimeoutString = popupInfo.myTimeoutString; + myButton0Label = popupInfo.myButton0Label; + myButton0Pressed = popupInfo.myButton0Pressed; + myButton1Label = popupInfo.myButton1Label; + myButton1Pressed = popupInfo.myButton1Pressed; + myButton2Label = popupInfo.myButton2Label; + myButton2Pressed = popupInfo.myButton2Pressed; + } + return *this; +} diff --git a/Legacy/Aria/ArNetworking/src/ArServerInfoDrawings.cpp b/Legacy/Aria/ArNetworking/src/ArServerInfoDrawings.cpp new file mode 100644 index 0000000..6ad8175 --- /dev/null +++ b/Legacy/Aria/ArNetworking/src/ArServerInfoDrawings.cpp @@ -0,0 +1,265 @@ +#include "Aria.h" +#include "ArExport.h" +#include "ArServerInfoDrawings.h" + +AREXPORT ArServerInfoDrawings::ArServerInfoDrawings(ArServerBase *server) : + myNetListDrawingsCB(this, &ArServerInfoDrawings::netListDrawings), + myNetGetDrawingListCB(this, &ArServerInfoDrawings::netGetDrawingList) +{ + myServer = server; + + if (myServer != NULL) + { + myServer->addData("listDrawings", + "Deprecated; use getDrawingList instead. Gets a list of things that can be drawn", + &myNetListDrawingsCB, + "none", + "byte4: numDrawings, string: name, string: shape, byte4: primaryColor(0RGB), byte4: size, byte4: layer, byte4: defaultRefreshTime(0 == don't request refresh), byte4: secondaryColor(0RGB)", "SensorInfo", "RETURN_SINGLE"); + myServer->addData("getDrawingList", + "Gets a list of items to be drawn on the map. Each packet contains one drawing. Terminates on empty packet.", + &myNetGetDrawingListCB, + "none", + "For each drawing, a packet that contains: string: name, string: shape, byte4: primaryColor(0RGB), byte4: size, byte4: layer, byte4: defaultRefreshTime(0 == don't request refresh), byte4: secondaryColor(0RGB), string: visibility", + "SensorInfo", "RETURN_UNTIL_EMPTY"); + } + +} + +AREXPORT ArServerInfoDrawings::~ArServerInfoDrawings() +{ + +} + +/** + @note 'name' must be unique. + If the name is unique, the given drawing data is stored to be returned + in response to the "listDrawings" client request, and a new data request + is created with the given name and functor. This functor must send + a reply packet to the client containing a 4-byte integer indicating the + number of coordinates or vertices in the figure, followed by a pair of + 4-byte integers for each coordinate or vertex in global map space. + For example, if drawingData describes a polyDots shape, + then the functor must create a packet, add a 4-byte integer indicating the + number of dots, then for each dot, add an integer for the X coordinate followed + by an integer for the Y coordinate. + */ +AREXPORT bool ArServerInfoDrawings::addDrawing(ArDrawingData *drawingData, + const char *name, + ArFunctor2 *functor) +{ + if (myDrawingDatas.find(name) != myDrawingDatas.end() || + myDrawingCallbacks.find(name) != myDrawingCallbacks.end()) + { + ArLog::log(ArLog::Normal, "ArServerInfoDrawings::addDrawing: Already a drawing of name '%s'", name); + return false; + } + if (myServer == NULL || + !myServer->addData(name, "", functor, "none", + "See getDrawingList for the information on how this drawing should be drawn, and the documentation in ArDrawingData for that information means.", "SensorInfo", + "RETURN_SINGLE")) + { + ArLog::log(ArLog::Normal, + "ArServerInfoDrawings::addDrawing: Could not add data of name '%s' to server", + name); + return false; + } + myDrawingDatas[name] = drawingData; + myDrawingCallbacks[name] = functor; + return true; +} + +AREXPORT void ArServerInfoDrawings::netListDrawings(ArServerClient *client, + ArNetPacket *packet) +{ + ArNetPacket sendingPacket; + std::map::iterator it; + + sendingPacket.byte4ToBuf(myDrawingDatas.size()); + for (it = myDrawingDatas.begin(); it != myDrawingDatas.end(); it++) + { + sendingPacket.strToBuf((*it).first.c_str()); + sendingPacket.strToBuf((*it).second->getShape()); + sendingPacket.byte4ToBuf((*it).second->getPrimaryColor().colorToByte4()); + sendingPacket.byte4ToBuf((*it).second->getSize()); + sendingPacket.byte4ToBuf((*it).second->getLayer()); + sendingPacket.uByte4ToBuf((*it).second->getDefaultRefreshTime()); + sendingPacket.byte4ToBuf((*it).second->getSecondaryColor().colorToByte4()); + } + client->sendPacketTcp(&sendingPacket); +} + +AREXPORT void ArServerInfoDrawings::netGetDrawingList(ArServerClient *client, + ArNetPacket *packet) +{ + ArNetPacket sendingPacket; + + // TODO: Any need to protect the map by a mutex? + + for (std::map::iterator it = + myDrawingDatas.begin(); + it != myDrawingDatas.end(); + it++) + { + sendingPacket.empty(); + + sendingPacket.strToBuf((*it).first.c_str()); + sendingPacket.strToBuf((*it).second->getShape()); + sendingPacket.byte4ToBuf((*it).second->getPrimaryColor().colorToByte4()); + sendingPacket.byte4ToBuf((*it).second->getSize()); + sendingPacket.byte4ToBuf((*it).second->getLayer()); + sendingPacket.uByte4ToBuf((*it).second->getDefaultRefreshTime()); + sendingPacket.byte4ToBuf((*it).second->getSecondaryColor().colorToByte4()); + sendingPacket.strToBuf((*it).second->getVisibility()); + + client->sendPacketTcp(&sendingPacket); + + } // end for each drawing + + sendingPacket.empty(); + client->sendPacketTcp(&sendingPacket); +} + +AREXPORT bool ArServerInfoDrawings::addRangeDevice(ArRangeDevice *rangeDevice) +{ + bool ret = true; + char name[512]; + if (myServer == NULL) + { + ArLog::log(ArLog::Normal, "ArServerInfoDrawings::addRangeDeviceForDrawing: srever is NULL"); + return false; + } + sprintf(name, "%sCurrent", rangeDevice->getName()); + // LEAK a little when called, shouldn't be called more than a few + // times and isn't a leak unless its called more than once + if (rangeDevice->getCurrentDrawingData() != NULL && + !addDrawing(rangeDevice->getCurrentDrawingData(), name, + new ArFunctor3C(this, &ArServerInfoDrawings::netRangeDeviceCurrent, NULL, NULL, rangeDevice))) + { + ArLog::log(ArLog::Normal, + "ArServerInfoDrawings::addRangeDevice: Could not add data for range device '%s' to server ('%s')", rangeDevice->getName(), name); + ret = false; + } + sprintf(name, "%sCumulative", rangeDevice->getName()); + if (rangeDevice->getCumulativeDrawingData() != NULL && + !addDrawing(rangeDevice->getCumulativeDrawingData(), name, + new ArFunctor3C(this, &ArServerInfoDrawings::netRangeDeviceCumulative, NULL, NULL, rangeDevice))) + { + ArLog::log(ArLog::Normal, + "ArServerInfoDrawings::addRangeDevice: Could not add data for range device '%s' to server ('%s')", rangeDevice->getName(), name); + ret = false; + } + return ret; +} + +AREXPORT bool ArServerInfoDrawings::addRobotsRangeDevices(ArRobot *robot) +{ + std::list::iterator it; + bool ret = true; + ArRangeDevice *device; + //printf("0\n"); + if (robot == NULL || robot->getRangeDeviceList() == NULL) + { + ArLog::log(ArLog::Terse, "InfoDrawings::addRobotsRangeDevices: Robot or robot's range device list is NULL"); + return false; + } + //printf("1\n"); + for (it = robot->getRangeDeviceList()->begin(); + it != robot->getRangeDeviceList()->end(); + it++) + { + device = (*it); + //printf("2 %s\n", device->getName()); + device->lockDevice(); + if (!addRangeDevice(device)) + ret = false; + device->unlockDevice(); + } + //printf("3\n"); + return ret; +} + +AREXPORT void ArServerInfoDrawings::netRangeDeviceCurrent( + ArServerClient *client, ArNetPacket *packet, ArRangeDevice *device) +{ + ArNetPacket sendPacket; + std::list *readings; + std::list::iterator it; + + device->lockDevice(); + readings = device->getCurrentBuffer(); + if (readings == NULL) + { + ArLog::log(ArLog::Verbose, "ArServerInfoDrawing::netRangeDeviceCurrent: No current buffer for %s", device->getName()); + device->unlockDevice(); + sendPacket.byte4ToBuf(0); + client->sendPacketUdp(&sendPacket); + return; + } + + sendPacket.byte4ToBuf(readings->size()); + for (it = readings->begin(); it != readings->end(); it++) + { + sendPacket.byte4ToBuf(ArMath::roundInt((*it)->getX())); + sendPacket.byte4ToBuf(ArMath::roundInt((*it)->getY())); + } + device->unlockDevice(); + client->sendPacketUdp(&sendPacket); + +} + + +AREXPORT void ArServerInfoDrawings::netRangeDeviceCumulative( + ArServerClient *client, ArNetPacket *packet, ArRangeDevice *device) +{ + ArNetPacket sendPacket; + std::list *readings; + std::list::iterator it; + + device->lockDevice(); + readings = device->getCumulativeBuffer(); + if (readings == NULL) + { + ArLog::log(ArLog::Verbose, "ArServerInfoDrawing::netRangeDeviceCumulative: No cumulative buffer for %s", device->getName()); + device->unlockDevice(); + sendPacket.byte4ToBuf(0); + client->sendPacketUdp(&sendPacket); + return; + } + + sendPacket.byte4ToBuf(readings->size()); + for (it = readings->begin(); it != readings->end(); it++) + { + sendPacket.byte4ToBuf(ArMath::roundInt((*it)->getX())); + sendPacket.byte4ToBuf(ArMath::roundInt((*it)->getY())); + } + device->unlockDevice(); + client->sendPacketUdp(&sendPacket); + +} + + +AREXPORT ArDrawingData *ArServerInfoDrawings::internalGetDrawingData( + const char *name) +{ + if (myDrawingDatas.find(name) == myDrawingDatas.end()) + { + ArLog::log(ArLog::Normal, "ArServerInfoDrawings::internalGetDrawingData: No drawing of name '%s'", name); + return NULL; + } + return myDrawingDatas[name]; +} + +AREXPORT ArFunctor2 *ArServerInfoDrawings::internalGetDrawingCallback(const char *name) +{ + if (myDrawingCallbacks.find(name) == myDrawingCallbacks.end()) + { + ArLog::log(ArLog::Normal, "ArServerInfoDrawings::internalGetDrawingCallback: No drawing of name '%s'", name); + return NULL; + } + return myDrawingCallbacks[name]; +} + diff --git a/Legacy/Aria/ArNetworking/src/ArServerInfoRobot.cpp b/Legacy/Aria/ArNetworking/src/ArServerInfoRobot.cpp new file mode 100644 index 0000000..66b4cf9 --- /dev/null +++ b/Legacy/Aria/ArNetworking/src/ArServerInfoRobot.cpp @@ -0,0 +1,270 @@ +#include "Aria.h" +#include "ArExport.h" +#include "ArServerInfoRobot.h" +#include "ArServerMode.h" + + +AREXPORT ArServerInfoRobot::ArServerInfoRobot(ArServerBase *server, + ArRobot *robot) : + myUpdateCB(this, &ArServerInfoRobot::update), + myUpdateNumbersCB(this, &ArServerInfoRobot::updateNumbers), + myUpdateStringsCB(this, &ArServerInfoRobot::updateStrings), + myBatteryInfoCB(this, &ArServerInfoRobot::batteryInfo), + myPhysicalInfoCB(this, &ArServerInfoRobot::physicalInfo), + myActivityTimeInfoCB(this, &ArServerInfoRobot::activityTimeInfo), + myUserTaskCB(this, &ArServerInfoRobot::userTask) +{ + myServer = server; + myRobot = robot; + + myServer->addData("update", + "gets an update about the important robot status (you should request this at an interval)... for bandwidth savings this is deprecated in favor of updateNumbers and updateStrings", + &myUpdateCB, "none", + "string: status; string: mode; byte2: 10 * battery; byte4: x; byte4: y; byte2: th; byte2: transVel; byte2: rotVel, byte2: latVel, byte: temperature (deg c, -128 means unknown)", "RobotInfo", + "RETURN_SINGLE"); + + myServer->addData("updateNumbers", + "gets an update about the important robot status (you should request this at an interval)", + &myUpdateNumbersCB, "none", + "byte2: 10 * battery; byte4: x; byte4: y; byte2: th; byte2: transVel; byte2: rotVel, byte2: latVel, byte: temperature (deg c, -128 means unknown)", "RobotInfo", + "RETURN_SINGLE"); + + myServer->addData("updateStrings", + "gets an update about the important robot status (you should ask for this at -1 interval since it is broadcast when the strings change)", + &myUpdateStringsCB, "none", + "string: status; string: mode; string: extended status (this has newlines)", "RobotInfo", + "RETURN_SINGLE"); + + + myServer->addData("batteryInfo", + "gets the low battery voltage and shutdown voltage (you only need to request this once)", + &myBatteryInfoCB, "none", + "double: low battery voltage, double: shutdown battery voltage: ubyte: voltageIsStateOfCharge, if 0 voltage (including update voltage) is really voltage, if 1 voltage (including update voltage) is state of charge", + "RobotInfo", + "RETURN_SINGLE"); + + myServer->addData("physicalInfo", + "gets the information about the physical robot (you only need to request this once)", + &myPhysicalInfoCB, "none", + "string: robotType; string: robotSubType; byte2: robotWidth; byte2: robotLengthFront; byte2: robotLengthRear; byte: 0 means no lateral control, 1 means lateral control", + "RobotInfo", "RETURN_SINGLE"); + + myServer->addData("activityTimeInfo", + "Returns information about the active server mode's last activity time", + &myActivityTimeInfoCB, "none", + "byte4: seconds since", + "RobotInfo", "RETURN_SINGLE"); + myUserTaskCB.setName("ArServerInfoRobot"); + myRobot->addUserTask("ArServerInfoRobot", 50, &myUserTaskCB); + +} + +AREXPORT ArServerInfoRobot::~ArServerInfoRobot() +{ +} + +AREXPORT void ArServerInfoRobot::update(ArServerClient *client, + ArNetPacket *packet) +{ + ArNetPacket sending; + + myRobot->lock(); + + ArServerMode *netMode; + if ((netMode = ArServerMode::getActiveMode()) != NULL) + { + sending.strToBuf(netMode->getStatus()); + sending.strToBuf(netMode->getMode()); + } + else + { + sending.strToBuf("Unknown status"); + sending.strToBuf("Unknown mode"); + } + + + //ArLog::log(ArLog::Normal, + // "ArServerInfoRobot::update() havestateofcharge = %d, soc = %f, real = %f, reg = %f", + // myRobot->haveStateOfCharge(), + // myRobot->getStateOfCharge(), + // myRobot->getRealBatteryVoltage(), + // myRobot->getBatteryVoltage()); + + if (myRobot->haveStateOfCharge()) + sending.byte2ToBuf(ArMath::roundInt(myRobot->getStateOfCharge() * 10)); + else if (myRobot->getRealBatteryVoltage() > 0) + sending.byte2ToBuf(ArMath::roundInt( + myRobot->getRealBatteryVoltage() * 10)); + else + sending.byte2ToBuf(ArMath::roundInt( + myRobot->getBatteryVoltage() * 10)); + + sending.byte4ToBuf((int)myRobot->getX()); + sending.byte4ToBuf((int)myRobot->getY()); + sending.byte2ToBuf((int)myRobot->getTh()); + sending.byte2ToBuf((int)myRobot->getVel()); + sending.byte2ToBuf((int)myRobot->getRotVel()); + sending.byte2ToBuf((int)myRobot->getLatVel()); + sending.byteToBuf((char)myRobot->getTemperature()); + //sending.byte2ToBuf((int)myRobot->getPayloadNumSlots()); + myRobot->unlock(); + + client->sendPacketUdp(&sending); +} + +AREXPORT void ArServerInfoRobot::updateNumbers(ArServerClient *client, + ArNetPacket *packet) +{ + ArNetPacket sending; + + myRobot->lock(); + + if (myRobot->haveStateOfCharge()) + sending.byte2ToBuf(ArMath::roundInt(myRobot->getStateOfCharge() * 10)); + else if (myRobot->getRealBatteryVoltage() > 0) + sending.byte2ToBuf(ArMath::roundInt( + myRobot->getRealBatteryVoltage() * 10)); + else + sending.byte2ToBuf(ArMath::roundInt( + myRobot->getBatteryVoltage() * 10)); + sending.byte4ToBuf((int)myRobot->getX()); + sending.byte4ToBuf((int)myRobot->getY()); + sending.byte2ToBuf((int)myRobot->getTh()); + sending.byte2ToBuf((int)myRobot->getVel()); + sending.byte2ToBuf((int)myRobot->getRotVel()); + sending.byte2ToBuf((int)myRobot->getLatVel()); + sending.byteToBuf((char)myRobot->getTemperature()); + //sending.byte2ToBuf((int)myRobot->getPayloadNumSlots()); + myRobot->unlock(); + + client->sendPacketUdp(&sending); +} + +AREXPORT void ArServerInfoRobot::updateStrings(ArServerClient *client, + ArNetPacket *packet) +{ + ArNetPacket sending; + + myRobot->lock(); + sending.strToBuf(myStatus.c_str()); + sending.strToBuf(myMode.c_str()); + sending.strToBuf(myExtendedStatus.c_str()); + myRobot->unlock(); + + client->sendPacketTcp(&sending); +} + + +AREXPORT void ArServerInfoRobot::batteryInfo(ArServerClient *client, + ArNetPacket *packet) +{ + ArNetPacket sending; + + myRobot->lock(); + if (myRobot->haveStateOfCharge()) + { + sending.doubleToBuf(myRobot->getStateOfChargeLow()); + sending.doubleToBuf(myRobot->getStateOfChargeShutdown()); + // voltage is really state of charge + sending.uByteToBuf(1); + } + else + { + const ArRobotConfigPacketReader *reader; + reader = myRobot->getOrigRobotConfig(); + if (reader != NULL && reader->hasPacketArrived()) + { + if (reader->getLowBattery() != 0) + sending.doubleToBuf(reader->getLowBattery() * .1); + else + sending.doubleToBuf(11.5); + if (reader->getShutdownVoltage() != 0) + sending.doubleToBuf(reader->getShutdownVoltage() * .1); + else + sending.doubleToBuf(11); + } + else + { + sending.doubleToBuf(11.5); + sending.doubleToBuf(11); + } + // voltage is voltage, not state of charge + sending.uByteToBuf(0); + } + + myRobot->unlock(); + client->sendPacketTcp(&sending); + +} + + +AREXPORT void ArServerInfoRobot::physicalInfo(ArServerClient *client, + ArNetPacket *packet) + +{ + ArNetPacket sending; + + myRobot->lock(); + sending.strToBuf(myRobot->getRobotType()); + sending.strToBuf(myRobot->getRobotSubType()); + sending.byte2ToBuf((int)myRobot->getRobotWidth()); + sending.byte2ToBuf((int)myRobot->getRobotLengthFront()); + sending.byte2ToBuf((int)myRobot->getRobotLengthRear()); + if (!myRobot->hasLatVel()) + sending.byteToBuf(0); + else + sending.byteToBuf(1); + myRobot->unlock(); + + client->sendPacketTcp(&sending); +} + + +AREXPORT void ArServerInfoRobot::activityTimeInfo( + ArServerClient *client, + ArNetPacket *packet) +{ + ArNetPacket sending; + + // TODO Not entirely sure whether the robot needs to be locked here, but + // it seems like it shouldn't hurt. + // + myRobot->lock(); + sending.byte4ToBuf(ArServerMode::getActiveModeActivityTimeSecSince()); + myRobot->unlock(); + + client->sendPacketTcp(&sending); + +} // end method activityTimeInfo + +void ArServerInfoRobot::userTask(void) +{ + ArServerMode *netMode; + ArNetPacket sending; + + if ((netMode = ArServerMode::getActiveMode()) != NULL) + { + myStatus = netMode->getStatus(); + myExtendedStatus = netMode->getExtendedStatus(); + if (myExtendedStatus.empty()) + myExtendedStatus = myStatus; + myMode = netMode->getMode(); + } + else + { + myStatus = "Unknown status"; + myExtendedStatus = "Unknown extended status"; + myMode = "Unknown mode"; + } + if (myStatus != myOldStatus || myMode != myOldMode || + myExtendedStatus != myOldExtendedStatus) + { + sending.strToBuf(myStatus.c_str()); + sending.strToBuf(myMode.c_str()); + sending.strToBuf(myExtendedStatus.c_str()); + myServer->broadcastPacketTcp(&sending, "updateStrings"); + } + myOldStatus = myStatus; + myOldMode = myMode; + myOldExtendedStatus = myExtendedStatus; +} diff --git a/Legacy/Aria/ArNetworking/src/ArServerInfoSensor.cpp b/Legacy/Aria/ArNetworking/src/ArServerInfoSensor.cpp new file mode 100644 index 0000000..37ebb37 --- /dev/null +++ b/Legacy/Aria/ArNetworking/src/ArServerInfoSensor.cpp @@ -0,0 +1,177 @@ +#include "Aria.h" +#include "ArExport.h" +#include "ArServerInfoSensor.h" + +AREXPORT ArServerInfoSensor::ArServerInfoSensor(ArServerBase *server, ArRobot *robot) : + myGetSensorListCB(this, &ArServerInfoSensor::getSensorList), + myGetSensorCurrentCB(this, &ArServerInfoSensor::getSensorCurrent), + myGetSensorCumulativeCB(this, &ArServerInfoSensor::getSensorCumulative) + +{ + myRobot = robot; + myServer = server; + + if (myServer != NULL) + { + /* + These are set as RETURN_COMPLEX since they won't work with the + connection forwarding stuff (since that can't deal with requests + set up like this) + */ + myServer->addData("getSensorList", + "gets a list of sensors attached to the robot", + &myGetSensorListCB, + "none", + "byte2: numSensors, repeating for numSensors: string: sensorName", + "SensorInfo", "RETURN_COMPLEX"); + + myServer->addData("getSensorCurrent", + "gets the current sensor readings for requested sensors", + &myGetSensorCurrentCB, + "string: sensorName", + "byte2: numReadings string: sensorName, repeating for numReadings times: byte4: x byte4: y.... if numReadings is -1 it means no sensor by that name", + "SensorInfo", "RETURN_COMPLEX"); + + myServer->addData("getSensorCumulative", + "gets the cumulative sensor readings for requested sensors", + &myGetSensorCumulativeCB, + "string: sensorName", + "byte2: numReadings string: sensorName, repeating for numReadings times: byte4: x byte4: y.... if numReadings is -1 it means no sensor by that name", + "SensorInfo", "RETURN_COMPLEX"); + } +} + +AREXPORT ArServerInfoSensor::~ArServerInfoSensor() +{ + +} + +AREXPORT void ArServerInfoSensor::getSensorList(ArServerClient *client, + ArNetPacket *packet) +{ + ArNetPacket sendPacket; + std::list *devList; + std::list::iterator it; + + myRobot->lock(); + devList = myRobot->getRangeDeviceList(); + + if (devList == NULL) + { + myRobot->unlock(); + client->sendPacketUdp(&sendPacket); + return; + } + + sendPacket.byte2ToBuf(devList->size()); + + for (it = devList->begin(); it != devList->end(); it++) + { + sendPacket.strToBuf((*it)->getName()); + } + myRobot->unlock(); + client->sendPacketUdp(&sendPacket); +} + + +AREXPORT void ArServerInfoSensor::getSensorCurrent(ArServerClient *client, + ArNetPacket *packet) +{ + ArRangeDevice *dev; + char sensor[512]; + std::list *readings; + std::list::iterator it; + + while (packet->getDataLength() > packet->getDataReadLength()) + { + ArNetPacket sendPacket; + + // find out the sensor they want + packet->bufToStr(sensor, sizeof(sensor)); + myRobot->lock(); + if ((dev = myRobot->findRangeDevice(sensor)) == NULL) + { + myRobot->unlock(); + ArLog::log(ArLog::Verbose, "ArServerInfoSensor::getSensorCurrent: No sensor %s", sensor); + sendPacket.byte2ToBuf(-1); + sendPacket.strToBuf(sensor); + client->sendPacketUdp(&sendPacket); + continue; + } + + myRobot->unlock(); + dev->lockDevice(); + readings = dev->getCurrentBuffer(); + if (readings == NULL) + { + dev->unlockDevice(); + ArLog::log(ArLog::Verbose, "ArServerInfoSensor::getSensorCurrent: No current buffer for %s", sensor); + sendPacket.byte2ToBuf(0); + sendPacket.strToBuf(sensor); + client->sendPacketUdp(&sendPacket); + continue; + } + + sendPacket.byte2ToBuf(readings->size()); + sendPacket.strToBuf(sensor); + for (it = readings->begin(); it != readings->end(); it++) + { + sendPacket.byte4ToBuf(ArMath::roundInt((*it)->getX())); + sendPacket.byte4ToBuf(ArMath::roundInt((*it)->getY())); + } + dev->unlockDevice(); + client->sendPacketUdp(&sendPacket); + } + + +} + +AREXPORT void ArServerInfoSensor::getSensorCumulative(ArServerClient *client, + ArNetPacket *packet) +{ + ArRangeDevice *dev; + char sensor[512]; + std::list *readings; + std::list::iterator it; + + while (packet->getDataLength() > packet->getDataReadLength()) + { + ArNetPacket sendPacket; + // find out the sensor they want + packet->bufToStr(sensor, sizeof(sensor)); + myRobot->lock(); + if ((dev = myRobot->findRangeDevice(sensor)) == NULL) + { + myRobot->unlock(); + ArLog::log(ArLog::Verbose, "ArServerInfoSensor::getSensorCumulative: No sensor %s", sensor); + sendPacket.byte2ToBuf(-1); + sendPacket.strToBuf(sensor); + client->sendPacketUdp(&sendPacket); + continue; + } + + myRobot->unlock(); + dev->lockDevice(); + readings = dev->getCumulativeBuffer(); + if (readings == NULL) + { + dev->unlockDevice(); + ArLog::log(ArLog::Verbose, "ArServerInfoSensor::getSensorCumulative: No current buffer for %s", sensor); + sendPacket.byte2ToBuf(0); + sendPacket.strToBuf(sensor); + client->sendPacketUdp(&sendPacket); + continue; + } + + sendPacket.byte2ToBuf(readings->size()); + sendPacket.strToBuf(sensor); + for (it = readings->begin(); it != readings->end(); it++) + { + sendPacket.byte4ToBuf(ArMath::roundInt((*it)->getX())); + sendPacket.byte4ToBuf(ArMath::roundInt((*it)->getY())); + } + dev->unlockDevice(); + client->sendPacketUdp(&sendPacket); + } + +} diff --git a/Legacy/Aria/ArNetworking/src/ArServerInfoStrings.cpp b/Legacy/Aria/ArNetworking/src/ArServerInfoStrings.cpp new file mode 100644 index 0000000..ab0ccc4 --- /dev/null +++ b/Legacy/Aria/ArNetworking/src/ArServerInfoStrings.cpp @@ -0,0 +1,138 @@ +#include "Aria.h" +#include "ArExport.h" +#include "ArServerInfoStrings.h" + +AREXPORT ArServerInfoStrings::ArServerInfoStrings(ArServerBase *server) : + myAddStringFunctor(this, &ArServerInfoStrings::addString), + myNetGetStringsInfoCB(this, &ArServerInfoStrings::netGetStringsInfo), + myNetGetStringsCB(this, &ArServerInfoStrings::netGetStrings) +{ + myStringsMutex.setLogName("ArServerInfoStrings::mySTringsMutex"); + myServer = server; + if (myServer != NULL) + { + myServer->addData("getStringsInfo", + "Gets the information about the 'getStrings' command", + &myNetGetStringsInfoCB, + "none", + "uByte2: count; repeating count times string: name, uByte2: maxlength", + "NavigationInfo", "RETURN_SINGLE"); + myServer->addData("getStrings", + "Gets the strings, for info about them see getStringsInfo", + &myNetGetStringsCB, + "none", + "byte2: count, repeating count: string", + "NavigationInfo", "RETURN_SINGLE"); + + } + myMaxMaxLength = 512; +} + +AREXPORT ArServerInfoStrings::~ArServerInfoStrings() +{ + +} + +AREXPORT void ArServerInfoStrings::buildStringsInfoPacket(void) +{ + myStringsMutex.lock(); + std::list::iterator it; + ArStringInfoHolder *info; + + myStringInfoPacket.empty(); + ArTypes::UByte2 count; + count = myStrings.size(); + myStringInfoPacket.uByte2ToBuf(count); + for (it = myStrings.begin(); it != myStrings.end(); it++) + { + info = (*it); + myStringInfoPacket.strToBuf(info->getName()); + myStringInfoPacket.uByte2ToBuf(info->getMaxLength()); + } + myStringsMutex.unlock(); +} + +AREXPORT void ArServerInfoStrings::buildStringsPacket(void) +{ + myStringsMutex.lock(); + + /* This part didn't work since the last string packet build was + * never set, so just commenting it since it caused problems when + * the value wrapped + if (myLastStringPacketBuild.mSecSince() < 100) + { + myStringsMutex.unlock(); + return; + } + */ + + myStringPacket.empty(); + std::list::iterator it; + ArStringInfoHolder *info; + + char *buf; + buf = new char[myMaxMaxLength+1]; + + for (it = myStrings.begin(); it != myStrings.end(); it++) + { + info = (*it); + info->getFunctor()->invoke(buf, info->getMaxLength()); + myStringPacket.strToBuf(buf); + } + + delete[] buf; + + myStringsMutex.unlock(); +} + +AREXPORT void ArServerInfoStrings::netGetStringsInfo(ArServerClient *client, + ArNetPacket *packet) +{ + buildStringsInfoPacket(); + client->sendPacketTcp(&myStringInfoPacket); +} + +AREXPORT void ArServerInfoStrings::netGetStrings(ArServerClient *client, + ArNetPacket *packet) +{ + buildStringsPacket(); + client->sendPacketTcp(&myStringPacket); +} + + +AREXPORT void ArServerInfoStrings::addString( + const char *name, ArTypes::UByte2 maxLength, + ArFunctor2 *functor) +{ + myStringsMutex.lock(); + if (myMaxMaxLength < maxLength) + myMaxMaxLength = maxLength; + myStrings.push_back(new ArStringInfoHolder(name, maxLength, functor)); + myStringsMutex.unlock(); + buildStringsInfoPacket(); + myServer->broadcastPacketTcp(&myStringInfoPacket, "getStringsInfo"); +} + + +AREXPORT ArStringInfoHolder *ArServerInfoStrings::internalGetStringInfoHolder( + const char *name) +{ + myStringsMutex.lock(); + std::list::iterator it; + ArStringInfoHolder *info; + + for (it = myStrings.begin(); it != myStrings.end(); it++) + { + info = (*it); + if (ArUtil::strcasecmp(info->getName(), name) == 0) + { + myStringsMutex.unlock(); + return info; + } + myStringInfoPacket.strToBuf(info->getName()); + myStringInfoPacket.uByte2ToBuf(info->getMaxLength()); + } + + myStringsMutex.unlock(); + return NULL; +} diff --git a/Legacy/Aria/ArNetworking/src/ArServerMode.cpp b/Legacy/Aria/ArNetworking/src/ArServerMode.cpp new file mode 100644 index 0000000..c61e053 --- /dev/null +++ b/Legacy/Aria/ArNetworking/src/ArServerMode.cpp @@ -0,0 +1,682 @@ +#include "Aria.h" +#include "ArExport.h" +#include "ArServerMode.h" +#include "ArServerModeIdle.h" +#include + +AREXPORT bool ArServerMode::ourActiveModeLocked = false; +AREXPORT bool ArServerMode::ourActiveModeWillUnlockIfRequested = false; +AREXPORT ArServerMode *ArServerMode::ourActiveMode = NULL; +AREXPORT ArServerMode *ArServerMode::ourNextActiveMode = NULL; +AREXPORT ArServerMode *ArServerMode::ourLastActiveMode = NULL; +AREXPORT std::list ArServerMode::ourDefaultModes; +AREXPORT std::list ArServerMode::ourRequestedActivateModes; +AREXPORT std::list ArServerMode::ourModes; +AREXPORT bool ArServerMode::ourUserTaskAdded = false; +AREXPORT ArGlobalFunctor ArServerMode::ourUserTaskCB( + ArServerMode::modeUserTask); +AREXPORT std::multimap ArServerMode::ourModeDataMap; +AREXPORT ArMutex ArServerMode::ourModeDataMapMutex; +AREXPORT ArGlobalFunctor2 ArServerMode::ourGetModeDataListCB( + ArServerMode::getModeDataList); +AREXPORT ArGlobalFunctor2 ArServerMode::ourGetModeInfoCB( + ArServerMode::getModeInfo); +AREXPORT ArGlobalFunctor2 + ArServerMode::ourGetModeBusyCB(ArServerMode::getModeBusy); + +AREXPORT bool ArServerMode::ourBroadcastActiveModeLocked = false; +AREXPORT ArServerMode *ArServerMode::ourBroadcastActiveMode = NULL; +AREXPORT bool ArServerMode::ourBroadcastActiveModeWillUnlockIfRequested = false; +AREXPORT bool ArServerMode::ourIsBusy = false; +AREXPORT ArServerBase *ArServerMode::ourServerBase = NULL; +AREXPORT ArServerModeIdle *ArServerMode::ourIdleMode = NULL; +AREXPORT ArMutex ArServerMode::ourIdleModeMutex; +AREXPORT bool ArServerMode::ourIdleModeCreated = false; +AREXPORT bool ArServerMode::ourActiveModeSetActivityThisCycle = false; + +AREXPORT void ArServerMode::modeUserTask(void) +{ + if (ourActiveMode != NULL) + { + ourActiveMode->mySetActivityThisCycle = false; + ourActiveMode->userTask(); + if (ourActiveMode != NULL) + ourActiveModeSetActivityThisCycle = ourActiveMode->mySetActivityThisCycle; + else + ourActiveModeSetActivityThisCycle = true; + } + else + { + std::list::iterator it; + for (it = ourDefaultModes.begin(); + it != ourDefaultModes.end() && ourActiveMode == NULL; + it++) + { + ArLog::log(ArLog::Terse, "Checking default on %s mode", (*it)->getName()); + (*it)->checkDefault(); + if (ourActiveMode != NULL) + { + ArLog::log(ArLog::Normal, "Activated %s mode as default", (*it)->getName()); + break; + } + } // end for each default mode + } // end else no active mode + + bool wasBusy = ourIsBusy; + // It seems to me that we wouldn't want to call the robot busy if there is no + // active mode. (Perhaps getActiveModeActivityTimeSecSince() should return + // something besides zero in this case.) + ourIsBusy = ((ourActiveMode != NULL) && + (ArServerMode::getActiveModeActivityTimeSecSince() == 0)); + + if (wasBusy != ourIsBusy) { + + if (ourServerBase != NULL) { + + //ArLog::log(ArLog::Normal, "ArServerMode busy changed: %i", ourIsBusy); + + ArNetPacket packet; + packet.byteToBuf(ourIsBusy); + + ourServerBase->broadcastPacketTcp(&packet, "modeBusyChanged"); + } + } // end if busy changed + +} // end method modeUserTask + + +AREXPORT ArServerMode::ArServerMode(ArRobot *robot, ArServerBase *server, + const char *name) +{ + ourModeDataMapMutex.setLogName("ArServerMode::ourModeDataMapMutex"); + + myName = name; + std::replace(myName.begin(), myName.end(), ' ', '_'); + + std::string activityMutexName; + activityMutexName = "ArServerMode::"; + activityMutexName += myName; + activityMutexName += "::myActivityTimeMutex"; + myActivityTimeMutex.setLogName(activityMutexName.c_str()); + myVerboseLogLevel = ArLog::Verbose; + myRobot = robot; + myServer = server; + myIsActive = false; + myStatusSetThisCycle = false; + ourModes.push_front(this); + myHasSetActivityTime = false; + mySetActivityThisCycle = false; + + std::string cbListName; + cbListName = "ArServerMode::"; + cbListName += myName; + cbListName += "::myActivateCallbacks"; + myActivateCallbacks.setName(cbListName.c_str()); + + cbListName = "ArServerMode::"; + cbListName += myName; + cbListName += "::myDeactivateCallbacks"; + myDeactivateCallbacks.setName(cbListName.c_str()); + + cbListName = "ArServerMode::"; + cbListName += myName; + cbListName += "::mySingleShotDeactivateCallbacks"; + mySingleShotDeactivateCallbacks.setName(cbListName.c_str()); + mySingleShotDeactivateCallbacks.setSingleShot(true); + + if (!ourUserTaskAdded) + { + ourUserTaskAdded = true; + myRobot->addUserTask("server mode", 50, &ourUserTaskCB); + myServer->addData("getModeDataList", "Gets the list of commands associated with modes.", + &ourGetModeDataListCB, + "none", + "ubyte4: numData; repeating numData times, string: mode; string: data", + "RobotInfo", "RETURN_SINGLE"); + myServer->addData("getModeInfo", "Gets the current mode active and if its locked and will or won't unlock (for lists of which commands are with which modes use getModeDataList) commands associated with modes.", + &ourGetModeInfoCB, + "none", + "string: mode; uByte: locked (1 == locked, 0 == unlocked); uByte: willUnlockIfRequested (1 == will, 0 == won't)", + "RobotInfo", "RETURN_SINGLE"); + + myServer->addData("modeBusyChanged", + "Broadcast when the busy state (non-zero idle time) of the active mode changes", + &ourGetModeBusyCB, + "None", + "byte: 1 if busy, 0 if idle", + "RobotInfo", + "RETURN_SINGLE"); + + } // end if static tasks and handlers not yet added + + // Storing the first occurrence of the server base for use in the static + // modeUserTask method. In general, there seems to be a single server base which + // isn't deleted during the program execution. However, if this should change, + // then will need to add a way of resetting the static ourServerBase. + if (ourServerBase == NULL) { + ourServerBase = server; + } + + ourIdleModeMutex.lock(); + if (ourIdleMode == NULL && !ourIdleModeCreated) + { + ourIdleModeCreated = true; + ourIdleModeMutex.unlock(); + ourIdleMode = new ArServerModeIdle(server, robot); + } + else + { + ourIdleModeMutex.unlock(); + } +} // end ctor + +AREXPORT ArServerMode::~ArServerMode() +{ + +} + +AREXPORT void ArServerMode::lockMode(bool willUnlockIfRequested) +{ + if (!myIsActive || ourActiveMode != this) + { + ArLog::log(myVerboseLogLevel, "ArServerMode::lockMode: mode %s could not lock because it is not active", getName()); + return; + } + ourActiveModeLocked = true; + ourActiveModeWillUnlockIfRequested = willUnlockIfRequested; + ArLog::log(myVerboseLogLevel, "Locked into %s mode, will unlock %s", + getName(), ArUtil::convertBool(willUnlockIfRequested)); + checkBroadcastModeInfoPacket(); +} + +AREXPORT void ArServerMode::unlockMode(void) +{ + if (!myIsActive || ourActiveMode != this) + { + ArLog::log(myVerboseLogLevel, "ArServerMode::unlockMode: mode %s could not unlock because it is not locked", getName()); + return; + } + ourActiveModeLocked = false; + ourActiveModeWillUnlockIfRequested = false; + ArLog::log(myVerboseLogLevel, "Unlocked from %s mode", getName()); + checkBroadcastModeInfoPacket(); +} + +/** + This should only be called from places where a forced unlock _HAS_ + to happen, ie on a robot joystick, but modes should do whatever + they have to in this to turn things off or what not. +**/ +AREXPORT void ArServerMode::forceUnlock(void) +{ + ArLog::log(ArLog::Terse, "Mode %s being forcibly unlocked", getName()); + unlockMode(); +} + +/// Gets whether we'll unlock if requested or not +AREXPORT bool ArServerMode::willUnlockIfRequested(void) +{ + if (ourActiveMode == NULL || !ourActiveModeLocked || + (ourActiveModeLocked && ourActiveModeWillUnlockIfRequested)) + return true; + else + return false; +} + +/// Gets if the active mode is locked or not +AREXPORT bool ArServerMode::isLocked(void) +{ + if (ourActiveMode == NULL || !ourActiveModeLocked) + return false; + else + return true; +} + +AREXPORT bool ArServerMode::isAutoResumeAfterInterrupt() +{ + return false; +} + + +/** + Makes this mode active if it can... If this returns false then the + mode's activate() method should just return... Note that before calling + this a mode should have already made sure it can activate... This also + calls the activate callbacks (only if the mode will be allowed to + activate of course). + + IMPORTANT: This method must only be called within the context of the + activate() method. + **/ + +AREXPORT bool ArServerMode::baseActivate(void) +{ + + // if we're locked then return false so nothing else activates + if (ourActiveMode != NULL && ourActiveMode != this && ourActiveModeLocked) + { + ArLog::log(myVerboseLogLevel, "Could not switch to %s mode because of lock.", + getName()); + + // request our active mode to unlock + // + // KMC: Moved the following line so that it is called after this mode is pushed + // onto the ourRequestedActivatedModes queue. Under certain conditions, + // the requestUnlock() call results in a mode being deactivated and the next + // queued mode being activated. This mode will essentially be pushed onto the + // queue too late -- and will either be ignored or activated at an unexpected + // time. (An example scenario occurs when the robot is going to dock, and the + // go-to-goal mode attempts to activate.) + // ourActiveMode->requestUnlock(); + + ArLog::log(myVerboseLogLevel, "Removing this (%s) from requested activate modes", + getName()); + + ourRequestedActivateModes.remove(this); + ArLog::log(myVerboseLogLevel, "Mode %s wants to be activated, adding to requested activate modes.", getName()); + + ourRequestedActivateModes.push_front(this); + + ourActiveMode->requestUnlock(); + + return false; + + } + + if (this != ourIdleMode && myServer->idleProcessingPending()) + { + if (ourActiveMode == ourIdleMode) + { + ArLog::log(myVerboseLogLevel, + "Since idle already active didn't set nextActiveMode when mode %s tried to activate, just returning", this->getName()); + return false; + } + ourNextActiveMode = ourIdleMode; + if (ourActiveMode != NULL) + ArLog::log(myVerboseLogLevel, + "Setting nextActiveMode explicitly to idle mode from mode %s trying to activate while %s is active", this->getName(), ourActiveMode->getName()); + else + ArLog::log(myVerboseLogLevel, + "Setting nextActiveMode explicitly to idle mode from mode %s trying to activate while no mode is active", this->getName()); + + if (ourActiveMode != NULL && ourActiveMode != ourIdleMode) + { + ourIdleMode->setModeInterrupted(ourActiveMode); + ourActiveMode->deactivate(); + } + ArLog::log(myVerboseLogLevel, "Removing this (%s) from requested activate modes", + getName()); + ourRequestedActivateModes.remove(this); + ArLog::log(myVerboseLogLevel, "Mode %s wants to be activated, denying for now because of idle, but adding to requested activate modes", getName()); + ourRequestedActivateModes.push_front(this); + ourIdleMode->activate(); + return false; + } + + ourNextActiveMode = this; + if (ourActiveMode != NULL) + ArLog::log(myVerboseLogLevel, "Setting nextActiveMode to mode %s (ourActiveMode %s)", + ourNextActiveMode->getName(), ourActiveMode->getName()); + else + ArLog::log(myVerboseLogLevel, "Setting nextActiveMode to mode %s (ourActiveMode NULL)", + ourNextActiveMode->getName()); + if (ourActiveMode != NULL) + ourActiveMode->deactivate(); + + myIsActive = true; + myActivityTimeMutex.lock(); + myActivityTime.setToNow(); + myActivityTimeMutex.unlock(); + + /* + if (myRobot != NULL) + { + myRobot->addUserTask(myName.c_str(), 50, &myUserTaskCB); + } + */ + ourLastActiveMode = ourActiveMode; + ourActiveMode = this; + ourNextActiveMode = NULL; + + ArLog::log(myVerboseLogLevel, "Setting nextActiveMode to NULL"); + if (myRobot != NULL) + { + myRobot->stop(); + myRobot->clearDirectMotion(); + } + /// Call our activate callbacks + myActivateCallbacks.invoke(); + /// Set the activity time to now, but do NOT set the flag, since that flag is used to determine if a particular mode has used it or not + ArLog::log(myVerboseLogLevel, "Activated %s mode", getName()); + checkBroadcastModeInfoPacket(); + return true; +} + +/** + Whenever a mode uses this it should already have done all of its + own deactivations (this also calls the deactive callbacks) + **/ +AREXPORT void ArServerMode::baseDeactivate(void) +{ + std::list::iterator it; + /* + for (it = ourDefaultModes.begin(); + it != ourDefaultModes.end(); + it++) + { + ArLog::log(myVerboseLogLevel, "defaults are %s mode", (*it)->getName()); + } + */ + // if we're the active mode, we're deactivating, and we're locked, then unlock + if (ourActiveMode != NULL && ourActiveMode == this && ourActiveModeLocked) + unlockMode(); + /* + if (myRobot != NULL) + myRobot->remUserTask(&myUserTaskCB); + */ + myIsActive = false; + if (ourActiveMode == this) + { + ourLastActiveMode = ourActiveMode; + ourActiveMode = NULL; + } + myDeactivateCallbacks.invoke(); + mySingleShotDeactivateCallbacks.invoke(); + + ArLog::log(myVerboseLogLevel, "Deactivated %s mode", getName()); + + if (ourNextActiveMode == NULL) + { + ArLog::log(myVerboseLogLevel, "No next active mode %s"); + + // walk through until one of these is ready + while ((it = ourRequestedActivateModes.begin()) != + ourRequestedActivateModes.end()) + { + std::string name; + name = (*it)->getName(); + ArLog::log(myVerboseLogLevel,"Trying to activate %s", name.c_str()); + + (*it)->activate(); + + if (ourActiveMode == ourIdleMode) + { + ArLog::log(myVerboseLogLevel, "Idle mode activated instead, so leaving the requestedActivateModes alone"); + return; + } + + ArLog::log(myVerboseLogLevel, "Popping front of requested activate modes (%s)"); + + ourRequestedActivateModes.pop_front(); + + if (ourActiveMode != NULL) + { + ArLog::log(myVerboseLogLevel, "and did, clearing requested activate modes (size = %i)", + ourRequestedActivateModes.size()); + // now clear out the old modes so that we don't wind up + // stacking too much. First, notify them that they will not be activated. + for (std::list::iterator dIter = ourRequestedActivateModes.begin(); + dIter != ourRequestedActivateModes.end(); + dIter++) + { + ArServerMode *deniedMode = *dIter; + if (deniedMode != NULL) + { + deniedMode->activationDenied(); + } + } + + ourRequestedActivateModes.clear(); + + ArLog::log(myVerboseLogLevel, + "Deactivate %s mode returns (1)", getName()); + return; + } + } // end while modes to activate + + ArLog::log(myVerboseLogLevel, "Deactivate did not activate any modes, clearing requested activate modes (size = %i)", ourRequestedActivateModes.size()); + + // now clear out the old modes so that we don't wind up stacking + // too much (should be empty anyways here, just make sure. (Same logic + // as above about notifying the mode that it won't be activated.) + for (std::list::iterator dIter = ourRequestedActivateModes.begin(); + dIter != ourRequestedActivateModes.end(); + dIter++) { + ArServerMode *deniedMode = *dIter; + if (deniedMode != NULL) { + deniedMode->activationDenied(); + } + } + ourRequestedActivateModes.clear(); + + for (it = ourDefaultModes.begin(); + it != ourDefaultModes.end() && ourActiveMode == NULL; + it++) + { + ArLog::log(ArLog::Normal, "Checking default on %s mode", (*it)->getName()); + (*it)->checkDefault(); + if (ourActiveMode != NULL) + { + //printf("and did\n"); + ArLog::log(myVerboseLogLevel, + "Deactivate %s mode returns (2)", getName()); + return; + } + } + } + else + { + ArLog::log(myVerboseLogLevel, "Our next active mode %s, removing it from requested activate modes", ourNextActiveMode->getName()); + ourRequestedActivateModes.remove(ourNextActiveMode); + } + ArLog::log(myVerboseLogLevel, + "Deactivate %s mode returns (3)", getName()); + +} + +/** + The default mode is activated whenever a mode is deactivated, even + if a mode is deactivated only for another mode to be activated + **/ +AREXPORT void ArServerMode::addAsDefaultMode(ArListPos::Pos pos) +{ + ArLog::log(ArLog::Normal, "Mode %s added as default mode", getName()); + if (pos == ArListPos::LAST) + ourDefaultModes.push_back(this); + else if (pos == ArListPos::FIRST) + ourDefaultModes.push_front(this); + else + { + ArLog::log(ArLog::Terse, "ArServerMode::addAsDefaultMode: bad list position."); + ourDefaultModes.push_front(this); + } +} + +AREXPORT ArTime ArServerMode::getActivityTime(void) +{ + ArTime ret; + myActivityTimeMutex.lock(); + ret = myActivityTime; + myActivityTimeMutex.unlock(); + return ret; +} + +AREXPORT void ArServerMode::setActivityTimeToNow(void) +{ + myActivityTimeMutex.lock(); + myHasSetActivityTime = true; + mySetActivityThisCycle = true; + myActivityTime.setToNow(); + myActivityTimeMutex.unlock(); +} + +AREXPORT int ArServerMode::getActiveModeActivityTimeSecSince(void) +{ + // chop this to an int so its easier to use, if you care about it + // use the getActivityTime on the ourActiveMode + if (ourActiveMode != NULL) + return (int)ourActiveMode->getActivityTime().secSince(); + else + return -1; +} + +AREXPORT bool ArServerMode::getActiveModeSetActivityThisCycle(void) +{ + return ourActiveModeSetActivityThisCycle; +} + +AREXPORT const char *ArServerMode::getActiveModeModeString(void) +{ + if (ourActiveMode != NULL) + return ourActiveMode->getMode(); + else + return NULL; +} + + +AREXPORT const char *ArServerMode::getActiveModeStatusString(void) +{ + if (ourActiveMode != NULL) + return ourActiveMode->getStatus(); + else + return NULL; +} + +AREXPORT const char *ArServerMode::getActiveModeExtendedStatusString(void) +{ + if (ourActiveMode != NULL) + return ourActiveMode->getExtendedStatus(); + else + return NULL; +} + +/** + This basically just notes the commands associated with a mode so + that clients can know what can and can't happen based on what mode + is active/locked/etc. You should call it only if the addData on + the ArServerBase returns true (since otherwise it means that + command wasn't added). +**/ +AREXPORT bool ArServerMode::addModeData( + const char *name, const char *description, + ArFunctor2 *functor, + const char *argumentDescription, const char *returnDescription, + const char *commandGroup, const char *dataFlags) +{ + if (myServer->addData(name, description, functor, argumentDescription, + returnDescription, commandGroup, dataFlags)) + { + ourModeDataMapMutex.lock(); + ourModeDataMap.insert(std::pair(myName, name)); + ourModeDataMapMutex.unlock(); + return true; + } + else + { + ArLog::log(ArLog::Normal, "ArServerMode %s: Could not add mode data %s", + myName.c_str(), name); + return false; + } + +} + +/** + This returns the list of which data is in which mode +**/ +AREXPORT void ArServerMode::getModeDataList(ArServerClient *client, + ArNetPacket *packet) + +{ + ourModeDataMapMutex.lock(); + ArNetPacket sending; + sending.uByte4ToBuf(ourModeDataMap.size()); + std::multimap::iterator it; + for (it = ourModeDataMap.begin(); it != ourModeDataMap.end(); it++) + { + sending.strToBuf((*it).first.c_str()); + sending.strToBuf((*it).second.c_str()); + } + ourModeDataMapMutex.unlock(); + client->sendPacketTcp(&sending); +} + +/** + This will get the info about the current active mode +**/ +AREXPORT void ArServerMode::getModeInfo(ArServerClient *client, + ArNetPacket *packet) +{ + ArNetPacket sending; + buildModeInfoPacket(&sending); + client->sendPacketTcp(&sending); +} + +AREXPORT void ArServerMode::buildModeInfoPacket(ArNetPacket *sending) +{ + if (ourActiveMode != NULL) + { + sending->strToBuf(ourActiveMode->getName()); + if (ourActiveModeLocked) + sending->uByteToBuf(1); + else + sending->uByteToBuf(0); + if (ourActiveModeWillUnlockIfRequested) + sending->uByteToBuf(1); + else + sending->uByteToBuf(0); + } + else + { + sending->strToBuf(""); + sending->uByteToBuf(0); + sending->uByteToBuf(0); + } + return; +} + +AREXPORT void ArServerMode::checkBroadcastModeInfoPacket(void) +{ + if (ourActiveMode != ourBroadcastActiveMode || + ourActiveModeLocked != ourBroadcastActiveModeLocked || + ourActiveModeWillUnlockIfRequested != + ourBroadcastActiveModeWillUnlockIfRequested) + { + ArNetPacket sending; + buildModeInfoPacket(&sending); + myServer->broadcastPacketTcp(&sending, "getModeInfo"); + } + + ourBroadcastActiveMode = ourActiveMode; + ourBroadcastActiveModeLocked = ourActiveModeLocked; + ourBroadcastActiveModeWillUnlockIfRequested = ourActiveModeWillUnlockIfRequested; +} + +AREXPORT ArServerMode* ArServerMode::getActiveMode(void) +{ + return ourActiveMode; +} + +AREXPORT ArServerMode* ArServerMode::getLastActiveMode() +{ + return ourLastActiveMode; +} + +AREXPORT ArServerModeIdle* ArServerMode::getIdleMode(void) { return ourIdleMode; } + +AREXPORT std::list *ArServerMode::getRequestedActivateModes(void) +{ + return &ourRequestedActivateModes; +} + +AREXPORT void ArServerMode::getModeBusy(ArServerClient *client, + ArNetPacket *packet) +{ + ArNetPacket sending; + sending.byteToBuf(ourIsBusy); + client->sendPacketTcp(&sending); +} + + + diff --git a/Legacy/Aria/ArNetworking/src/ArServerModeDrive.cpp b/Legacy/Aria/ArNetworking/src/ArServerModeDrive.cpp new file mode 100644 index 0000000..06de5df --- /dev/null +++ b/Legacy/Aria/ArNetworking/src/ArServerModeDrive.cpp @@ -0,0 +1,244 @@ +#include "Aria.h" +#include "ArExport.h" +#include "ArServerModeDrive.h" + +AREXPORT ArServerModeDrive::ArServerModeDrive(ArServerBase *server, + ArRobot *robot, + bool takeControlOnJoystick) : + ArServerMode(robot, server, "drive"), + myDriveGroup(robot), + myServerDriveJoystickCB(this, &ArServerModeDrive::serverDriveJoystick), + myJoyUserTaskCB(this, &ArServerModeDrive::joyUserTask), + myServerSafeDrivingEnableCB(this, + &ArServerModeDrive::serverSafeDrivingEnable), + myServerSafeDrivingDisableCB(this, + &ArServerModeDrive::serverSafeDrivingDisable) +{ + myHandlerCommands = NULL; + myTakeControlOnJoystick = takeControlOnJoystick; + myDriveSafely = true; + myJoydriveAction.setStopIfNoButtonPressed(false); + myDriveGroup.addAction(&myJoydriveAction, 75); + myDriveGroup.addAction(&myStopAction, 60); + myInputAction = myDriveGroup.getActionInput(); + setThrottleParams(200, 2000); + myExtraUnsafeAction = NULL; + if (myServer != NULL) + { + addModeData("driveJoystick", + "drives the robot as with a joystick", + &myServerDriveJoystickCB, + "byte2: vel, byte2: rotVel", + "none", "Movement", "RETURN_NONE"); + } + if ((myJoyHandler = Aria::getJoyHandler()) == NULL) + { + myJoyHandler = new ArJoyHandler; + myJoyHandler->init(); + Aria::setJoyHandler(myJoyHandler); + } + myRobot->addUserTask("driveJoyUserTask", 75, &myJoyUserTaskCB); +} + +AREXPORT ArServerModeDrive::~ArServerModeDrive() +{ + +} + +AREXPORT void ArServerModeDrive::activate(void) +{ + driveJoystick(0, 0, true); +} + +AREXPORT void ArServerModeDrive::deactivate(void) +{ + myDriveGroup.deactivate(); + baseDeactivate(); +} + +AREXPORT void ArServerModeDrive::setSafeDriving(bool safe) +{ + // if this is a change then print it + if (safe != myDriveSafely) + { + if (safe) + { + ArLog::log(ArLog::Normal, "Driving safely again"); + } + else + { + ArLog::log(ArLog::Normal, "Driving UNSAFELY"); + } + myNewDriveSafely = true; + } + myDriveSafely = safe; + if (isActive()) + driveJoystick(myVel, myRotVel); +} + +AREXPORT bool ArServerModeDrive::getSafeDriving(void) +{ + return myDriveSafely; +} + +AREXPORT void ArServerModeDrive::serverSafeDrivingEnable(void) +{ + myRobot->lock(); + setSafeDriving(true); + myRobot->unlock(); +} + +AREXPORT void ArServerModeDrive::serverSafeDrivingDisable(void) +{ + myRobot->lock(); + setSafeDriving(false); + myRobot->unlock(); +} + +AREXPORT void ArServerModeDrive::addControlCommands(ArServerHandlerCommands *handlerCommands) +{ + myHandlerCommands = handlerCommands; + myHandlerCommands->addCommand( + "safeDrivingEnable", + "Enables safe driving, which will attempt to prevent collisions (default)", + &myServerSafeDrivingEnableCB, "UnsafeMovement"); + myHandlerCommands->addCommand( + "safeDrivingDisable", + "Disables safe driving, this is UNSAFE and will let you drive your robot into things or down stairs, use at your own risk", + &myServerSafeDrivingDisableCB, "UnsafeMovement"); +} + +AREXPORT void ArServerModeDrive::setThrottleParams(int lowSpeed, int highSpeed) +{ + myJoydriveAction.setThrottleParams(lowSpeed, highSpeed); +} + + +/** + * @param vel Forward velocity + * @param rotVel Rotational velocity + * @param isActivating a bool set to true only if this method is called from the activate() + * method, otherwise false +**/ +AREXPORT void ArServerModeDrive::driveJoystick(double vel, double rotVel, bool isActivating) +{ + bool wasActive; + wasActive = isActive(); + + myVel = vel; + myRotVel = rotVel; + + // KMC: Changed the following test to include isActivating. + // if (!wasActive && !baseActivate()) + // return; + + // The baseActivate() method should only be called in the context of the activate() + // method. + if (isActivating && !wasActive) { + if (!baseActivate()) { + return; + } + } // end if activating and wasn't previously active + + + // This is to handle the case where ratioDrive is called outside the + // activate() method, and the activation was not successful. + if (!isActive()) { + return; + } + + if (!wasActive || myNewDriveSafely) + { + myRobot->clearDirectMotion(); + if (myDriveSafely) + { + myDriveGroup.activateExclusive(); + myMode = "Drive"; + ArLog::log(ArLog::Verbose, "Driving safely"); + } + else + { + myRobot->deactivateActions(); + myJoydriveAction.activate(); + myInputAction->activate(); + if (myExtraUnsafeAction != NULL) + myExtraUnsafeAction->activate(); + myMode = "UNSAFE Drive"; + ArLog::log(ArLog::Verbose, "Driving unsafely"); + } + } + myNewDriveSafely = false; + + myVel = vel; + myRotVel = rotVel; + + myDriveGroup.setVel(vel); + myDriveGroup.setRotVel(rotVel); + + setActivityTimeToNow(); +} + +AREXPORT void ArServerModeDrive::serverDriveJoystick(ArServerClient *client, + ArNetPacket *packet) +{ + double vel; + double rotVel; + + vel = packet->bufToByte2(); + rotVel = packet->bufToByte2(); + myRobot->lock(); + + // Activate if necessary. Note that this is done before the ratioDrive + // call because we want the new ratio values to be applied after the + // default ones. + if (!isActive()) { + activate(); + } + driveJoystick(vel, rotVel); + myRobot->unlock(); +} + +AREXPORT void ArServerModeDrive::joyUserTask(void) +{ + // if we're not active but we should be + if (myTakeControlOnJoystick && !isActive() && + myJoyHandler->haveJoystick() && myJoyHandler->getButton(1)) + { + if (ArServerMode::getActiveMode() != NULL) + ArLog::log(ArLog::Normal, + "ArServerModeDrive: Activating instead of %s because of local joystick", ArServerMode::getActiveMode()->getName()); + else + ArLog::log(ArLog::Normal, + "ArServerModeDrive: Activating because of local joystick"); + activate(); + } +} + +AREXPORT void ArServerModeDrive::userTask(void) +{ + // Sets the robot so that we always thing we're trying to move in + // this mode + myRobot->forceTryingToMove(); + + if (myJoyHandler->haveJoystick() && myJoyHandler->getButton(1)) + setActivityTimeToNow(); + if (!myStatusSetThisCycle) + { + if (myRobot->isLeftMotorStalled() || myRobot->isRightMotorStalled()) + myStatus = "Stalled"; + // this works because if the motors stalled above caught it, if + // not and more values it means a stall + else if (myRobot->getStallValue()) + myStatus = "Bumped"; + else if (ArMath::fabs(myRobot->getVel()) < 2 && + ArMath::fabs(myRobot->getRotVel()) < 2) + myStatus = "Stopped"; + else + myStatus = "Driving"; + } + myStatusSetThisCycle = false; +} + + + + diff --git a/Legacy/Aria/ArNetworking/src/ArServerModeIdle.cpp b/Legacy/Aria/ArNetworking/src/ArServerModeIdle.cpp new file mode 100644 index 0000000..3aa0029 --- /dev/null +++ b/Legacy/Aria/ArNetworking/src/ArServerModeIdle.cpp @@ -0,0 +1,163 @@ +#include "Aria.h" +#include "ArExport.h" +#include "ArServerModeIdle.h" + +AREXPORT ArServerModeIdle::ArServerModeIdle(ArServerBase *server, + ArRobot *robot) : + ArServerMode(robot, server, "idle"), + myStopGroup(robot) +{ + myStatus = "Idle processing"; + myMode = "Idle"; + + myUseLocationDependentDevices = true; + + myModeInterrupted = NULL; + + myLimiterForward = new ArActionDeceleratingLimiter( + "DeceleratingLimiterForward"); + myStopGroup.addAction(myLimiterForward, 150); + + myLimiterBackward = new ArActionDeceleratingLimiter( + "DeceleratingLimiterBackward", + ArActionDeceleratingLimiter::BACKWARDS); + myStopGroup.addAction(myLimiterBackward, 149); + + myLimiterLateralLeft = NULL; + if (myRobot->hasLatVel()) + { + myLimiterLateralLeft = new ArActionDeceleratingLimiter( + "DeceleratingLimiterLateralLeft", + ArActionDeceleratingLimiter::LATERAL_LEFT); + myStopGroup.addAction(myLimiterLateralLeft, 148); + } + + myLimiterLateralRight = NULL; + if (myRobot->hasLatVel()) + { + myLimiterLateralRight = new ArActionDeceleratingLimiter( + "DeceleratingLimiterLateralRight", + ArActionDeceleratingLimiter::LATERAL_RIGHT); + myStopGroup.addAction(myLimiterLateralRight, 147); + } + + + +} + +AREXPORT ArServerModeIdle::~ArServerModeIdle() +{ + +} + +AREXPORT void ArServerModeIdle::activate(void) +{ + if (isActive()) + return; + + if (!baseActivate()) + { + /* + ArLog::log(ArLog::Normal, + "IDLE: Clearing mode interrupted since could not activate..."); + */ + myModeInterrupted = NULL; + return; + } + + //ArLog::log(ArLog::Normal, "IDLE... um... %p", myModeInterrupted); + + myRobot->stop(); + myRobot->clearDirectMotion(); + myStopGroup.activateExclusive(); + setActivityTimeToNow(); + ArLog::log(ArLog::Normal, "Idle processing mode activated"); +} + +AREXPORT void ArServerModeIdle::deactivate(void) +{ + ArLog::log(ArLog::Normal, "Idle processing mode deactivating"); + myStopGroup.deactivate(); + baseDeactivate(); +} + +AREXPORT void ArServerModeIdle::userTask(void) +{ + if (fabs(myRobot->getVel()) > 2 || fabs(myRobot->getRotVel()) > 2 || + (myRobot->hasLatVel() && fabs(myRobot->getLatVel()) > 2)) + { + myStatus = "Stopping"; + setActivityTimeToNow(); + } + else + { + myStatus = "Idle processing"; + } + + //ArLog::log(ArLog::Normal, "Idle mode called"); + if (!myServer->idleProcessingPending()) + { + //ArLog::log(ArLog::Normal, "Idle mode done"); + deactivate(); + } +} + +AREXPORT void ArServerModeIdle::addToConfig(ArConfig *config, + const char *section) +{ + myLimiterForward->addToConfig(config, section, "Forward"); + myLimiterBackward->addToConfig(config, section, "Backward"); + if (myLimiterLateralLeft != NULL) + myLimiterLateralLeft->addToConfig(config, section, "Lateral"); + if (myLimiterLateralRight != NULL) + myLimiterLateralRight->addToConfig(config, section, "Lateral"); +} + +AREXPORT void ArServerModeIdle::setUseLocationDependentDevices( + bool useLocationDependentDevices, bool internal) +{ + if (!internal) + myRobot->lock(); + // if this is a change then print it + if (useLocationDependentDevices != myUseLocationDependentDevices) + { + myUseLocationDependentDevices = useLocationDependentDevices; + myLimiterForward->setUseLocationDependentDevices( + myUseLocationDependentDevices); + myLimiterBackward->setUseLocationDependentDevices( + myUseLocationDependentDevices); + if (myLimiterLateralLeft != NULL) + myLimiterLateralLeft->setUseLocationDependentDevices( + myUseLocationDependentDevices); + if (myLimiterLateralRight != NULL) + myLimiterLateralRight->setUseLocationDependentDevices( + myUseLocationDependentDevices); + } + if (!internal) + myRobot->unlock(); +} + +AREXPORT bool ArServerModeIdle::getUseLocationDependentDevices(void) +{ + return myUseLocationDependentDevices; +} + + +AREXPORT void ArServerModeIdle::setModeInterrupted( + ArServerMode *modeInterrupted) +{ + /* + if (modeInterrupted != NULL) + ArLog::log(ArLog::Normal, "IDLE: Setting mode interrupted to %s", + modeInterrupted->getName()); + else + ArLog::log(ArLog::Normal, "IDLE: Setting mode interrupted to NULL"); + */ + myModeInterrupted = modeInterrupted; +} + +AREXPORT ArServerMode *ArServerModeIdle::getModeInterrupted(void) +{ + return myModeInterrupted; +} + diff --git a/Legacy/Aria/ArNetworking/src/ArServerModeRatioDrive.cpp b/Legacy/Aria/ArNetworking/src/ArServerModeRatioDrive.cpp new file mode 100644 index 0000000..f531259 --- /dev/null +++ b/Legacy/Aria/ArNetworking/src/ArServerModeRatioDrive.cpp @@ -0,0 +1,543 @@ +#include "Aria.h" +#include "ArExport.h" +#include "ArServerModeRatioDrive.h" +#include "ArServerHandlerCommands.h" + +AREXPORT ArServerModeRatioDrive::ArServerModeRatioDrive( + ArServerBase *server, ArRobot *robot, bool takeControlOnJoystick, + bool useComputerJoystick, bool useRobotJoystick, + bool useServerCommands, const char *name, + bool robotJoystickOverridesLocks) : + ArServerMode(robot, server, name), + myRatioDriveGroup(robot), + myJoyUserTaskCB(this, &ArServerModeRatioDrive::joyUserTask), + myServerSetSafeDriveCB(this, + &ArServerModeRatioDrive::serverSetSafeDrive), + myServerGetSafeDriveCB(this, + &ArServerModeRatioDrive::serverGetSafeDrive), + myServerRatioDriveCB(this, &ArServerModeRatioDrive::serverRatioDrive), + myRatioFireCB(this, &ArServerModeRatioDrive::ratioFireCallback), + myServerSafeDrivingEnableCB(this, + &ArServerModeRatioDrive::serverSafeDrivingEnable), + myServerSafeDrivingDisableCB(this, + &ArServerModeRatioDrive::serverSafeDrivingDisable) +{ + myHandlerCommands = NULL; + myDriveSafely = true; + myTakeControlOnJoystick = takeControlOnJoystick; + myUseComputerJoystick = useComputerJoystick; + myUseRobotJoystick = useRobotJoystick; + myUseServerCommands = useServerCommands; + myUseLocationDependentDevices = true; + myRobotJoystickOverridesLock = robotJoystickOverridesLocks; + myTimeout = 2; + myGotServerCommand = true; + + myLastTimedOut = false; + + // SEEKUR + mySentRecenter = false; + + // add the actions, put the ratio input on top, then have the + // limiters since the ratio doesn't touch decel except lightly + // whereas the limiter will touch it strongly + + myRatioAction = new ArActionRatioInput; + myRatioDriveGroup.addAction(myRatioAction, 50); + + myLimiterForward = new ArActionDeceleratingLimiter( + "DeceleratingLimiterForward", ArActionDeceleratingLimiter::FORWARDS); + myRatioDriveGroup.addAction(myLimiterForward, 40); + + myLimiterBackward = new ArActionDeceleratingLimiter( + "DeceleratingLimiterBackward", + ArActionDeceleratingLimiter::BACKWARDS); + myRatioDriveGroup.addAction(myLimiterBackward, 39); + + myLimiterLateralLeft = NULL; + myLimiterLateralRight = NULL; + if (myRobot->hasLatVel()) + { + myLimiterLateralLeft = new ArActionDeceleratingLimiter( + "DeceleratingLimiterLateralLeft", + ArActionDeceleratingLimiter::LATERAL_LEFT); + myRatioDriveGroup.addAction(myLimiterLateralLeft, 38); + myLimiterLateralRight = new ArActionDeceleratingLimiter( + "DeceleratingLimiterLateralRight", + ArActionDeceleratingLimiter::LATERAL_RIGHT); + myRatioDriveGroup.addAction(myLimiterLateralRight, 37); + } + + myMovementParameters = new ArActionMovementParameters("TeleopMovementParameters", false); + myRatioDriveGroup.addAction(myMovementParameters, 1); + + myRatioFireCB.setName("ArServerModeRatioDrive"); + myRatioAction->addFireCallback(30, &myRatioFireCB); + + myLastRobotSafeDrive = true; + + if (myServer != NULL && myUseServerCommands) + { + addModeData("ratioDrive", "drives the robot as with a joystick", + &myServerRatioDriveCB, + "double: transRatio; double: rotRatio; double: throttleRatio ", + "none", "Movement", "RETURN_NONE"); + myServer->addData("setSafeDrive", + "sets whether we drive the robot safely or not", + &myServerSetSafeDriveCB, + "byte: 1 == drive safely, 0 == drive unsafely", + "none", "UnsafeMovement", "RETURN_NONE"); + myServer->addData("getSafeDrive", + "gets whether we drive the robot safely or not", + &myServerGetSafeDriveCB, + "none", + "byte: 1 == driving safely, 0 == driving unsafely", + "Movement", "RETURN_SINGLE"); + } + + if (myUseComputerJoystick) + { + myJoydrive = new ArRatioInputJoydrive(robot, myRatioAction); + if ((myJoyHandler = Aria::getJoyHandler()) == NULL) + { + myJoyHandler = new ArJoyHandler; + myJoyHandler->init(); + Aria::setJoyHandler(myJoyHandler); + } + } + if (myUseRobotJoystick) + { + myRobotJoydrive = new ArRatioInputRobotJoydrive(robot, myRatioAction); + if ((myRobotJoyHandler = Aria::getRobotJoyHandler()) == NULL) + { + myRobotJoyHandler = new ArRobotJoyHandler(robot); + Aria::setRobotJoyHandler(myRobotJoyHandler); + } + } + if (myUseRobotJoystick || myUseComputerJoystick) + { + std::string taskName = name; + taskName += "::joyUserTask"; + myRobot->addUserTask(taskName.c_str(), 75, &myJoyUserTaskCB); + } + + myPrinting = false; +} + +AREXPORT ArServerModeRatioDrive::~ArServerModeRatioDrive() +{ + +} + +AREXPORT void ArServerModeRatioDrive::addToConfig(ArConfig *config, + const char *section) +{ + config->addParam( + ArConfigArg( + "Timeout", &myTimeout, + "If there are no commands for this period of time, then the robot will stop. 0 Disables. This is a double so you can do like .1 seconds if you want.", 0), + section, ArPriority::ADVANCED); + myRatioAction->addToConfig(config, section); + myLimiterForward->addToConfig(config, section, "Forward"); + myLimiterBackward->addToConfig(config, section, "Backward"); + if (myLimiterLateralLeft != NULL) + myLimiterLateralLeft->addToConfig(config, section, "Lateral"); + if (myLimiterLateralRight != NULL) + myLimiterLateralRight->addToConfig(config, section, "Lateral"); + myMovementParameters->addToConfig(config, section, "Teleop"); + +} + +AREXPORT void ArServerModeRatioDrive::activate(void) +{ + //if (!baseActivate()) { + // return; + //} + ratioDrive(0, 0, 100, true); +} + +AREXPORT void ArServerModeRatioDrive::deactivate(void) +{ + myRatioDriveGroup.deactivate(); + baseDeactivate(); +} + +AREXPORT void ArServerModeRatioDrive::setSafeDriving(bool safe, bool internal) +{ + if (!internal) + myRobot->lock(); + // if this is a change then print it + if (safe != myDriveSafely) + { + if (safe) + { + ArLog::log(ArLog::Normal, "%s: Driving safely again", myName.c_str()); + } + else + { + ArLog::log(ArLog::Normal, "%s: Driving UNSAFELY", myName.c_str()); + } + myNewDriveSafely = true; + } + myDriveSafely = safe; + // ratioDrive is only called if this mode is already active (and now just sends 0s) + if (isActive()) + ratioDrive(0, 0, 0, false, 0); + /* + ratioDrive(myRatioAction->getTransRatio(), + myRatioAction->getRotRatio(), + myRatioAction->getThrottleRatio()); + */ + if (!internal) + myRobot->unlock(); +} + +AREXPORT bool ArServerModeRatioDrive::getSafeDriving(void) +{ + return myDriveSafely; +} + +AREXPORT void ArServerModeRatioDrive::serverSafeDrivingEnable(void) +{ + setSafeDriving(true); +} + +AREXPORT void ArServerModeRatioDrive::serverSafeDrivingDisable(void) +{ + setSafeDriving(false); +} + +AREXPORT void ArServerModeRatioDrive::addControlCommands(ArServerHandlerCommands *handlerCommands) +{ + if (!myUseServerCommands) + { + ArLog::log(ArLog::Normal, + "ArServerModeRatioDrive::addControlCommands: Tried to add control commands to a ratio drive not using the server"); + return; + } + myHandlerCommands = handlerCommands; + myHandlerCommands->addCommand( + "safeRatioDrivingEnable", + "Enables safe driving with ratioDrive, which will attempt to prevent collisions (default)", + &myServerSafeDrivingEnableCB, "UnsafeMovement"); + myHandlerCommands->addCommand( + "safeRatioDrivingDisable", + "Disables safe driving with ratioDrive, this is UNSAFE and will let you drive your robot into things or down stairs, use at your own risk", + &myServerSafeDrivingDisableCB, "UnsafeMovement"); +} + + +/** + * @param isActivating a bool set to true only if this method is called from the activate() + * method, otherwise false + * @param transRatio Amount of forward velocity to request + * @param rotRatio Amount of rotational velocity to request + * @param throttleRatio Amount of speed to request + * @param latRatio amount of lateral velocity to request (if robot supports it) +**/ +AREXPORT void ArServerModeRatioDrive::ratioDrive( + double transRatio, double rotRatio, double throttleRatio, + bool isActivating, double latRatio) +{ + bool wasActive; + wasActive = isActive(); + + myTransRatio = transRatio; + myRotRatio = rotRatio; + myThrottleRatio = throttleRatio; + myLatRatio = latRatio; + + // KMC: Changed the following test to include isActivating. + // if (!wasActive && !baseActivate()) + // return; + + // The baseActivate() method should only be called in the context of the activate() + // method. + if (isActivating && !wasActive) { + if (!baseActivate()) { + return; + } + } // end if activating and wasn't previously active + + // This is to handle the case where ratioDrive is called outside the + // activate() method, and the activation was not successful. + if (!isActive()) { + return; + } + + if (!wasActive || myNewDriveSafely) + { + myRobot->clearDirectMotion(); + if (myDriveSafely) + { + myRatioDriveGroup.activateExclusive(); + myMode = "Drive"; + ArLog::log(ArLog::Normal, "%s: Driving safely", myName.c_str()); + } + else + { + myRobot->deactivateActions(); + myRatioAction->activate(); + myMode = "UNSAFE Drive"; + ArLog::log(ArLog::Normal, "%s: Driving unsafely", myName.c_str()); + } + if (myDriveSafely) + mySafeDrivingCallbacks.invoke(); + else + myUnsafeDrivingCallbacks.invoke(); + } + myNewDriveSafely = false; + + // MPL why is this here twice? + myTransRatio = transRatio; + myRotRatio = rotRatio; + myThrottleRatio = throttleRatio; + myLatRatio = latRatio; + + setActivityTimeToNow(); + myLastCommand.setToNow(); + + + // SEEKUR + mySentRecenter = false; + + if (myPrinting) + ArLog::log(ArLog::Normal, "%s: cmd %.0f %.0f %.0f %.0f", + getName(), transRatio, rotRatio, throttleRatio, latRatio); + if (myTransRatio < -0.1) + myDrivingBackwardsCallbacks.invoke(); + //myRatioAction.setRatios(transRatio, rotRatio, throttleRatio); +} + +AREXPORT void ArServerModeRatioDrive::serverRatioDrive(ArServerClient *client, + ArNetPacket *packet) +{ + double transRatio = packet->bufToDouble(); + double rotRatio = packet->bufToDouble(); + double throttleRatio = packet->bufToDouble(); + double lateralRatio = packet->bufToDouble(); + + myGotServerCommand = true; + + if (!myDriveSafely && !client->hasGroupAccess("UnsafeMovement")) + serverSafeDrivingEnable(); + myRobot->lock(); + + // Activate if necessary. Note that this is done before the ratioDrive + // call because we want the new ratio values to be applied after the + // default ones. + if (!isActive()) { + activate(); + } + + if (myPrinting) + ArLog::log(ArLog::Normal, + "%s: serverCmd (%s) trans %.0f rot %.0f lat %.0f ratio %.0f", + + getName(), client->getIPString(), + transRatio, rotRatio, lateralRatio, throttleRatio); + + ratioDrive(transRatio, rotRatio, throttleRatio, false, lateralRatio); + myRobot->unlock(); +} + +AREXPORT void ArServerModeRatioDrive::serverSetSafeDrive( + ArServerClient *client, ArNetPacket *packet) +{ + if (packet->bufToUByte() == 0) + setSafeDriving(false); + else + setSafeDriving(true); +} + +AREXPORT void ArServerModeRatioDrive::serverGetSafeDrive( + ArServerClient *client, ArNetPacket *packet) +{ + ArNetPacket sendPacket; + if (getSafeDriving()) + sendPacket.uByteToBuf(1); + else + sendPacket.uByteToBuf(0); + + client->sendPacketTcp(&sendPacket); +} + + +AREXPORT void ArServerModeRatioDrive::joyUserTask(void) +{ + // if we're not active but we should be + if (myTakeControlOnJoystick && !isActive() && + ((myUseComputerJoystick && myJoyHandler->haveJoystick() && + myJoyHandler->getButton(1)) || + (myUseRobotJoystick && myRobotJoyHandler->gotData() && + myRobotJoyHandler->getButton1()))) + { + if (ArServerMode::getActiveMode() != NULL) + ArLog::log(ArLog::Normal, + "%s: Activating instead of %s because of local joystick", + myName.c_str(), + ArServerMode::getActiveMode()->getName()); + else + ArLog::log(ArLog::Normal, + "%s: Activating because of local joystick", + myName.c_str()); + // if we're locked and are overriding that lock for the robot + // joystick and it was the robot joystick that caused it to happen + if (myUseRobotJoystick && myRobotJoyHandler->gotData() && + myRobotJoyHandler->getButton1() && myRobotJoystickOverridesLock && + ArServerMode::ourActiveModeLocked) + { + ArLog::log(ArLog::Terse, "Robot joystick is overriding locked mode %s", + ourActiveMode->getName()); + ourActiveMode->forceUnlock(); + myRobot->enableMotors(); + } + activate(); + } + bool unsafeRobotDrive; + if (myUseRobotJoystick && myRobotJoyHandler->gotData() && + ((unsafeRobotDrive = + (bool)(myRobot->getFaultFlags() & ArUtil::BIT15)) != + !myLastRobotSafeDrive)) + { + myLastRobotSafeDrive = !unsafeRobotDrive; + setSafeDriving(myLastRobotSafeDrive, true); + } +} + +AREXPORT void ArServerModeRatioDrive::userTask(void) +{ + // Sets the robot so that we always think we're trying to move in + // this mode + myRobot->forceTryingToMove(); + + bool moving = (fabs(myRobot->getVel()) > 1 || + fabs(myRobot->getRotVel()) > 1 || + fabs(myRobot->getLatVel()) > 1); + + bool wantToMove; + if ((myTransRatio < .1 && myRotRatio < .1 && myLatRatio < .1) || + myThrottleRatio < .1) + wantToMove = false; + else + wantToMove = true; + + // if the joystick is pushed then set that we're active, server + // commands'll go into ratioDrive and set it there too + if ((myUseComputerJoystick && myJoyHandler->haveJoystick() && + myJoyHandler->getButton(1)) || + (myUseRobotJoystick && myRobotJoyHandler->gotData() && + myRobotJoyHandler->getButton1()) || + (myUseServerCommands && myGotServerCommand) || + moving) + { + setActivityTimeToNow(); + } + + myGotServerCommand = false; + + bool timedOut = false; + // if we want to move, and there is a timeout, and the activity time is + // greater than the timeout, then stop the robot + if (wantToMove && + myTimeout > .0000001 && + myLastCommand.mSecSince()/1000.0 >= myTimeout) + + { + if (!myLastTimedOut) + { + ArLog::log(ArLog::Normal, "Stopping the robot since teleop timed out"); + myRobot->stop(); + myRobot->clearDirectMotion(); + ArTime lastCommand = myLastCommand; + ratioDrive(0, 0, 0, false, 0); + myLastCommand = lastCommand; + } + timedOut = true; + } + + myLastTimedOut = timedOut; + + // SEEKUR (needed for prototype versions) + /* + if (myRobot->hasLatVel() && !mySentRecenter && + getActivityTime().secSince() >= 10) + { + mySentRecenter = true; + myRobot->com(120); + } + */ + + if (!myStatusSetThisCycle) + { + if (myRobot->isLeftMotorStalled() || myRobot->isRightMotorStalled()) + myStatus = "Stalled"; + // this works because if the motors stalled above caught it, if + // not and more values it means a stall + else if (myRobot->getStallValue()) + myStatus = "Bumped"; + else if (ArMath::fabs(myRobot->getVel()) < 2 && + ArMath::fabs(myRobot->getRotVel()) < 1 && + (!myRobot->hasLatVel() || ArMath::fabs(myRobot->getLatVel()) < 2)) + myStatus = "Stopped"; + else + myStatus = "Driving"; + } + + myStatusSetThisCycle = false; +} // end method userTask + + +AREXPORT void ArServerModeRatioDrive::ratioFireCallback(void) +{ + if (myPrinting) + ArLog::log(ArLog::Normal, "ArServerModeRatioDrive: TransRatio=%.0f RotRatio=%.0f ThrottleRatio=%.0f LatRatio=%.0f", + myTransRatio, myRotRatio, myThrottleRatio, myLatRatio); + myRatioAction->setRatios(myTransRatio, myRotRatio, myThrottleRatio, + myLatRatio); +} + +AREXPORT void ArServerModeRatioDrive::setUseLocationDependentDevices( + bool useLocationDependentDevices, bool internal) +{ + if (!internal) + myRobot->lock(); + // if this is a change then print it + if (useLocationDependentDevices != myUseLocationDependentDevices) + { + if (useLocationDependentDevices) + { + ArLog::log(ArLog::Normal, "%s: Using location dependent range devices", + myName.c_str()); + } + else + { + ArLog::log(ArLog::Normal, + "%s: Not using location dependent range devices", + myName.c_str()); + } + myUseLocationDependentDevices = useLocationDependentDevices; + myLimiterForward->setUseLocationDependentDevices( + myUseLocationDependentDevices); + myLimiterBackward->setUseLocationDependentDevices( + myUseLocationDependentDevices); + if (myLimiterLateralLeft != NULL) + myLimiterLateralLeft->setUseLocationDependentDevices( + myUseLocationDependentDevices); + if (myLimiterLateralRight != NULL) + myLimiterLateralRight->setUseLocationDependentDevices( + myUseLocationDependentDevices); + + } + if (!internal) + myRobot->unlock(); +} + +AREXPORT bool ArServerModeRatioDrive::getUseLocationDependentDevices(void) +{ + return myUseLocationDependentDevices; +} + + + + diff --git a/Legacy/Aria/ArNetworking/src/ArServerModeStop.cpp b/Legacy/Aria/ArNetworking/src/ArServerModeStop.cpp new file mode 100644 index 0000000..fcd1be4 --- /dev/null +++ b/Legacy/Aria/ArNetworking/src/ArServerModeStop.cpp @@ -0,0 +1,139 @@ +#include "Aria.h" +#include "ArExport.h" +#include "ArServerModeStop.h" + +AREXPORT ArServerModeStop::ArServerModeStop(ArServerBase *server, + ArRobot *robot, + bool defunct) : + ArServerMode(robot, server, "stop"), + myStopGroup(robot), + myNetStopCB(this, &ArServerModeStop::netStop) +{ + myMode = "Stop"; + if (myServer != NULL) + { + addModeData("stop", "stops the robot", &myNetStopCB, + "none", "none", "Stop", "RETURN_NONE"); + } + + myUseLocationDependentDevices = true; + + myLimiterForward = new ArActionDeceleratingLimiter( + "DeceleratingLimiterForward"); + myStopGroup.addAction(myLimiterForward, 150); + + myLimiterBackward = new ArActionDeceleratingLimiter( + "DeceleratingLimiterBackward", + ArActionDeceleratingLimiter::BACKWARDS); + myStopGroup.addAction(myLimiterBackward, 149); + + myLimiterLateralLeft = NULL; + if (myRobot->hasLatVel()) + { + myLimiterLateralLeft = new ArActionDeceleratingLimiter( + "DeceleratingLimiterLateralLeft", + ArActionDeceleratingLimiter::LATERAL_LEFT); + myStopGroup.addAction(myLimiterLateralLeft, 148); + } + + myLimiterLateralRight = NULL; + if (myRobot->hasLatVel()) + { + myLimiterLateralRight = new ArActionDeceleratingLimiter( + "DeceleratingLimiterLateralRight", + ArActionDeceleratingLimiter::LATERAL_RIGHT); + myStopGroup.addAction(myLimiterLateralRight, 147); + } + +} + +AREXPORT ArServerModeStop::~ArServerModeStop() +{ + +} + +AREXPORT void ArServerModeStop::activate(void) +{ + if (isActive() || !baseActivate()) + return; + setActivityTimeToNow(); + myRobot->stop(); + myRobot->clearDirectMotion(); + myStopGroup.activateExclusive(); + myStatus = "Stopping"; +} + +AREXPORT void ArServerModeStop::deactivate(void) +{ + myStopGroup.deactivate(); + baseDeactivate(); +} + +AREXPORT void ArServerModeStop::stop(void) +{ + activate(); +} + +AREXPORT void ArServerModeStop::netStop(ArServerClient *client, + ArNetPacket *packet) +{ + setActivityTimeToNow(); + myRobot->lock(); + ArLog::log(ArLog::Verbose, "Stopping"); + stop(); + myRobot->unlock(); +} + +AREXPORT void ArServerModeStop::userTask(void) +{ + if (myRobot->getVel() < 2 && myRobot->getRotVel() < 2) + { + myStatus = "Stopped"; + } + else + { + setActivityTimeToNow(); + myStatus = "Stopping"; + } +} + +AREXPORT void ArServerModeStop::addToConfig(ArConfig *config, + const char *section) +{ + myLimiterForward->addToConfig(config, section, "Forward"); + myLimiterBackward->addToConfig(config, section, "Backward"); + if (myLimiterLateralLeft != NULL) + myLimiterLateralLeft->addToConfig(config, section, "Lateral"); + if (myLimiterLateralRight != NULL) + myLimiterLateralRight->addToConfig(config, section, "Lateral"); +} + +AREXPORT void ArServerModeStop::setUseLocationDependentDevices( + bool useLocationDependentDevices, bool internal) +{ + if (!internal) + myRobot->lock(); + // if this is a change then print it + if (useLocationDependentDevices != myUseLocationDependentDevices) + { + myUseLocationDependentDevices = useLocationDependentDevices; + myLimiterForward->setUseLocationDependentDevices( + myUseLocationDependentDevices); + myLimiterBackward->setUseLocationDependentDevices( + myUseLocationDependentDevices); + if (myLimiterLateralLeft != NULL) + myLimiterLateralLeft->setUseLocationDependentDevices( + myUseLocationDependentDevices); + if (myLimiterLateralRight != NULL) + myLimiterLateralRight->setUseLocationDependentDevices( + myUseLocationDependentDevices); + } + if (!internal) + myRobot->unlock(); +} + +AREXPORT bool ArServerModeStop::getUseLocationDependentDevices(void) +{ + return myUseLocationDependentDevices; +} + diff --git a/Legacy/Aria/ArNetworking/src/ArServerModeWander.cpp b/Legacy/Aria/ArNetworking/src/ArServerModeWander.cpp new file mode 100644 index 0000000..58a565d --- /dev/null +++ b/Legacy/Aria/ArNetworking/src/ArServerModeWander.cpp @@ -0,0 +1,64 @@ +#include "Aria.h" +#include "ArExport.h" +#include "ArServerModeWander.h" + +AREXPORT ArServerModeWander::ArServerModeWander(ArServerBase *server, ArRobot *robot) : + ArServerMode(robot, server, "wander"), + myWanderGroup(robot), + myNetWanderCB(this, &ArServerModeWander::netWander) +{ + myMode = "Wander"; + if (myServer != NULL) + { + addModeData("wander", "makes the robot wander", &myNetWanderCB, + "none", "none", "Movement", "RETURN_NONE"); + } +} + +AREXPORT ArServerModeWander::~ArServerModeWander() +{ + +} + +AREXPORT void ArServerModeWander::activate(void) +{ + if (!baseActivate()) + return; + + setActivityTimeToNow(); + myRobot->clearDirectMotion(); + myWanderGroup.activateExclusive(); + myStatus = "Wandering"; +} + +AREXPORT void ArServerModeWander::deactivate(void) +{ + myWanderGroup.deactivate(); + baseDeactivate(); +} + +AREXPORT void ArServerModeWander::wander(void) +{ + activate(); +} + +AREXPORT void ArServerModeWander::netWander(ArServerClient *client, + ArNetPacket *packet) +{ + myRobot->lock(); + ArLog::log(ArLog::Verbose, "Wandering"); + wander(); + myRobot->unlock(); + setActivityTimeToNow(); +} + +AREXPORT void ArServerModeWander::userTask(void) +{ + setActivityTimeToNow(); + + // Sets the robot so that we always thing we're trying to move in + // this mode + myRobot->forceTryingToMove(); + + //myStatus = "Wandering"; +} diff --git a/Legacy/Aria/ArNetworking/src/ArServerSimpleCommands.cpp b/Legacy/Aria/ArNetworking/src/ArServerSimpleCommands.cpp new file mode 100644 index 0000000..2a08f41 --- /dev/null +++ b/Legacy/Aria/ArNetworking/src/ArServerSimpleCommands.cpp @@ -0,0 +1,971 @@ +#include "Aria.h" +#include "ArExport.h" +#include "ArServerBase.h" +#include "ArServerSimpleCommands.h" + +AREXPORT ArServerSimpleComUC::ArServerSimpleComUC( + ArServerHandlerCommands *handlerCommands, ArRobot *robot) : + myCommandCB(this, &ArServerSimpleComUC::command), + myMotionCommandCB(this, &ArServerSimpleComUC::motionCommand) +{ + myHandlerCommands = handlerCommands; + myRobot = robot; + if (myHandlerCommands != NULL) + { + myHandlerCommands->addStringCommand("MicroControllerCommand", + "MicroController (uC) command mode has three ways to send commands:\ncom: \ncomInt: \ncom2Bytes: ", &myCommandCB); + myHandlerCommands->addStringCommand("MicroControllerMotionCommand", + "MicroController (uC) motion commands will suspend normal motion commands to the microcontroller and ONLY the motion commands will be in charge. This will last until the server mode is changed or stop is pressed (unless the server mode is locked, ie docking). This has four ways to send commands:\ncom: \ncomInt: \ncom2Bytes: :", &myMotionCommandCB); + } +} + +AREXPORT ArServerSimpleComUC::~ArServerSimpleComUC() +{ +} + + +AREXPORT void ArServerSimpleComUC::command(ArArgumentBuilder *arg) +{ + processCommand(arg, false); +} + +AREXPORT void ArServerSimpleComUC::motionCommand(ArArgumentBuilder *arg) +{ + processCommand(arg, true); +} + +void ArServerSimpleComUC::processCommand(ArArgumentBuilder *arg, + bool motionCommand) +{ + int command; + int int1; + int int2; + + std::string prefix; + + if (!motionCommand) + prefix = "uCCommand: "; + else + prefix = "uCMotionCommand: "; + myRobot->lock(); + if (motionCommand) + myRobot->stopStateReflection(); + if (arg->getFullString() == NULL || arg->getFullString()[0] == '\0' || + arg->getArgc() == 0) + { + if (motionCommand) + { + ArLog::log(ArLog::Terse, "%sReset to normal control.", + prefix.c_str()); + myRobot->stop(); + myRobot->clearDirectMotion(); + } + else + ArLog::log(ArLog::Terse, "%sSyntax error, no arguments.", + prefix.c_str()); + } + else if (arg->getArgc() == 1) + { + command = arg->getArgInt(0); + if (command < 0 || command > 255 || !arg->isArgInt(0)) + { + ArLog::log(ArLog::Terse, + "%sInvalid command, must be an integer between 0 and 255", + prefix.c_str()); + } + else + { + ArLog::log(ArLog::Terse, "%scom(%d)", prefix.c_str(), command); + myRobot->com(command); + } + } + else if (arg->getArgc() == 2) + { + command = arg->getArgInt(0); + int1 = arg->getArgInt(1); + if (command < 0 || command > 255 || !arg->isArgInt(0)) + { + ArLog::log(ArLog::Terse, + "%sInvalid command, must be an integer between 0 and 255", + prefix.c_str()); + } + else if (int1 < -32767 || int1 > 65536 || !arg->isArgInt(1)) + { + ArLog::log(ArLog::Terse, + "%sInvalid integer, must be an integer between -32767 and 65536", + prefix.c_str()); + } + else + { + ArLog::log(ArLog::Terse, "%scomInt(%d, %d)", prefix.c_str(), command, + int1); + myRobot->comInt(command, int1); + } + } + else if (arg->getArgc() == 3) + { + command = arg->getArgInt(0); + int1 = arg->getArgInt(1); + int2 = arg->getArgInt(2); + if (command < 0 || command > 255 || !arg->isArgInt(0)) + { + ArLog::log(ArLog::Terse, + "%sInvalid command, must be between 0 and 255", + prefix.c_str()); + } + else if (int1 < -128 || int1 > 255 || !arg->isArgInt(1)) + { + ArLog::log(ArLog::Terse, + "%sInvalid byte1, must be an integer between -128 and 127, or between 0 and 255", prefix.c_str()); + } + else if (int2 < -128 || int2 > 255 || !arg->isArgInt(2)) + { + ArLog::log(ArLog::Terse, + "%sInvalid byte2, must be an integer between -128 and 127, or between 0 and 255", prefix.c_str()); + } + else + { + ArLog::log(ArLog::Terse, + "%scom2Bytes(%d, %d, %d)", + prefix.c_str(), command, int1, int2); + myRobot->com2Bytes(command, int1, int2); + } + } + else + { + ArLog::log(ArLog::Terse, "%sSyntax error, too many arguments", + prefix.c_str()); + } + myRobot->unlock(); +} + + +AREXPORT ArServerSimpleComMovementLogging::ArServerSimpleComMovementLogging( + ArServerHandlerCommands *handlerCommands, ArRobot *robot, + ArServerHandlerPopup *popupHandler) : + myLogMovementSentEnableCB(this, + &ArServerSimpleComMovementLogging::logMovementSentEnable), + myLogMovementSentDisableCB(this, + &ArServerSimpleComMovementLogging::logMovementSentDisable), + myLogMovementReceivedEnableCB(this, + &ArServerSimpleComMovementLogging::logMovementReceivedEnable), + myLogMovementReceivedDisableCB(this, + &ArServerSimpleComMovementLogging::logMovementReceivedDisable), + myLogVelocitiesReceivedEnableCB(this, + &ArServerSimpleComMovementLogging::logVelocitiesReceivedEnable), + myLogVelocitiesReceivedDisableCB(this, + &ArServerSimpleComMovementLogging::logVelocitiesReceivedDisable), + myPacketsReceivedTrackingEnableCB(this, + &ArServerSimpleComMovementLogging::packetsReceivedTrackingEnable), + myPacketsReceivedTrackingDisableCB(this, + &ArServerSimpleComMovementLogging::packetsReceivedTrackingDisable), + myPacketsSentTrackingEnableCB(this, + &ArServerSimpleComMovementLogging::packetsSentTrackingEnable), + myPacketsSentTrackingDisableCB(this, + &ArServerSimpleComMovementLogging::packetsSentTrackingDisable), + myLogActionsEnableCB(this, + &ArServerSimpleComMovementLogging::logActionsEnable), + myLogActionsDisableCB(this, + &ArServerSimpleComMovementLogging::logActionsDisable), + myLogActionsCB(this, &ArServerSimpleComMovementLogging::logActions), + myPopupMovementParamsCB(this, + &ArServerSimpleComMovementLogging::popupMovementParams), + myResetOdometerCB(this, &ArServerSimpleComMovementLogging::resetOdometer) +{ + myHandlerCommands = handlerCommands; + myRobot = robot; + myPopupHandler = popupHandler; + myHandlerCommands->addCommand( + "LogMovementSentEnable", + "Enables logging of the movement commands sent to the robot", + &myLogMovementSentEnableCB); + myHandlerCommands->addCommand( + "LogMovementSentDisable", + "Disables logging of the movement commands sent to the robot", + &myLogMovementSentDisableCB); + myHandlerCommands->addCommand( + "LogMovementReceivedEnable", + "Enables logging of the movement data received from the robot", + &myLogMovementReceivedEnableCB); + myHandlerCommands->addCommand( + "LogMovementReceivedDisable", + "Disables logging of the movement data received from the robot", + &myLogMovementReceivedDisableCB); + myHandlerCommands->addCommand( + "LogVelocitiesReceivedEnable", + "Enables logging of the velocity data received from the robot", + &myLogVelocitiesReceivedEnableCB); + myHandlerCommands->addCommand( + "LogVelocitiesReceivedDisable", + "Disables logging of the velocity data received from the robot", + &myLogVelocitiesReceivedDisableCB); + myHandlerCommands->addCommand( + "PacketsReceivedTrackingEnable", + "Enables tracking of packets received from the robot", + &myPacketsReceivedTrackingEnableCB); + myHandlerCommands->addCommand( + "PacketsReceivedTrackingDisable", + "Disables tracking of packets received from the robot", + &myPacketsReceivedTrackingDisableCB); + myHandlerCommands->addCommand( + "PacketsSentTrackingEnable", + "Enables tracking of packets sent to the robot", + &myPacketsSentTrackingEnableCB); + myHandlerCommands->addCommand( + "PacketsSentTrackingDisable", + "Disables tracking of packets sent to the robot", + &myPacketsSentTrackingDisableCB); + myHandlerCommands->addCommand( + "LogActionsEnable", + "Enables continual logging of the actions", + &myLogActionsEnableCB); + myHandlerCommands->addCommand( + "LogActionsDisable", + "Disables continual logging of the actions", + &myLogActionsDisableCB); + myHandlerCommands->addCommand( + "LogActions", + "Logs the state of the actions on the robot once", + &myLogActionsCB); + if (myPopupHandler != NULL) + { + myHandlerCommands->addCommand( + "PopupMovementParams", + "Creates a popup with the movement parameters for this robot", + &myPopupMovementParamsCB); + } + myHandlerCommands->addCommand( + "ResetTripOdometer", + "Resets the robot's trip odometer", + &myResetOdometerCB); + +} + +AREXPORT ArServerSimpleComMovementLogging::~ArServerSimpleComMovementLogging() +{ +} + +AREXPORT void ArServerSimpleComMovementLogging::logMovementSentEnable(void) +{ + myRobot->lock(); + myRobot->setLogMovementSent(true); + myRobot->unlock(); +} + +AREXPORT void ArServerSimpleComMovementLogging::logMovementSentDisable(void) +{ + myRobot->lock(); + myRobot->setLogMovementSent(false); + myRobot->unlock(); +} + +AREXPORT void ArServerSimpleComMovementLogging::logMovementReceivedEnable(void) +{ + myRobot->lock(); + myRobot->setLogMovementReceived(true); + myRobot->unlock(); +} + +AREXPORT void ArServerSimpleComMovementLogging::logMovementReceivedDisable(void) +{ + myRobot->lock(); + myRobot->setLogMovementReceived(false); + myRobot->unlock(); +} + +AREXPORT void ArServerSimpleComMovementLogging::logVelocitiesReceivedEnable(void) +{ + myRobot->lock(); + myRobot->setLogVelocitiesReceived(true); + myRobot->unlock(); +} + +AREXPORT void ArServerSimpleComMovementLogging::logVelocitiesReceivedDisable(void) +{ + myRobot->lock(); + myRobot->setLogVelocitiesReceived(false); + myRobot->unlock(); +} + +AREXPORT void ArServerSimpleComMovementLogging::packetsReceivedTrackingEnable(void) +{ + myRobot->lock(); + myRobot->setPacketsReceivedTracking(true); + myRobot->unlock(); +} + +AREXPORT void ArServerSimpleComMovementLogging::packetsReceivedTrackingDisable(void) +{ + myRobot->lock(); + myRobot->setPacketsReceivedTracking(false); + myRobot->unlock(); +} + + +AREXPORT void ArServerSimpleComMovementLogging::packetsSentTrackingEnable(void) +{ + myRobot->lock(); + myRobot->setPacketsSentTracking(true); + myRobot->unlock(); +} + +AREXPORT void ArServerSimpleComMovementLogging::packetsSentTrackingDisable(void) +{ + myRobot->lock(); + myRobot->setPacketsSentTracking(false); + myRobot->unlock(); +} + +AREXPORT void ArServerSimpleComMovementLogging::logActionsEnable(void) +{ + myRobot->lock(); + myRobot->setLogActions(true); + myRobot->unlock(); +} + +AREXPORT void ArServerSimpleComMovementLogging::logActionsDisable(void) +{ + myRobot->lock(); + myRobot->setLogActions(false); + myRobot->unlock(); +} + +AREXPORT void ArServerSimpleComMovementLogging::logActions(void) +{ + myRobot->lock(); + myRobot->logActions(); + myRobot->unlock(); +} + +AREXPORT void ArServerSimpleComMovementLogging::popupMovementParams(void) +{ + char buf[32000]; + myRobot->lock(); + sprintf(buf, "AbsoluteMaxTransVel %.0f AbsoluteMaxTransNegVel %.0f\nTransVelMax %.0f TransNegVelMax %.0f\n\nAbsoluteMaxTransAccel %.0f AbsoluteMaxTransDecel %.0f\nTransAccel %.0f TransDecel %.0f\n\nAbsoluteMaxRotVel %.0f AbsoluteMaxRotAccel %.0f AbsoluteMaxRotDecel %.0f\nRotVelMax %.0f RotAccel %.0f RotDecel %.0f", + myRobot->getAbsoluteMaxTransVel(), + myRobot->getAbsoluteMaxTransNegVel(), + myRobot->getTransVelMax(), + myRobot->getTransNegVelMax(), + myRobot->getAbsoluteMaxTransAccel(), + myRobot->getAbsoluteMaxTransDecel(), + myRobot->getTransAccel(), + myRobot->getTransDecel(), + myRobot->getAbsoluteMaxRotVel(), + myRobot->getAbsoluteMaxRotAccel(), + myRobot->getAbsoluteMaxRotDecel(), + myRobot->getRotVelMax(), + myRobot->getRotAccel(), + myRobot->getRotDecel()); + if (myRobot->hasLatVel()) + sprintf(buf, "%s\n\nAbsoluteMaxLatVel %.0f AbsoluteMaxLatAccel %.0f AbsoluteMaxLatDecel %.0f\nLatVelMax %.0f LatAccel %.0f LatDecel %.0f", + buf, + myRobot->getAbsoluteMaxLatVel(), + myRobot->getAbsoluteMaxLatAccel(), + myRobot->getAbsoluteMaxLatDecel(), + myRobot->getLatVelMax(), + myRobot->getLatAccel(), + myRobot->getLatDecel()); + + ArServerHandlerPopupInfo popupInfo( + NULL, "Robot Movement Parameters", buf, + ArServerHandlerPopup::INFORMATION, + 0, 0, 0, NULL, "OK", "Done viewing movement parameters"); + + myPopupHandler->createPopup(&popupInfo); + myRobot->unlock(); +} +AREXPORT ArServerSimpleComGyro::ArServerSimpleComGyro( + ArServerHandlerCommands *handlerCommands, ArRobot *robot, + ArAnalogGyro *gyro) : + myGyroEnableCB(this, &ArServerSimpleComGyro::gyroEnable), + myGyroDisableCB(this, &ArServerSimpleComGyro::gyroDisable) +{ + myHandlerCommands = handlerCommands; + myRobot = robot; + myGyro = gyro; + myHandlerCommands->addCommand("GyroEnable", + "Enables the gyro", + &myGyroEnableCB); + myHandlerCommands->addCommand("GyroDisable", + "Disables the gyro", + &myGyroDisableCB); +} + +AREXPORT void ArServerSimpleComMovementLogging::resetOdometer(void) +{ + myRobot->lock(); + myRobot->resetTripOdometer(); + myRobot->unlock(); +} + +AREXPORT ArServerSimpleComGyro::~ArServerSimpleComGyro() +{ +} + +AREXPORT void ArServerSimpleComGyro::gyroEnable(void) +{ + myRobot->lock(); + if (myGyro != NULL) + myGyro->activate(); + myRobot->unlock(); +} + +AREXPORT void ArServerSimpleComGyro::gyroDisable(void) +{ + myRobot->lock(); + if (myGyro != NULL) + myGyro->deactivate(); + myRobot->unlock(); +} + +AREXPORT ArServerSimpleComLogRobotConfig::ArServerSimpleComLogRobotConfig( + ArServerHandlerCommands *commands, ArRobot* robot, + ArServerHandlerPopup *popupHandler) : + myPacketArrivedCB(this, + &ArServerSimpleComLogRobotConfig::configPacketArrived), + myPacketReader(robot, false, &myPacketArrivedCB), + myLogConfigCB(this, &ArServerSimpleComLogRobotConfig::logConfig), + myLogMovementConfigCB( + this, &ArServerSimpleComLogRobotConfig::logMovementConfig), + myLogOrigConfigCB(this, &ArServerSimpleComLogRobotConfig::logOrigConfig), + myPopupConfigCB(this, &ArServerSimpleComLogRobotConfig::popupConfig), + myPopupOrigConfigCB(this, &ArServerSimpleComLogRobotConfig::popupOrigConfig), + myPopupMovementConfigCB( + this, &ArServerSimpleComLogRobotConfig::popupMovementConfig) +{ + myRobot = robot; + myHandlerCommands = commands; + myPopupHandler = popupHandler; + + myLogConfig = false; + myPopupConfig = false; + myLogConfigMovement = false; + myPopupConfigMovement = false; + + commands->addCommand("LogRobotConfig", + "Get current robot configuration and write it to the server log.", + &myLogConfigCB); + commands->addCommand("LogRobotConfigOrig", + "Logs the original config packet the robot sent on connection.", + &myLogOrigConfigCB); + commands->addCommand("LogRobotConfigMovement", + "Get current robot configuration and write the movement part to the server log.", + &myLogMovementConfigCB); + if (myPopupHandler != NULL) + { + commands->addCommand("PopupRobotConfig", + "Popups up the current robot configuration.", + &myPopupConfigCB); + commands->addCommand("PopupRobotConfigOrig", + "Popups up the original config packet the robot sent on connection.", + &myPopupOrigConfigCB); + commands->addCommand("PopupRobotConfigMovement", + "Popups up the movement part of the current robot configuration.", + &myPopupMovementConfigCB); + + } +} + + +AREXPORT void ArServerSimpleComLogRobotConfig::logConfig(void) +{ + ArLog::log(ArLog::Normal, "Server received logRobotConfig command. Config packet requested"); + myRobot->lock(); + myPacketReader.requestPacket(); + myLogConfig = true; + myRobot->unlock(); +} + +AREXPORT void ArServerSimpleComLogRobotConfig::logMovementConfig(void) +{ + ArLog::log(ArLog::Normal, "Server received logRobotConfigMovement command. Config packet requested"); + myRobot->lock(); + myPacketReader.requestPacket(); + myLogConfigMovement = true; + myRobot->unlock(); +} + + +AREXPORT void ArServerSimpleComLogRobotConfig::logOrigConfig(void) +{ + myRobot->lock(); + if (myRobot->getOrigRobotConfig() != NULL && + myRobot->getOrigRobotConfig()->hasPacketArrived()) + { + ArLog::log(ArLog::Normal, "-- Orig Config Packet: --"); + myRobot->getOrigRobotConfig()->log(); + ArLog::log(ArLog::Normal, "-- End Orig Config --"); + } + else + { + ArLog::log(ArLog::Normal, + "Cannot log Orig Config since it was never received."); + } + myRobot->unlock(); +} + +AREXPORT void ArServerSimpleComLogRobotConfig::popupConfig(void) +{ + ArLog::log(ArLog::Normal, "Server received popupRobotConfig command. Config packet requested"); + myRobot->lock(); + myPacketReader.requestPacket(); + myPopupConfig = true; + myRobot->unlock(); +} + +AREXPORT void ArServerSimpleComLogRobotConfig::popupMovementConfig(void) +{ + ArLog::log(ArLog::Normal, "Server received popupRobotConfigMovement command. Config packet requested"); + myRobot->lock(); + myPacketReader.requestPacket(); + myPopupConfigMovement = true; + myRobot->unlock(); +} + +AREXPORT void ArServerSimpleComLogRobotConfig::popupOrigConfig(void) +{ + myRobot->lock(); + if (myRobot->getOrigRobotConfig() != NULL && + myRobot->getOrigRobotConfig()->hasPacketArrived()) + { + std::string str; + str = myRobot->getOrigRobotConfig()->buildString(); + ArServerHandlerPopupInfo popupInfo( + NULL, "Orig robot config", str.c_str(), + ArServerHandlerPopup::INFORMATION, + 0, 0, 0, NULL, "OK", "Done viewing orig robot config parameters"); + + myPopupHandler->createPopup(&popupInfo); + } + else + { + ArLog::log(ArLog::Normal, + "Cannot log Orig Config since it was never received."); + } + myRobot->unlock(); +} + +void ArServerSimpleComLogRobotConfig::configPacketArrived(void) +{ + if (myLogConfig) + { + ArLog::log(ArLog::Normal, "-- Robot Config Movement Packet Returned: --"); + myPacketReader.log(); + ArLog::log(ArLog::Normal, "-- End Config --"); + } + if (myLogConfigMovement) + { + ArLog::log(ArLog::Normal, "-- Robot Config Movement Packet Returned: --"); + myPacketReader.logMovement(); + ArLog::log(ArLog::Normal, "-- End Config --"); + } + if (myPopupConfig) + { + std::string str; + str = myPacketReader.buildString(); + ArServerHandlerPopupInfo popupInfo( + NULL, "Robot config", str.c_str(), + ArServerHandlerPopup::INFORMATION, + 0, 0, 0, NULL, "OK", "Done viewing robot config parameters"); + + myPopupHandler->createPopup(&popupInfo); + + } + if (myPopupConfigMovement) + { + std::string str; + str = "_______________________________________________________\n"; + str += myPacketReader.buildStringMovement(); + ArServerHandlerPopupInfo popupInfo( + NULL, "Robot config movement", str.c_str(), + ArServerHandlerPopup::INFORMATION, + 0, 0, 0, NULL, "OK", + "Done viewing robot config movement parameters"); + myPopupHandler->createPopup(&popupInfo); + } + myLogConfig = false; + myPopupConfig = false; + myLogConfigMovement = false; + myPopupConfigMovement = false; +} + +AREXPORT ArServerSimpleComLogActions::ArServerSimpleComLogActions(ArServerHandlerCommands *commands, ArRobot* robot) : + myRobot(robot), myCallback(this, &ArServerSimpleComLogActions::logActions) +{ + commands->addCommand("LogActions", "Write current ArRobot actions to server log file.", + &myCallback); +} + +AREXPORT void ArServerSimpleComLogActions::logActions() +{ + ArLog::log(ArLog::Normal, "Server simple command logActions: current ArRobot actions are:"); + myRobot->logActions(); +} + +AREXPORT ArServerSimpleServerCommands::ArServerSimpleServerCommands( + ArServerHandlerCommands *commands, ArServerBase *server, + bool addLogConnections) : + myTerseTrackingCB(this, &ArServerSimpleServerCommands::logTerseTracking), + myVerboseTrackingCB(this, &ArServerSimpleServerCommands::logVerboseTracking), + myResetTrackingCB(this, &ArServerSimpleServerCommands::resetTracking), + myLogConnectionsCB(this, &ArServerSimpleServerCommands::logConnections) +{ + myServer = server; + commands->addCommand("NetworkTrackingLogTerse", + "Logs the information about client commands sent and received:", + &myTerseTrackingCB); + commands->addCommand("NetworkTrackingLogVerbose", + "Logs verbosely (broken up by tcp/udp) the information about client commands sent and received:", + &myVerboseTrackingCB); + + commands->addCommand("NetworkTrackingReset", + "Resets the information about client commands sent and received:", + &myResetTrackingCB); + if (addLogConnections) + commands->addCommand("NetworkLogConnections", + "Logs the connections to the server", + &myLogConnectionsCB); +} + +AREXPORT ArServerSimpleServerCommands::~ArServerSimpleServerCommands() +{ +} + +AREXPORT void ArServerSimpleServerCommands::logTerseTracking() +{ + myServer->logTracking(true); +} + +AREXPORT void ArServerSimpleServerCommands::logVerboseTracking() +{ + myServer->logTracking(false); +} + +AREXPORT void ArServerSimpleServerCommands::resetTracking() +{ + myServer->resetTracking(); +} + +AREXPORT void ArServerSimpleServerCommands::logConnections() +{ + myServer->logConnections(); +} + +AREXPORT ArServerSimplePopup::ArServerSimplePopup( + ArServerHandlerCommands *commands, + ArServerHandlerPopup *popupHandler) : + mySimplePopupCB(this, &ArServerSimplePopup::simplePopup) +{ + myCommands = commands; + myPopupHandler = popupHandler; + myCommands->addStringCommand( + "SimplePopup", + "\"\" \"<message>\" \"<button>\" <int:timeout>", + &mySimplePopupCB); +} + +AREXPORT ArServerSimplePopup::~ArServerSimplePopup() +{ +} + +AREXPORT void ArServerSimplePopup::simplePopup(ArArgumentBuilder *arg) +{ + + arg->compressQuoted(true); + + if (arg->getArgc() < 4) + { + ArLog::log(ArLog::Terse, + "simplePopup: Syntax error, not enough arguments."); + return; + } + + ArServerHandlerPopupInfo popupInfo( + arg->getArg(0), arg->getArg(0), + arg->getArg(1), ArServerHandlerPopup::INFORMATION, + 0, 0, arg->getArgInt(3), arg->getArg(1), + arg->getArg(2), arg->getArg(1)); + myPopupHandler->createPopup(&popupInfo); +} + +AREXPORT ArServerSimpleLogRobotDebugPackets::ArServerSimpleLogRobotDebugPackets( + ArServerHandlerCommands *commands, ArRobot *robot, + const char *baseDirectory) : + myPacketHandlerCB(this, &ArServerSimpleLogRobotDebugPackets::packetHandler), + myStartLoggingCB(this, &ArServerSimpleLogRobotDebugPackets::startLogging, + "robotDebugPacketsLog.txt"), + myStopLoggingCB(this, &ArServerSimpleLogRobotDebugPackets::stopLogging) +{ + myRobot = robot; + myCommands = commands; + + myPacketHandlerCB.setName("ArServerSimpleLogRobotDebugPackets::packetHandler"); + myStartLoggingCB.setName("ArLogRobotDebugPacktets::startLogging"); + myStopLoggingCB.setName("ArLogRobotDebugPacktets::stopLogging"); + + myRobot->addPacketHandler(&myPacketHandlerCB); + myCommands->addCommand("RobotDebugPacketLoggingEnable", + "Starts logging robot debug packets to file", + &myStartLoggingCB); + + myCommands->addCommand("RobotDebugPacketLoggingDisable", + "Stops logging robot debug packets to file", + &myStopLoggingCB); + + myFile = NULL; + if (baseDirectory != NULL && baseDirectory[0] != '\0') + myBaseDir = baseDirectory; + else + myBaseDir = ""; +} + +AREXPORT ArServerSimpleLogRobotDebugPackets::~ArServerSimpleLogRobotDebugPackets() +{ + myRobot->remPacketHandler(&myPacketHandlerCB); +} + +AREXPORT bool ArServerSimpleLogRobotDebugPackets::packetHandler(ArRobotPacket *packet) +{ + if (packet->getID() != 0xfc || myFile == NULL) + return false; + + int numIntsInGroup = 0; + int numGroups = 0; + + numIntsInGroup = packet->bufToByte(); + numGroups = packet->bufToByte(); + + myNumVals = numIntsInGroup; + + if (numIntsInGroup == 0 || numGroups == 0) + { + ArLog::log(ArLog::Normal, "numIntsInGroup %d numGroups %d", + numIntsInGroup, numGroups); + return true; + } + + int i; + int j; + int val; + char buf[2048]; + char *timeStr; + int timeLen = 20; // this is a value based on the standard length of + // ctime return + time_t now; + for (i = 0; i < numGroups; i++) + { + now = time(NULL); + timeStr = ctime(&now); + // get take just the portion of the time we want + strncpy(buf, timeStr, timeLen); + buf[timeLen] = '\0'; + for (j = 0; j < numIntsInGroup; j++) + { + val = packet->bufToByte2(); + myVals[j] = val; + sprintf(buf, "%s\t%d", buf, val); + } + fprintf(myFile, "%s\n", buf); + } + return true; +} + +AREXPORT bool ArServerSimpleLogRobotDebugPackets::startLogging(const char *fileName) +{ + std::string realFileName; + + if (myFile != NULL) + stopLogging(); + + if (fileName == NULL || fileName[0] == '\0') + { + ArLog::log(ArLog::Normal, "ArServerSimpleLogRobotDebugPackets::startLogging: Empty filename given, cannot log"); + return false; + } + + if (fileName[0] == '/' || fileName[0] == '\\') + { + realFileName = fileName; + } + else + { + realFileName = myBaseDir; + realFileName += fileName; + } + + + if ((myFile = ArUtil::fopen(realFileName.c_str(), "w")) == NULL) + { + ArLog::log(ArLog::Terse, + "ArServerSimpleLogRobotDebugPackets::startLogging: Could not open file %s for writing", + realFileName.c_str()); + return false; + } + + ArLog::log(ArLog::Normal, + "ArServerSimpleLogRobotDebugPackets::startLogging: Logging to file %s", + realFileName.c_str()); + myRobot->lock(); + myRobot->comInt(251, 1); + myRobot->unlock(); + return true; +} + +AREXPORT bool ArServerSimpleLogRobotDebugPackets::stopLogging(void) +{ + if (myFile != NULL) + { + ArLog::log(ArLog::Normal, "ArServerSimpleLogRobotDebugPackets::stopLogging: Stopping"); + fclose(myFile); + myFile = NULL; + } + myRobot->lock(); + myRobot->comInt(251, 0); + myRobot->unlock(); + return true; +} + +AREXPORT void ArServerSimpleLogRobotDebugPackets::addToInfoGroup( + ArStringInfoGroup *infoGroup, const char *name, int whichVal, + const char *format) +{ + infoGroup->addStringInt( + name, 8, + new ArRetFunctor1C<int, ArServerSimpleLogRobotDebugPackets, int>( + this, + &ArServerSimpleLogRobotDebugPackets::getValue, whichVal), + format); +} + +AREXPORT int ArServerSimpleLogRobotDebugPackets::getNumValues(void) +{ + return myNumVals; +} + +AREXPORT int ArServerSimpleLogRobotDebugPackets::getValue(int whichVal) +{ + if (myVals.find(whichVal) == myVals.end()) + return 0; + else + return myVals[whichVal]; +} + +AREXPORT ArServerSimpleConnectionTester::ArServerSimpleConnectionTester( + ArServerHandlerCommands *handlerCommands, ArRobot *robot) : + myConnectionTestStartCB(this, &ArServerSimpleConnectionTester::connectionTestStart), + myConnectionTestStopCB(this, &ArServerSimpleConnectionTester::connectionTestStop), + myPacketHandlerCB(this, &ArServerSimpleConnectionTester::packetHandler), + myUserTaskCB(this, &ArServerSimpleConnectionTester::userTask) +{ + myRobot = robot; + myHandlerCommands = handlerCommands; + + if (myHandlerCommands) + { + myHandlerCommands->addCommand( + "ConnectionTesterStart", + "Starts testing the connection to the robot", + &myConnectionTestStartCB); + myHandlerCommands->addCommand( + "ConnectionTesterStop", + "Stops testing the connection to the robot", + &myConnectionTestStopCB); + } + + myPacketHandlerCB.setName("ArServerSimpleConnectionTester::packetHandler"); + myUserTaskCB.setName("ArServerSimpleConnectionTester::userTask"); + +} + +AREXPORT ArServerSimpleConnectionTester::~ArServerSimpleConnectionTester() +{ +} + + +AREXPORT void ArServerSimpleConnectionTester::connectionTestStart(void) +{ + ArLog::log(ArLog::Normal, "ConnectionTester: Starting test"); + myRobot->lock(); + myFirst = true; + myRobot->remPacketHandler(&myPacketHandlerCB); + myRobot->addPacketHandler(&myPacketHandlerCB, ArListPos::FIRST); + myRobot->remUserTask(&myUserTaskCB); + myRobot->addUserTask("connectionTester", 50, &myUserTaskCB); + myRobot->unlock(); +} + +AREXPORT void ArServerSimpleConnectionTester::connectionTestStop(void) +{ + ArLog::log(ArLog::Normal, "ConnectionTester: Stopping test"); + myRobot->lock(); + log(); + myRobot->remPacketHandler(&myPacketHandlerCB); + myRobot->remUserTask(&myUserTaskCB); + myRobot->unlock(); +} + +bool ArServerSimpleConnectionTester::packetHandler(ArRobotPacket *packet) +{ + if (packet->getID() == 0x90) + { + myReceivedPackets++; + myPacketsThisCycle++; + myPacketReceived.setToNow(); + return true; + } + return false; +} + +void ArServerSimpleConnectionTester::userTask(void) +{ + if (myFirst) + { + myRobot->comInt(ArCommands::ENCODER, 1); + myFirst = false; + myReceivedPackets = 0; + myMissedPackets = 0; + myMissedMotorPackets = 0; + myPacketsThisCycle = 0; + myCyclesSincePacket = 0; + myPacketReceived.setToNow(); + myLastLog.setToNow(); + log(); + return; + } + + if (myCyclesSincePacket > 2 && myPacketReceived.mSecSince() > 200) + { + myMissedPackets++; + log(); + myRobot->comInt(ArCommands::ENCODER, 1); + } + /* + if (myPacketsThisCycle > 1) + { + myMissedMotorPackets++; + log(); + } + */ + if (myPacketsThisCycle == 0) + myCyclesSincePacket++; + + if (myPacketsThisCycle > 0) + myRobot->comInt(ArCommands::ENCODER, 1); + + if (myLastLog.secSince() >= 15) + { + log(); + myLastLog.setToNow(); + } + + myPacketsThisCycle = 0; +} + +void ArServerSimpleConnectionTester::log(void) +{ + ArLog::log(ArLog::Normal, "ConnectionTester: Received %d packets, missed %d packets, mpacs %d", + myReceivedPackets, myMissedPackets, myRobot->getMotorPacCount()); + +} + + diff --git a/Legacy/Aria/ArNetworking/src/ArServerSimpleOpener.cpp b/Legacy/Aria/ArNetworking/src/ArServerSimpleOpener.cpp new file mode 100644 index 0000000..514510e --- /dev/null +++ b/Legacy/Aria/ArNetworking/src/ArServerSimpleOpener.cpp @@ -0,0 +1,333 @@ +#include "Aria.h" +#include "ArExport.h" +#include "ArServerBase.h" +#include "ArServerSimpleOpener.h" + + +/** + @param parser the parser to use for information + **/ +AREXPORT ArServerSimpleOpener::ArServerSimpleOpener( + ArArgumentParser *parser, const char *prefix, + bool addAriaCallbacks) : + myParseArgsCB(this, &ArServerSimpleOpener::parseArgs), + myLogOptionsCB(this, &ArServerSimpleOpener::logOptions), + myFileServerKeyCB(this, &ArServerSimpleOpener::fileServerKeyCallback) +{ + myParser = parser; + myOwnParser = false; + if (prefix != NULL) + myPrefix = prefix; + else + myPrefix = ""; + + myUserFile = NULL; + myServerPort = 7272; + myLogUserInfo = false; + myLogCommandGroups = false; + myServer = NULL; + myOpenOnIP = NULL; + myTcpOnly = false; + + std::string functorName; + functorName = prefix; + functorName += "ArServerSimpleOpener"; + + if (addAriaCallbacks) + { + myParseArgsCB.setName(functorName.c_str()); + Aria::addParseArgsCB(&myParseArgsCB, 60); + myLogOptionsCB.setName(functorName.c_str()); + Aria::addLogOptionsCB(&myLogOptionsCB, 60); + } + + myFileServerKeyCB.setName("ArServerSimpleOpener::serverKey"); + myFileParser.addHandler("serverKey", &myFileServerKeyCB); +} + +AREXPORT ArServerSimpleOpener::~ArServerSimpleOpener(void) +{ + +} + +AREXPORT bool ArServerSimpleOpener::parseArgs(void) +{ + return parseArgs(myParser); +} + +AREXPORT bool ArServerSimpleOpener::parseArgs(ArArgumentParser *parser) +{ + if (myPrefix.size() > 0) + return parseArgsWithPrefix(parser); + else + return parseArgsWithOutPrefix(parser); + +} + +AREXPORT bool ArServerSimpleOpener::parseArgsWithOutPrefix(ArArgumentParser *parser) +{ + + bool wasReallySetOnlyTrue = parser->getWasReallySetOnlyTrue(); + parser->setWasReallySetOnlyTrue(false); + + if (parser->checkArgument("-lui") || + parser->checkArgument("-logUserInfo")) + { + myLogUserInfo = true; + } + + if (parser->checkArgument("-lcg") || + parser->checkArgument("-logCommandGroups")) + { + myLogCommandGroups = true; + } + + if (parser->checkArgument("-serverTcpOnly")) + { + myTcpOnly = true; + } + + if (!parser->checkParameterArgumentString("-ui", + &myUserFile) || + !parser->checkParameterArgumentString("-userInfo", + &myUserFile) || + !parser->checkParameterArgumentInteger("-sp", + &myServerPort) || + !parser->checkParameterArgumentInteger("-serverPort", + &myServerPort) || + !parser->checkParameterArgumentString("-sip", + &myOpenOnIP) || + !parser->checkParameterArgumentString("-serverIP", + &myOpenOnIP)) + + /*|| + !parser->checkParameterArgumentString("-setServerKey", + &myServerKey) || + !parser->checkParameterArgumentString("-ssk", + &myServerKey))*/ + { + return false; + } + + bool wasReallySet; + const char *serverInfoFile = NULL; + while (myParser->checkParameterArgumentString( + "-serverInfoFile", &serverInfoFile, + &wasReallySet, true) && + wasReallySet) + { + if (serverInfoFile != NULL && !parseFile(serverInfoFile)) + { + parser->setWasReallySetOnlyTrue(wasReallySetOnlyTrue); + return false; + } + } + parser->setWasReallySetOnlyTrue(wasReallySetOnlyTrue); + return true; +} + +AREXPORT bool ArServerSimpleOpener::parseArgsWithPrefix( + ArArgumentParser *parser) +{ + + bool wasReallySetOnlyTrue = parser->getWasReallySetOnlyTrue(); + parser->setWasReallySetOnlyTrue(true); + + if (parser->checkArgumentVar("-%sLogUserInfo", myPrefix.c_str())) + { + myLogUserInfo = true; + } + + if (parser->checkArgumentVar("-%sLogCommandGroups", myPrefix.c_str())) + { + myLogCommandGroups = true; + } + + if (parser->checkArgumentVar("-%sTcpOnly", myPrefix.c_str())) + { + myTcpOnly = true; + } + + if (!parser->checkParameterArgumentStringVar( + NULL, &myUserFile, "-%sUserInfo", myPrefix.c_str()) || + !parser->checkParameterArgumentStringVar( + NULL, &myOpenOnIP, "-%sServerIP", myPrefix.c_str()) || + !parser->checkParameterArgumentIntegerVar( + NULL, &myServerPort, "-%sServerPort", myPrefix.c_str())) + /*|| + !parser->checkParameterArgumentStringVar( + NULL, &myServerKey, "-%sSetServerKey", myPrefix.c_str()))*/ + { + parser->setWasReallySetOnlyTrue(wasReallySetOnlyTrue); + return false; + } + + bool wasReallySet; + const char *serverInfoFile = NULL; + if (myParser->checkParameterArgumentStringVar( + &wasReallySet, &serverInfoFile, "-%sServerInfoFile", + myPrefix.c_str()) && + wasReallySet) + { + if (serverInfoFile != NULL && !parseFile(serverInfoFile)) + { + parser->setWasReallySetOnlyTrue(wasReallySetOnlyTrue); + return false; + } + } + + parser->setWasReallySetOnlyTrue(wasReallySetOnlyTrue); + return true; +} + +AREXPORT void ArServerSimpleOpener::logOptions(void) const +{ + if (myPrefix.size() > 0) + logOptionsWithPrefix(); + else + logOptionsWithOutPrefix(); +} + +AREXPORT void ArServerSimpleOpener::logOptionsWithOutPrefix(void) const +{ + // ArLog::log(ArLog::Terse, ""); + ArLog::log(ArLog::Terse, "Options for ArServerSimpleOpener:"); + ArLog::log(ArLog::Terse, "-serverPort <serverPortNumber>"); + ArLog::log(ArLog::Terse, "-sp <serverPortNumber>"); + ArLog::log(ArLog::Terse, "-serverIP <serverIPToOpenOn>"); + ArLog::log(ArLog::Terse, "-sip <serverIPToOpenOn>"); + ArLog::log(ArLog::Terse, "-serverTcpOnly"); + ArLog::log(ArLog::Terse, "-userInfo <userInfoFileName>"); + ArLog::log(ArLog::Terse, "-ui <userInfoFileName>"); + ArLog::log(ArLog::Terse, "-logUserInfo"); + ArLog::log(ArLog::Terse, "-lui"); + ArLog::log(ArLog::Terse, "-logCommandGroups"); + ArLog::log(ArLog::Terse, "-lcg"); + /* + ArLog::log(ArLog::Terse, "-setServerKey <key>"); + ArLog::log(ArLog::Terse, "-ssk <key>"); + */ + ArLog::log(ArLog::Terse, "-serverInfoFile <file>"); + ArLog::log(ArLog::Terse, ""); +} + +AREXPORT void ArServerSimpleOpener::logOptionsWithPrefix(void) const +{ + //ArLog::log(ArLog::Terse, ""); + ArLog::log(ArLog::Terse, "Options for ArServerSimpleOpener:"); + ArLog::log(ArLog::Terse, "-%sServerPort <serverPortNumber>", + myPrefix.c_str()); + ArLog::log(ArLog::Terse, "-%sServerIP <serverIPToOpenOn>", + myPrefix.c_str()); + ArLog::log(ArLog::Terse, "-%sServerTcpOnly", + myPrefix.c_str()); + ArLog::log(ArLog::Terse, "-%sUserInfo <userInfoFileName>", + myPrefix.c_str()); + ArLog::log(ArLog::Terse, "-%sLogUserInfo", myPrefix.c_str()); + ArLog::log(ArLog::Terse, "-%sLogCommandGroups", myPrefix.c_str()); + /*ArLog::log(ArLog::Terse, "-%sSetServerKey <key>", + myPrefix.c_str()); + */ + ArLog::log(ArLog::Terse, "-%sServerInfoFile <file>", + myPrefix.c_str()); + ArLog::log(ArLog::Terse, ""); +} + +/** + @param server the server to operate on + + @param baseDirectory the base directory (solely for loading user + information) + + @param secondsToTryFor this is the number of seconds to try opening + for, 0 means only try to open once + **/ +AREXPORT bool ArServerSimpleOpener::open(ArServerBase *server, + const char *baseDirectory, + int secondsToTryFor) +{ + ArTime startedServer; + bool serverOpened; + startedServer.setToNow(); + myBadUserFile = false; + myOpenFailed = false; + + if (secondsToTryFor < 0) + secondsToTryFor = 0; + + server->setServerKey(myServerKey.c_str()); + + if (myUserFile != NULL && myUserFile[0] != '\0' && + !server->loadUserInfo(myUserFile, baseDirectory)) + { + ArLog::log(ArLog::Normal, "ArServerSimpleOpener: Bad user file"); + myBadUserFile = true; + return false; + } + + while (Aria::getRunning() && + (serverOpened = + server->open(myServerPort, myOpenOnIP, myTcpOnly)) == false) + { + if (secondsToTryFor == 0) + { + ArLog::log(ArLog::Normal, "Could not open server on port %d", myServerPort); + myOpenFailed = true; + return false; + } + if (startedServer.secSince() > secondsToTryFor) + { + ArLog::log(ArLog::Normal, "Could not open server on port %d even after %d seconds", + myServerPort, secondsToTryFor); + myOpenFailed = true; + return false; + } + ArLog::log(ArLog::Normal, "Can't open server on port %d yet, waiting", myServerPort); + ArUtil::sleep(1000); + } + + if (serverOpened) + myServer = server; + + return serverOpened; +} + +AREXPORT bool ArServerSimpleOpener::checkAndLog(void) const +{ + if (myServer != NULL && myLogCommandGroups) + myServer->logCommandGroups(); + + if (myServer != NULL && myLogUserInfo) + myServer->logUserInfo(); + + + return true; +} + +bool ArServerSimpleOpener::fileServerKeyCallback(ArArgumentBuilder *arg) +{ + if (arg->getArgc() > 1) + { + ArLog::log(ArLog::Normal, "Bad serverKey line: %s %s", + arg->getExtraString(), arg->getFullString()); + return false; + } + if (arg->getArgc() == 0) + myServerKey = ""; + else + myServerKey = arg->getArg(0); + return true; +} + +AREXPORT bool ArServerSimpleOpener::parseFile(const char *fileName) +{ + ArLog::log(ArLog::Normal, "Loading server key from %s", + fileName); + if (!myFileParser.parseFile(fileName)) + { + ArLog::log(ArLog::Normal, "Failed parsing server key file %s", + fileName); + return false; + } + return true; +} diff --git a/Legacy/Aria/ArNetworking/src/ArServerUserInfo.cpp b/Legacy/Aria/ArNetworking/src/ArServerUserInfo.cpp new file mode 100644 index 0000000..4b0d1db --- /dev/null +++ b/Legacy/Aria/ArNetworking/src/ArServerUserInfo.cpp @@ -0,0 +1,273 @@ +#include "Aria.h" +#include "ArExport.h" +#include "ArServerUserInfo.h" +#include "md5.h" + +AREXPORT ArServerUserInfo::ArServerUserInfo(const char *baseDirectory) : + myV1HeaderCB(this, &ArServerUserInfo::v1HeaderCallback), + myV1UserCB(this, &ArServerUserInfo::v1UserCallback), + myV1DoNotUseCB(this, &ArServerUserInfo::v1DoNotUseCallback) +{ + myDataMutex.setLogName("ArServerUserInfo::myDataMutex"); + myParser.setBaseDirectory(baseDirectory); + myGotHeader = false; + myDoNotUse = false; + myLogFailureVerbosely = false; +} + +AREXPORT ArServerUserInfo::~ArServerUserInfo() +{ + +} + +AREXPORT void ArServerUserInfo::setBaseDirectory(const char *baseDirectory) +{ + myDataMutex.lock(); + myParser.setBaseDirectory(baseDirectory); + myDataMutex.unlock(); +} + + +bool ArServerUserInfo::v1HeaderCallback(ArArgumentBuilder * arg) +{ + removeHandlers(); + if (myParser.addHandler("user", &myV1UserCB) && + myParser.addHandler("doNotUse", &myV1DoNotUseCB)) + { + myGotHeader = true; + myDoNotUse = false; + return true; + } + else + { + ArLog::log(ArLog::Terse, "ArServerUserInfo::Could not add user info callback"); + return false; + } +} + +bool ArServerUserInfo::v1UserCallback(ArArgumentBuilder * arg) +{ + if (arg->getArgc() < 2) + { + ArLog::log(ArLog::Normal, "ArServerUserInfo: Not enough arguments to user info 'user <user> <password> <reapingOptional:group>"); + return false; + } + + const char *user; + const char *password; + user = arg->getArg(0); + if (!ArUtil::isOnlyAlphaNumeric(user)) + { + ArLog::log(ArLog::Normal, "ArServerUserInfo: user '%s' has non-alpha-numeric characters in it", user); + return false; + } + password = arg->getArg(1); + if (!ArUtil::isOnlyAlphaNumeric(password)) + { + ArLog::log(ArLog::Normal, "ArServerUserInfo: password has non-alpha-numeric characters in it"); + return false; + } + + if (myPasswords.find(user) != myPasswords.end()) + { + ArLog::log(ArLog::Terse, "ArServerUserInfo: Already a user with name %s", user); + return false; + } + //printf("Adding user %s with password %s and groups\n", user, password); + myPasswords[user] = password; + + std::set<std::string, ArStrCaseCmpOp> *groups; + groups = new std::set<std::string, ArStrCaseCmpOp>; + myGroups[user] = groups; + + unsigned int i; + for (i = 2; i < arg->getArgc(); i++) + { + groups->insert(arg->getArg(i)); + } + return true; +} + +bool ArServerUserInfo::v1DoNotUseCallback(ArArgumentBuilder * arg) +{ + myDoNotUse = true; + return true; +} + +void ArServerUserInfo::removeHandlers(void) +{ + myParser.remHandler(&myV1HeaderCB); + myParser.remHandler(&myV1UserCB); +} + +AREXPORT bool ArServerUserInfo::readFile(const char *fileName) +{ + myDataMutex.lock(); + removeHandlers(); + myPasswords.clear(); + ArUtil::deleteSetPairs(myGroups.begin(), myGroups.end()); + myGroups.clear(); + myParser.addHandler("UserInfoVersion1", &myV1HeaderCB); + myGotHeader = false; + if (!myParser.parseFile(fileName, false)) + { + myDataMutex.unlock(); + ArLog::log(ArLog::Terse, "Problem loading server user info"); + return false; + } + removeHandlers(); + if (myGotHeader) + { + myDataMutex.unlock(); + ArLog::log(ArLog::Verbose, "Loaded server user info"); + return true; + } + else + { + myDataMutex.unlock(); + ArLog::log(ArLog::Normal, "Problem loading server user info: no header"); + return false; + } +} + +AREXPORT bool ArServerUserInfo::matchUserPassword( + const char *user, unsigned char password[16], const char *passwordKey, + const char *serverKey, bool logFailureVerbosely) const +{ + std::map<std::string, std::string, ArStrCaseCmpOp>::const_iterator it; + if (!ArUtil::isOnlyAlphaNumeric(user)) + { + ArLog::log(ArLog::Normal, + "ArServerUserInfo: login denied: user '%s' has non alpha-numeric characters", + user); + return false; + } + it = myPasswords.find(user); + if (it == myPasswords.end()) + { + ArLog::log(ArLog::Normal, "ArServerUserInfo: login denied: No user %s", + user); + return false; + } + /* thd old simple clear text way + if (ArUtil::strcmp((*it).second, password) != 0) + { + ArLog::log(ArLog::Normal, + "ArServerUserInfo: login denied: Wrong password for user %s", + user); + return false; + }*/ + md5_state_t md5State; + unsigned char md5Digest[16]; + + md5_init(&md5State); + md5_append(&md5State, (unsigned char *)serverKey, strlen(serverKey)); + md5_append(&md5State, (unsigned char *)passwordKey, strlen(passwordKey)); + md5_append(&md5State, (unsigned char *)(*it).second.c_str(), + (*it).second.size()); + md5_finish(&md5State, md5Digest); + + if (memcmp(md5Digest, password, 16) != 0) + { + + ArLog::log(ArLog::Normal, + "ArServerUserInfo: login denied: Wrong password for user %s", + user); + if (logFailureVerbosely) + { + ArLog::log(ArLog::Terse, "The server key is '%s'", serverKey); + ArLog::log(ArLog::Terse, "The password seed is '%s'", passwordKey); + ArLog::log(ArLog::Terse, "The resulting digest is: "); + logDigest(md5Digest); + ArLog::log(ArLog::Terse, "The returned password is:"); + logDigest(password); + } + return false; + } + return true; +} + +AREXPORT std::set<std::string, ArStrCaseCmpOp> +ArServerUserInfo::getUsersGroups(const char *user) const +{ + std::map<std::string, std::set<std::string, ArStrCaseCmpOp> *, ArStrCaseCmpOp>::const_iterator sit; + std::set<std::string, ArStrCaseCmpOp> ret; + + if ((sit = myGroups.find(user)) == myGroups.end()) + { + ArLog::log(ArLog::Terse, "No user %s", user); + return ret; + } + + ret = *((*sit).second); + return ret; +} + +AREXPORT void ArServerUserInfo::logUsers(void) const +{ + std::map<std::string, std::string, ArStrCaseCmpOp>::const_iterator it; + std::set<std::string, ArStrCaseCmpOp> groups; + std::set<std::string, ArStrCaseCmpOp>::const_iterator git; + std::string line; + if (myDoNotUse) + ArLog::log(ArLog::Terse, "The user info should not be used"); + else + ArLog::log(ArLog::Terse, "The user info should be used"); + for (it = myPasswords.begin(); it != myPasswords.end(); it++) + { + line = "User "; + line += (*it).first; + line += " has groups:"; + + groups = getUsersGroups((*it).first.c_str()); + /* + if ((sit = myGroups.find((*it).first)) == myGroups.end()) + { + ArLog::log(ArLog::Terse, "ArServerUserInfo::logUsersAndGroups: Hideous error with the groups of user '%s'", (*it).first.c_str()); + continue; + } + groups = (*sit).second; + */ + for (git = groups.begin(); git != groups.end(); git++) + { + line += " "; + line += (*git); + } + ArLog::log(ArLog::Terse, line.c_str()); + } +} + +AREXPORT bool ArServerUserInfo::doNotUse(void) const +{ + return myDoNotUse; +} + + +void ArServerUserInfo::logDigest(unsigned char digest[16]) const +{ + int i; + char buf[1024]; + buf[0] = '\0'; + int highNibble; + char highChar; + int lowNibble; + char lowChar; + for (i = 0; i < 16; i++) + { + highNibble = ((unsigned char)digest[i] >> 4) & 0xf; + if (highNibble <= 9) + highChar = '0' + highNibble; + else + highChar = 'a' + highNibble - 10; + lowNibble = (unsigned char)digest[i] & 0xf; + if (lowNibble <= 9) + lowChar = '0' + lowNibble; + else + lowChar = 'a' + lowNibble - 10; + sprintf(buf, "%s%c%c ", buf, highChar, lowChar); + } + ArLog::log(ArLog::Terse, buf); +} + + + diff --git a/Legacy/Aria/ArNetworking/src/ArTempDirectoryHelper.cpp b/Legacy/Aria/ArNetworking/src/ArTempDirectoryHelper.cpp new file mode 100644 index 0000000..9d95830 --- /dev/null +++ b/Legacy/Aria/ArNetworking/src/ArTempDirectoryHelper.cpp @@ -0,0 +1,250 @@ +#include "ArExport.h" + +#include "ArTempDirectoryHelper.h" + +#include "ArLog.h" +#include "ariaUtil.h" + +AREXPORT ArTempDirectoryHelper::ArTempDirectoryHelper + (const char *baseDirectory, + const char *tempDirectory) : + myBaseDirectory((baseDirectory != NULL) ? baseDirectory : ""), + myTempDirectory((tempDirectory != NULL) ? tempDirectory : ""), + myPreMoveCallbacks(), + myPostMoveCallbacks() +{ + if (myTempDirectory.empty()) { + myTempDirectory = myBaseDirectory; + } +} // end ctor + +AREXPORT ArTempDirectoryHelper::~ArTempDirectoryHelper() +{ +} + + +AREXPORT const char *ArTempDirectoryHelper::getTempDirectory() +{ + return myTempDirectory.c_str(); +} + + +AREXPORT const char *ArTempDirectoryHelper::getBaseDirectory() +{ + return myBaseDirectory.c_str(); +} + + + +AREXPORT bool ArTempDirectoryHelper::moveFileToBaseDirectory + (const char *fileName) +{ + if (!ArUtil::isStrEmpty(fileName)) { + std::list<std::string> fileNameList; + fileNameList.push_back(fileName); + return moveFilesToBaseDirectory(fileNameList); + } + else { + ArLog::log(ArLog::Normal, + "ArTempDirectoryHelper::moveFileToBaseDirectory() cannot move empty file name"); + return false; + } + +} // end method moveFileToBaseDirectory + + + +AREXPORT bool ArTempDirectoryHelper::moveFilesToBaseDirectory + (const std::list<std::string> &fileNameList) +{ + + bool isSuccess = true; + + // now, if our temp directory and base directory are different we + // need to move it and put the result in the packet, otherwise put + // in we're okay + if (ArUtil::strcasecmp(myBaseDirectory, myTempDirectory) != 0) + { +#ifndef WIN32 + char *mvName = "mv"; +#else + char *mvName = "move"; +#endif + + char systemBuf[6400]; + char fromBuf[1024]; + char toBuf[1024]; + + bool isFirstMoveCmd = true; + + for (std::list<std::string>::const_iterator iter = fileNameList.begin(); + iter != fileNameList.end(); + iter++) { + + + std::string sourceFileName = *iter; + + if (sourceFileName.empty()) { + continue; // Nothing to be done for this file... + } + + if (myTempDirectory.size() > 0) { + snprintf(fromBuf, sizeof(fromBuf), "%s%s", + myTempDirectory.c_str(), sourceFileName.c_str()); + } + else { + snprintf(fromBuf, sizeof(fromBuf), "%s", + sourceFileName.c_str()); + } + + ArUtil::fixSlashes(fromBuf, sizeof(fromBuf)); + + if (myBaseDirectory.size() > 0) { + snprintf(toBuf, sizeof(toBuf), "%s%s", + myBaseDirectory.c_str(), sourceFileName.c_str()); + } + else { + snprintf(toBuf, sizeof(toBuf), "%s", sourceFileName.c_str()); + } + + ArUtil::fixSlashes(toBuf, sizeof(toBuf)); + + // Create the move command + sprintf(systemBuf, "%s \"%s\" \"%s\"", mvName, fromBuf, toBuf); + + ArLog::log(ArLog::Normal, "Moving with '%s'", systemBuf); + + // Call our pre move callbacks + if (isFirstMoveCmd) { + isFirstMoveCmd = false; + + for (std::list<ArFunctor *>::iterator preIt = myPreMoveCallbacks.begin(); + preIt != myPreMoveCallbacks.end(); + preIt++) { + (*preIt)->invoke(); + } + } // end if first move command + + // move file + int ret = system(systemBuf); + if (ret == 0) + { + ArLog::log(ArLog::Verbose, + "ArTempDirectoryHelper: Moved file %s (with %s)", + sourceFileName.c_str(), + systemBuf); + + if (iter == fileNameList.begin()) { + isSuccess = true; + } + } + else // error moving file + { + ArLog::log(ArLog::Normal, + "ArTempDirectoryHelper: Couldn't move %s (ret of '%s' is %d) removing file", + sourceFileName.c_str(), + systemBuf, + ret); + + unlink(fromBuf); + if (iter == fileNameList.begin()) { + isSuccess = false; + } + } // end else error moving file + } // end for each file + + // If files were moved, then call the post move callbacks + if (!isFirstMoveCmd) { + for (std::list<ArFunctor *>::iterator postIt = myPostMoveCallbacks.begin(); + postIt != myPostMoveCallbacks.end(); + postIt++) { + (*postIt)->invoke(); + } + } + + } // end if files need to be moved + + return isSuccess; + +} // end method moveFilesToBaseDirectory + + +AREXPORT std::string ArTempDirectoryHelper::makeTempFilePathName + (const char *fileName) +{ + return makeFilePathName(fileName, + myTempDirectory.c_str()); +} + +AREXPORT std::string ArTempDirectoryHelper::makeBaseFilePathName + (const char *fileName) +{ + return makeFilePathName(fileName, + myBaseDirectory.c_str()); +} + +AREXPORT std::string ArTempDirectoryHelper::makeFilePathName + (const char *fileName, + const char *dirName) +{ + + if (ArUtil::isStrEmpty(fileName)) { + return ""; + } + + std::string filePathName; + + if ((!ArUtil::isStrEmpty(dirName)) && + (fileName[0] != '/') && + (fileName[0] != '\\') ) { + filePathName = myTempDirectory; + filePathName += fileName; + } + else { + filePathName = fileName; + } + + return filePathName; + +} // end method makeFilePathName + + +AREXPORT void ArTempDirectoryHelper::addPreMoveCallback( + ArFunctor *functor, ArListPos::Pos position) +{ + if (position == ArListPos::FIRST) + myPreMoveCallbacks.push_front(functor); + else if (position == ArListPos::LAST) + myPreMoveCallbacks.push_back(functor); + else + ArLog::log(ArLog::Terse, + "ArTempDirectoryHelper::addPreMoveCallback: Invalid position."); +} + + +AREXPORT void ArTempDirectoryHelper::remPreMoveCallback( + ArFunctor *functor) +{ + myPreMoveCallbacks.remove(functor); +} + + +AREXPORT void ArTempDirectoryHelper::addPostMoveCallback( + ArFunctor *functor, ArListPos::Pos position) +{ + if (position == ArListPos::FIRST) + myPostMoveCallbacks.push_front(functor); + else if (position == ArListPos::LAST) + myPostMoveCallbacks.push_back(functor); + else + ArLog::log(ArLog::Terse, + "ArTempDirectoryHelper::addPostMoveCallback: Invalid position."); +} + + +AREXPORT void ArTempDirectoryHelper::remPostMoveCallback( + ArFunctor *functor) +{ + myPostMoveCallbacks.remove(functor); +} + diff --git a/Legacy/Aria/ArNetworking/src/md5.cpp b/Legacy/Aria/ArNetworking/src/md5.cpp new file mode 100644 index 0000000..b5e5f9e --- /dev/null +++ b/Legacy/Aria/ArNetworking/src/md5.cpp @@ -0,0 +1,390 @@ +/* + MPL (ActivMedia) renamed to a cpp file + +*/ + +/* RH (ActivMedia/MobileRobots) including header from ARIA which defines AREXPORT to export + functions from Windows DLLs, and added AREXPORT to functions defined below: +*/ +#include "ArExport.h" + +/* + Copyright (C) 1999, 2000, 2002 Aladdin Enterprises. All rights reserved. + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + L. Peter Deutsch + ghost@aladdin.com + + */ +/* + Independent implementation of MD5 (RFC 1321). + + This code implements the MD5 Algorithm defined in RFC 1321, whose + text is available at + http://www.ietf.org/rfc/rfc1321.txt + The code is derived from the text of the RFC, including the test suite + (section A.5) but excluding the rest of Appendix A. It does not include + any code or documentation that is identified in the RFC as being + copyrighted. + + The original and principal author of md5.c is L. Peter Deutsch + <ghost@aladdin.com>. Other authors are noted in the change history + that follows (in reverse chronological order): + + 2002-04-13 lpd Clarified derivation from RFC 1321; now handles byte order + either statically or dynamically; added missing #include <string.h> + in library. + 2002-03-11 lpd Corrected argument list for main(), and added int return + type, in test program and T value program. + 2002-02-21 lpd Added missing #include <stdio.h> in test program. + 2000-07-03 lpd Patched to eliminate warnings about "constant is + unsigned in ANSI C, signed in traditional"; made test program + self-checking. + 1999-11-04 lpd Edited comments slightly for automatic TOC extraction. + 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5). + 1999-05-03 lpd Original version. + */ + +#include "md5.h" +#include <string.h> + +#undef BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown */ +#ifdef ARCH_IS_BIG_ENDIAN +# define BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1) +#else +# define BYTE_ORDER 0 +#endif + +#define T_MASK ((md5_word_t)~0) +#define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87) +#define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9) +#define T3 0x242070db +#define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111) +#define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050) +#define T6 0x4787c62a +#define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec) +#define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe) +#define T9 0x698098d8 +#define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850) +#define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e) +#define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841) +#define T13 0x6b901122 +#define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c) +#define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71) +#define T16 0x49b40821 +#define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d) +#define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf) +#define T19 0x265e5a51 +#define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855) +#define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2) +#define T22 0x02441453 +#define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e) +#define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437) +#define T25 0x21e1cde6 +#define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829) +#define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278) +#define T28 0x455a14ed +#define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa) +#define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07) +#define T31 0x676f02d9 +#define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375) +#define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd) +#define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e) +#define T35 0x6d9d6122 +#define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3) +#define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb) +#define T38 0x4bdecfa9 +#define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f) +#define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f) +#define T41 0x289b7ec6 +#define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805) +#define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a) +#define T44 0x04881d05 +#define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6) +#define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a) +#define T47 0x1fa27cf8 +#define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a) +#define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb) +#define T50 0x432aff97 +#define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58) +#define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6) +#define T53 0x655b59c3 +#define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d) +#define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82) +#define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e) +#define T57 0x6fa87e4f +#define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f) +#define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb) +#define T60 0x4e0811a1 +#define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d) +#define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca) +#define T63 0x2ad7d2bb +#define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e) + + +static void +md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/) +{ + md5_word_t + a = pms->abcd[0], b = pms->abcd[1], + c = pms->abcd[2], d = pms->abcd[3]; + md5_word_t t; +#if BYTE_ORDER > 0 + /* Define storage only for big-endian CPUs. */ + md5_word_t X[16]; +#else + /* Define storage for little-endian or both types of CPUs. */ + md5_word_t xbuf[16]; + const md5_word_t *X; +#endif + + { +#if BYTE_ORDER == 0 + /* + * Determine dynamically whether this is a big-endian or + * little-endian machine, since we can use a more efficient + * algorithm on the latter. + */ + static const int w = 1; + + if (*((const md5_byte_t *)&w)) /* dynamic little-endian */ +#endif +#if BYTE_ORDER <= 0 /* little-endian */ + { + /* + * On little-endian machines, we can process properly aligned + * data without copying it. + */ + if (!((data - (const md5_byte_t *)0) & 3)) { + /* data are properly aligned */ + X = (const md5_word_t *)data; + } else { + /* not aligned */ + memcpy(xbuf, data, 64); + X = xbuf; + } + } +#endif +#if BYTE_ORDER == 0 + else /* dynamic big-endian */ +#endif +#if BYTE_ORDER >= 0 /* big-endian */ + { + /* + * On big-endian machines, we must arrange the bytes in the + * right order. + */ + const md5_byte_t *xp = data; + int i; + +# if BYTE_ORDER == 0 + X = xbuf; /* (dynamic only) */ +# else +# define xbuf X /* (static only) */ +# endif + for (i = 0; i < 16; ++i, xp += 4) + xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24); + } +#endif + } + +#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) + + /* Round 1. */ + /* Let [abcd k s i] denote the operation + a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */ +#define F(x, y, z) (((x) & (y)) | (~(x) & (z))) +#define SET(a, b, c, d, k, s, Ti)\ + t = a + F(b,c,d) + X[k] + Ti;\ + a = ROTATE_LEFT(t, s) + b + /* Do the following 16 operations. */ + SET(a, b, c, d, 0, 7, T1); + SET(d, a, b, c, 1, 12, T2); + SET(c, d, a, b, 2, 17, T3); + SET(b, c, d, a, 3, 22, T4); + SET(a, b, c, d, 4, 7, T5); + SET(d, a, b, c, 5, 12, T6); + SET(c, d, a, b, 6, 17, T7); + SET(b, c, d, a, 7, 22, T8); + SET(a, b, c, d, 8, 7, T9); + SET(d, a, b, c, 9, 12, T10); + SET(c, d, a, b, 10, 17, T11); + SET(b, c, d, a, 11, 22, T12); + SET(a, b, c, d, 12, 7, T13); + SET(d, a, b, c, 13, 12, T14); + SET(c, d, a, b, 14, 17, T15); + SET(b, c, d, a, 15, 22, T16); +#undef SET + + /* Round 2. */ + /* Let [abcd k s i] denote the operation + a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */ +#define G(x, y, z) (((x) & (z)) | ((y) & ~(z))) +#define SET(a, b, c, d, k, s, Ti)\ + t = a + G(b,c,d) + X[k] + Ti;\ + a = ROTATE_LEFT(t, s) + b + /* Do the following 16 operations. */ + SET(a, b, c, d, 1, 5, T17); + SET(d, a, b, c, 6, 9, T18); + SET(c, d, a, b, 11, 14, T19); + SET(b, c, d, a, 0, 20, T20); + SET(a, b, c, d, 5, 5, T21); + SET(d, a, b, c, 10, 9, T22); + SET(c, d, a, b, 15, 14, T23); + SET(b, c, d, a, 4, 20, T24); + SET(a, b, c, d, 9, 5, T25); + SET(d, a, b, c, 14, 9, T26); + SET(c, d, a, b, 3, 14, T27); + SET(b, c, d, a, 8, 20, T28); + SET(a, b, c, d, 13, 5, T29); + SET(d, a, b, c, 2, 9, T30); + SET(c, d, a, b, 7, 14, T31); + SET(b, c, d, a, 12, 20, T32); +#undef SET + + /* Round 3. */ + /* Let [abcd k s t] denote the operation + a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */ +#define H(x, y, z) ((x) ^ (y) ^ (z)) +#define SET(a, b, c, d, k, s, Ti)\ + t = a + H(b,c,d) + X[k] + Ti;\ + a = ROTATE_LEFT(t, s) + b + /* Do the following 16 operations. */ + SET(a, b, c, d, 5, 4, T33); + SET(d, a, b, c, 8, 11, T34); + SET(c, d, a, b, 11, 16, T35); + SET(b, c, d, a, 14, 23, T36); + SET(a, b, c, d, 1, 4, T37); + SET(d, a, b, c, 4, 11, T38); + SET(c, d, a, b, 7, 16, T39); + SET(b, c, d, a, 10, 23, T40); + SET(a, b, c, d, 13, 4, T41); + SET(d, a, b, c, 0, 11, T42); + SET(c, d, a, b, 3, 16, T43); + SET(b, c, d, a, 6, 23, T44); + SET(a, b, c, d, 9, 4, T45); + SET(d, a, b, c, 12, 11, T46); + SET(c, d, a, b, 15, 16, T47); + SET(b, c, d, a, 2, 23, T48); +#undef SET + + /* Round 4. */ + /* Let [abcd k s t] denote the operation + a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */ +#define I(x, y, z) ((y) ^ ((x) | ~(z))) +#define SET(a, b, c, d, k, s, Ti)\ + t = a + I(b,c,d) + X[k] + Ti;\ + a = ROTATE_LEFT(t, s) + b + /* Do the following 16 operations. */ + SET(a, b, c, d, 0, 6, T49); + SET(d, a, b, c, 7, 10, T50); + SET(c, d, a, b, 14, 15, T51); + SET(b, c, d, a, 5, 21, T52); + SET(a, b, c, d, 12, 6, T53); + SET(d, a, b, c, 3, 10, T54); + SET(c, d, a, b, 10, 15, T55); + SET(b, c, d, a, 1, 21, T56); + SET(a, b, c, d, 8, 6, T57); + SET(d, a, b, c, 15, 10, T58); + SET(c, d, a, b, 6, 15, T59); + SET(b, c, d, a, 13, 21, T60); + SET(a, b, c, d, 4, 6, T61); + SET(d, a, b, c, 11, 10, T62); + SET(c, d, a, b, 2, 15, T63); + SET(b, c, d, a, 9, 21, T64); +#undef SET + + /* Then perform the following additions. (That is increment each + of the four registers by the value it had before this block + was started.) */ + pms->abcd[0] += a; + pms->abcd[1] += b; + pms->abcd[2] += c; + pms->abcd[3] += d; +} + +AREXPORT void +md5_init(md5_state_t *pms) +{ + pms->count[0] = pms->count[1] = 0; + pms->abcd[0] = 0x67452301; + pms->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476; + pms->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301; + pms->abcd[3] = 0x10325476; +} + +AREXPORT void +md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes) +{ + const md5_byte_t *p = data; + int left = nbytes; + int offset = (pms->count[0] >> 3) & 63; + md5_word_t nbits = (md5_word_t)(nbytes << 3); + + if (nbytes <= 0) + return; + + /* Update the message length. */ + pms->count[1] += nbytes >> 29; + pms->count[0] += nbits; + if (pms->count[0] < nbits) + pms->count[1]++; + + /* Process an initial partial block. */ + if (offset) { + int copy = (offset + nbytes > 64 ? 64 - offset : nbytes); + + memcpy(pms->buf + offset, p, copy); + if (offset + copy < 64) + return; + p += copy; + left -= copy; + md5_process(pms, pms->buf); + } + + /* Process full blocks. */ + for (; left >= 64; p += 64, left -= 64) + md5_process(pms, p); + + /* Process a final partial block. */ + if (left) + memcpy(pms->buf, p, left); +} + +AREXPORT void +md5_finish(md5_state_t *pms, md5_byte_t digest[16]) +{ + static const md5_byte_t pad[64] = { + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + md5_byte_t data[8]; + int i; + + /* Save the length before padding. */ + for (i = 0; i < 8; ++i) + data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3)); + /* Pad to 56 bytes mod 64. */ + md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1); + /* Append the length. */ + md5_append(pms, data, 8); + for (i = 0; i < 16; ++i) + digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3)); +} diff --git a/Legacy/Aria/ArNetworking/tests/Makefile b/Legacy/Aria/ArNetworking/tests/Makefile new file mode 100644 index 0000000..83d812d --- /dev/null +++ b/Legacy/Aria/ArNetworking/tests/Makefile @@ -0,0 +1,9 @@ + +.PHONY: all + +all: + $(MAKE) -C .. tests + +%: %.cpp + $(MAKE) -C .. tests/$@ + diff --git a/Legacy/Aria/ArNetworking/tests/baseTest.cpp b/Legacy/Aria/ArNetworking/tests/baseTest.cpp new file mode 100644 index 0000000..e875b1f --- /dev/null +++ b/Legacy/Aria/ArNetworking/tests/baseTest.cpp @@ -0,0 +1,62 @@ +#include "Aria.h" +#include "ArNetworking.h" + + + + +/* Key handler for the escape key: shutdown all of Aria. */ +void escape(void) +{ + printf("esc pressed, shutting down aria\n"); + Aria::shutdown(); +} + +int main(int argc, char **argv) +{ + Aria::init(); + + ArClientBase client; + + ArArgumentParser parser(&argc, argv); + + ArClientSimpleConnector clientConnector(&parser); + + parser.loadDefaultArguments(); + + if (!Aria::parseArgs() || !parser.checkHelpAndWarnUnparsed()) + { + Aria::logOptions(); + exit(0); + } + + if (!clientConnector.connectClient(&client)) + { + if (client.wasRejected()) + printf("Server '%s' rejected connection, exiting\n", client.getHost()); + else + printf("Could not connect to server '%s', exiting\n", client.getHost()); + exit(1); + } + + printf("Connected to server.\n"); + + + /* Create a key handler and also tell Aria about it */ + ArKeyHandler keyHandler; + Aria::setKeyHandler(&keyHandler); + + /* Global escape-key handler to shut everythnig down */ + ArGlobalFunctor escapeCB(&escape); + keyHandler.addKeyHandler(ArKeyHandler::ESCAPE, &escapeCB); + + client.runAsync(); + + while (client.getRunningWithLock()) + { + keyHandler.checkKeys(); + ArUtil::sleep(100); + } + + Aria::shutdown(); + return 0; +} diff --git a/Legacy/Aria/ArNetworking/tests/cameraModeClient.cpp b/Legacy/Aria/ArNetworking/tests/cameraModeClient.cpp new file mode 100644 index 0000000..8a454bd --- /dev/null +++ b/Legacy/Aria/ArNetworking/tests/cameraModeClient.cpp @@ -0,0 +1,85 @@ +#include "Aria.h" +#include "ArNetworking.h" + +void getCameraModeList(ArNetPacket *packet) +{ + ArTypes::UByte2 numModes; + + numModes = packet->bufToUByte2(); + + printf("%d camera modes:\n", numModes); + char modeName[512]; + for (int i = 0; i < numModes; i++) + { + packet->bufToStr(modeName, sizeof(modeName)); + printf("\t%s\n", modeName); + } +} + +void cameraModeUpdated(ArNetPacket *packet) +{ + char modeName[512]; + packet->bufToStr(modeName, sizeof(modeName)); + printf("Switched to mode %s\n", modeName); +} + +int main(int argc, char **argv) +{ + Aria::init(); + ArClientBase client; + std::string host; + + + ArArgumentParser parser(&argc, argv); + ArClientSimpleConnector clientConnector(&parser); + + parser.loadDefaultArguments(); + + /* Check for -help, and unhandled arguments: */ + if (!clientConnector.parseArgs() || !parser.checkHelpAndWarnUnparsed()) + { + clientConnector.logOptions(); + exit(0); + } + + + /* Connect our client object to the remote server: */ + if (!clientConnector.connectClient(&client)) + { + if (client.wasRejected()) + printf("Server rejected connection, exiting\n"); + else + printf("Could not connect to server, exiting\n"); + exit(1); + } + + + client.addHandler("getCameraModeListCam1", + new ArGlobalFunctor1<ArNetPacket *>(&getCameraModeList)); + + client.requestOnce("getCameraModeListCam1"); + + ArNetPacket sending; + + // This does the look at goal mode + sending.empty(); + sending.strToBuf("lookAtGoal"); + client.requestOnce("setCameraModeCam1", &sending); + + // This does the look at point mode (at 0 0); + + sending.empty(); + sending.strToBuf("lookAtPoint"); + sending.byte4ToBuf(1157); + sending.byte4ToBuf(-15786); + client.requestOnce("setCameraModeCam1", &sending); + + while (Aria::getRunning() && client.isConnected()) + { + client.loopOnce(); + ArUtil::sleep(1000); + } + Aria::shutdown(); + return 0; + +}; diff --git a/Legacy/Aria/ArNetworking/tests/clientLoadMap.cpp b/Legacy/Aria/ArNetworking/tests/clientLoadMap.cpp new file mode 100644 index 0000000..9690c33 --- /dev/null +++ b/Legacy/Aria/ArNetworking/tests/clientLoadMap.cpp @@ -0,0 +1,52 @@ +#include "Aria.h" +#include "ArNetworking.h" + +int main(int argc, char **argv) +{ + Aria::init(); + //ArLog::init(ArLog::StdOut, ArLog::Verbose); + ArClientBase client; + + ArArgumentParser parser(&argc, argv); + + ArClientSimpleConnector clientConnector(&parser); + parser.loadDefaultArguments(); + + if (!clientConnector.parseArgs() || !parser.checkHelpAndWarnUnparsed()) + { + clientConnector.logOptions(); + exit(0); + } + + if (!clientConnector.connectClient(&client)) + { + if (client.wasRejected()) + printf("Server '%s' rejected connection, exiting\n", client.getHost()); + else + printf("Could not connect to server '%s', exiting\n", client.getHost()); + exit(1); + } + client.runAsync(); + + ArNetPacket sending; + // We have to tell it what section we're sending + sending.strToBuf("Section"); + // The map is in the files section + sending.strToBuf("Files"); + // The parameter name + sending.strToBuf("Map"); + // The value of the parameter + sending.strToBuf("entire2.map"); + + // you could put in however many of these you want... + + client.requestOnce("setConfig", &sending); + + // you have to give the client some time to send the command + ArUtil::sleep(500); + + + Aria::shutdown(); + return 0; +} + diff --git a/Legacy/Aria/ArNetworking/tests/clientLocalizeToPose.cpp b/Legacy/Aria/ArNetworking/tests/clientLocalizeToPose.cpp new file mode 100644 index 0000000..dbe1c39 --- /dev/null +++ b/Legacy/Aria/ArNetworking/tests/clientLocalizeToPose.cpp @@ -0,0 +1,56 @@ +#include "Aria.h" +#include "ArNetworking.h" + +int main(int argc, char **argv) +{ + Aria::init(); + //ArLog::init(ArLog::StdOut, ArLog::Verbose); + ArClientBase client; + + ArArgumentParser parser(&argc, argv); + + ArClientSimpleConnector clientConnector(&parser); + parser.loadDefaultArguments(); + + if (!clientConnector.parseArgs() || !parser.checkHelpAndWarnUnparsed()) + { + clientConnector.logOptions(); + exit(0); + } + + if (parser.getArgc() < 4 || parser.getArgc() > 6) + { + printf("usage: %s <x> <y> <th> <optional:xyspread> <optional:thspread>", argv[0]); + exit(1); + } + + if (!clientConnector.connectClient(&client)) + { + if (client.wasRejected()) + printf("Server '%s' rejected connection, exiting\n", client.getHost()); + else + printf("Could not connect to server '%s', exiting\n", client.getHost()); + exit(1); + } + client.runAsync(); + + ArNetPacket sending; + // put in the arguments (you can see what they are from doing -lcl on clientDemo) + sending.byte4ToBuf(atoi(parser.getArg(1))); + sending.byte4ToBuf(atoi(parser.getArg(2))); + sending.byte4ToBuf(atoi(parser.getArg(3))); + if (parser.getArgc() > 4) + sending.uByte4ToBuf(atoi(parser.getArg(4))); + if (parser.getArgc() > 5) + sending.uByte4ToBuf(atoi(parser.getArg(5))); + // send the packet + client.requestOnce("localizeToPose", &sending); + + // you have to give the client some time to send the command + ArUtil::sleep(500); + + + Aria::shutdown(); + return 0; +} + diff --git a/Legacy/Aria/ArNetworking/tests/clientPatrol.cpp b/Legacy/Aria/ArNetworking/tests/clientPatrol.cpp new file mode 100644 index 0000000..2e0b48d --- /dev/null +++ b/Legacy/Aria/ArNetworking/tests/clientPatrol.cpp @@ -0,0 +1,50 @@ +#include "Aria.h" +#include "ArNetworking.h" + +int main(int argc, char **argv) +{ + Aria::init(); + //ArLog::init(ArLog::StdOut, ArLog::Verbose); + ArClientBase client; + + ArArgumentParser parser(&argc, argv); + + ArClientSimpleConnector clientConnector(&parser); + parser.loadDefaultArguments(); + + if (!clientConnector.parseArgs() || !parser.checkHelpAndWarnUnparsed()) + { + clientConnector.logOptions(); + exit(0); + } + + if (!clientConnector.connectClient(&client)) + { + if (client.wasRejected()) + printf("Server '%s' rejected connection, exiting\n", client.getHost()); + else + printf("Could not connect to server '%s', exiting\n", client.getHost()); + exit(1); + } + client.runAsync(); + + ArNetPacket sending; + // We have to tell it what route we want to patrol + sending.strToBuf("hallways"); + // tell it how much many times we want to patrol (<= 0 == forever) + sending.byte4ToBuf(0); + + client.requestOnce("patrolRouteCount", &sending); + + // note that there's also another call (patrol) that just has it always + // patrol forever but this gives you more options and is only + // slightly more complicated (just give it that byte4) + + // you have to give the client some time to send the command + ArUtil::sleep(500); + + + Aria::shutdown(); + return 0; +} + diff --git a/Legacy/Aria/ArNetworking/tests/clientTest.vcproj b/Legacy/Aria/ArNetworking/tests/clientTest.vcproj new file mode 100644 index 0000000..a9d0308 --- /dev/null +++ b/Legacy/Aria/ArNetworking/tests/clientTest.vcproj @@ -0,0 +1,176 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="7.10" + Name="clientTest" + SccProjectName="" + SccLocalPath=""> + <Platforms> + <Platform + Name="Win32"/> + </Platforms> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory=".\../../bin" + IntermediateDirectory=".\../../obj" + ConfigurationType="1" + UseOfMFC="0" + ATLMinimizesCRunTimeLibraryUsage="FALSE" + CharacterSet="2"> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="..\include,..\..\include" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + PrecompiledHeaderFile=".\../../obj/clientTest.pch" + AssemblerListingLocation=".\../../obj/" + ObjectFile=".\../../obj/" + ProgramDataBaseFileName=".\../../obj/" + BrowseInformation="1" + WarningLevel="3" + SuppressStartupBanner="TRUE" + DebugInformationFormat="3" + CompileAs="0"/> + <Tool + Name="VCCustomBuildTool"/> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="Aria.lib ArNetworking.lib odbc32.lib odbccp32.lib" + OutputFile=".\../../bin/clientTest.exe" + Version="1.0" + LinkIncremental="2" + SuppressStartupBanner="TRUE" + AdditionalLibraryDirectories="..\..\lib" + GenerateDebugInformation="TRUE" + SubSystem="1" + TargetMachine="1"/> + <Tool + Name="VCMIDLTool" + TypeLibraryName=".\../../bin/clientTest.tlb" + HeaderFileName=""/> + <Tool + Name="VCPostBuildEventTool"/> + <Tool + Name="VCPreBuildEventTool"/> + <Tool + Name="VCPreLinkEventTool"/> + <Tool + Name="VCResourceCompilerTool" + PreprocessorDefinitions="_DEBUG" + Culture="1033"/> + <Tool + Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCWebDeploymentTool"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory=".\../../bin" + IntermediateDirectory=".\../../obj" + ConfigurationType="1" + UseOfMFC="0" + ATLMinimizesCRunTimeLibraryUsage="FALSE" + CharacterSet="2"> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + InlineFunctionExpansion="1" + AdditionalIncludeDirectories="..\include,..\..\include" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" + StringPooling="TRUE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="TRUE" + PrecompiledHeaderFile=".\../../obj/clientTest.pch" + AssemblerListingLocation=".\../../obj/" + ObjectFile=".\../../obj/" + ProgramDataBaseFileName=".\../../obj/" + WarningLevel="3" + SuppressStartupBanner="TRUE" + CompileAs="0"/> + <Tool + Name="VCCustomBuildTool"/> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="Aria.lib odbc32.lib odbccp32.lib" + OutputFile=".\../../bin/clientTest.exe" + Version="1.0" + LinkIncremental="1" + SuppressStartupBanner="TRUE" + AdditionalLibraryDirectories="..\..\lib" + SubSystem="1" + TargetMachine="1"/> + <Tool + Name="VCMIDLTool" + TypeLibraryName=".\../../bin/clientTest.tlb" + HeaderFileName=""/> + <Tool + Name="VCPostBuildEventTool"/> + <Tool + Name="VCPreBuildEventTool"/> + <Tool + Name="VCPreLinkEventTool"/> + <Tool + Name="VCResourceCompilerTool" + PreprocessorDefinitions="NDEBUG" + Culture="1033"/> + <Tool + Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCWebDeploymentTool"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"> + <File + RelativePath="clientTest.cpp"> + <FileConfiguration + Name="Debug|Win32"> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="" + PreprocessorDefinitions="" + BasicRuntimeChecks="3" + BrowseInformation="1"/> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32"> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + AdditionalIncludeDirectories="" + PreprocessorDefinitions=""/> + </FileConfiguration> + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl"> + </Filter> + <Filter + Name="Resource Files" + Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"> + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/Legacy/Aria/ArNetworking/tests/commandTestClient.cpp b/Legacy/Aria/ArNetworking/tests/commandTestClient.cpp new file mode 100644 index 0000000..86ea48b --- /dev/null +++ b/Legacy/Aria/ArNetworking/tests/commandTestClient.cpp @@ -0,0 +1,94 @@ +#include "Aria.h" +#include "ArNetworking.h" + +ArClientBase client; + +void commandList(ArNetPacket *packet) +{ + char name[512]; + char description[512]; + int numCommands; + int i; + + numCommands = packet->bufToByte2(); + printf("%d commands\n", numCommands); + for (i = 0; i < numCommands; i++) + { + packet->bufToStr(name, sizeof(name)); + packet->bufToStr(description, sizeof(description)); + printf("%-20s%s\n", name, description); + client.requestOnce(name); + } + +} + +void stringCommandList(ArNetPacket *packet) +{ + char name[512]; + char description[512]; + int numCommands; + int i; + char buf[512]; + + numCommands = packet->bufToByte2(); + printf("%d string commands\n", numCommands); + for (i = 0; i < numCommands; i++) + { + packet->bufToStr(name, sizeof(name)); + packet->bufToStr(description, sizeof(description)); + printf("%-20s%s\n", name, description); + sprintf(buf, "%ld some random fun string %ld", ArMath::random(), + ArMath::random()); + client.requestOnceWithString(name, buf); + } + +} + + + +int main(int argc, char **argv) +{ + + std::string hostname; + Aria::init(); + //ArLog::init(ArLog::StdOut, ArLog::Verbose); + + if (argc == 1) + hostname = "localhost"; + else + hostname = argv[1]; + if (!client.blockingConnect(hostname.c_str(), 7272)) + { + printf("Could not connect to server, exiting\n"); + exit(1); + } + ArGlobalFunctor1<ArNetPacket *> commandCB(&commandList); + ArGlobalFunctor1<ArNetPacket *> stringCommandCB(&stringCommandList); + client.addHandler("listCommands", &commandCB); + client.addHandler("listStringCommands", &stringCommandCB); + client.requestOnce("listCommands"); + client.requestOnce("listStringCommands"); + /* + client.requestOnce("Function1"); + client.requestOnce("Function2"); + client.requestOnce("Function3"); + client.requestOnce("Function1"); + client.requestOnceWithString("StringFunction4", "Some string!"); + client.requestOnceWithString("StringFunction5", "funfunfun"); + client.requestOnceWithString("StringFunction6", "six"); + client.requestOnceWithString("StringFunction4", "Some other string!"); + */ + client.runAsync(); + while (client.getRunningWithLock()) + { + ArUtil::sleep(1); + //printf("%d ms since last data\n", client.getLastPacketReceived().mSecSince()); + } + Aria::shutdown(); + return 0; + +} + + + + diff --git a/Legacy/Aria/ArNetworking/tests/commandTestServer.cpp b/Legacy/Aria/ArNetworking/tests/commandTestServer.cpp new file mode 100644 index 0000000..3140b79 --- /dev/null +++ b/Legacy/Aria/ArNetworking/tests/commandTestServer.cpp @@ -0,0 +1,67 @@ +#include "Aria.h" +#include "ArNetworking.h" + +void function1(void) +{ + printf("Function1 called\n"); +} + +void function2(void) +{ + printf("Function2 called\n"); +} + +void function3(void) +{ + printf("Function3 called\n"); +} + +void function4(ArArgumentBuilder *arg) +{ + printf("Function4 called with string '%s'\n", arg->getFullString()); +} + +void function5(ArArgumentBuilder *arg) +{ + printf("Function5 called with string '%s'\n", arg->getFullString()); +} + +void function6(ArArgumentBuilder *arg) +{ + printf("Function6 called with string '%s'\n", arg->getFullString()); +} + + +int main(int argc, char **argv) +{ + Aria::init(); + ArServerBase server; + + if (!server.open(7272)) + { + printf("Could not open server port\n"); + exit(1); + } + + ArServerHandlerCommands commands(&server); + commands.addCommand("Function1", "Call the function that is number 1!", + new ArGlobalFunctor(&function1)); + commands.addCommand("Function2", "Second function to call", + new ArGlobalFunctor(&function2)); + commands.addCommand("Function3", "Tree climb", + new ArGlobalFunctor(&function3)); + commands.addStringCommand("StringFunction4", + "Print a string in function 4", + new ArGlobalFunctor1< + ArArgumentBuilder *>(&function4)); + commands.addStringCommand("StringFunction5", + "Prints a string given (5)", + new ArGlobalFunctor1< + ArArgumentBuilder *>(&function5)); + commands.addStringCommand("StringFunction6", + "Print out a value for function 6", + new ArGlobalFunctor1< + ArArgumentBuilder *>(&function6)); + + server.run(); +} diff --git a/Legacy/Aria/ArNetworking/tests/fileClient.cpp b/Legacy/Aria/ArNetworking/tests/fileClient.cpp new file mode 100644 index 0000000..c1a18ed --- /dev/null +++ b/Legacy/Aria/ArNetworking/tests/fileClient.cpp @@ -0,0 +1,217 @@ +#include "Aria.h" +#include "ArNetworking.h" + +ArClientFileLister *fileLister; +ArClientFileToClient *fileToClient; +ArClientFileFromClient *fileFromClient; +ArClientDeleteFileOnServer *deleteFileOnServer; + +bool done = false; + +void updated(int ret) +{ + done = true; + if (ret == 0) + fileLister->log(false); + else + printf("Bad update %d\n", ret); +} + +void fileReceived(int ret) +{ + done = true; + if (ret == 0) + printf("Got file '%s'\n", fileToClient->getFileName()); + else + printf("Didn't get file '%s' because %d\n", fileToClient->getFileName(), + ret); +} + +void fileSent(int ret) +{ + done = true; + if (ret == 0) + printf("Sent file '%s'\n", fileFromClient->getFileName()); + else + printf("Didn't send file '%s' because %d\n", + fileFromClient->getFileName(), + ret); +} + +void fileDeleted(int ret) +{ + done = true; + if (ret == 0) + printf("Deleted file '%s'\n", deleteFileOnServer->getFileName()); + else + printf("Didn't delete file '%s' because %d\n", + deleteFileOnServer->getFileName(), + ret); +} + +void waitForDone(void) +{ + while (!done && Aria::getRunning()) + ArUtil::sleep(1); + done = false; +} + +int main(int argc, char **argv) +{ + std::string hostname; + Aria::init(); + //ArLog::init(ArLog::StdOut, ArLog::Verbose); + ArClientBase client; + + + ArArgumentParser parser(&argc, argv); + + ArClientSimpleConnector clientConnector(&parser); + + parser.loadDefaultArguments(); + + /* Check for -help, and unhandled arguments: */ + if (!Aria::parseArgs() || !parser.checkHelpAndWarnUnparsed()) + { + Aria::logOptions(); + exit(0); + } + + /* Connect our client object to the remote server: */ + if (!clientConnector.connectClient(&client)) + { + if (client.wasRejected()) + printf("Server '%s' rejected connection, exiting\n", client.getHost()); + else + printf("Could not connect to server '%s', exiting\n", client.getHost()); + exit(1); + } + + fileLister = new ArClientFileLister(&client); + fileLister->addUpdatedCallback(new ArGlobalFunctor1<int>(&updated)); + + fileToClient = new ArClientFileToClient(&client); + fileToClient->addFileReceivedCallback( + new ArGlobalFunctor1<int>(&fileReceived)); + + fileFromClient = new ArClientFileFromClient(&client); + fileFromClient->addFileSentCallback( + new ArGlobalFunctor1<int>(&fileSent)); + + deleteFileOnServer = new ArClientDeleteFileOnServer(&client); + deleteFileOnServer->addFileDeletedCallback( + new ArGlobalFunctor1<int>(&fileDeleted)); + + client.runAsync(); + + /* + if (deleteFileOnServer->deleteFileFromDirectory(NULL, "all.bob")) + waitForDone(); + else + printf("Error deleting file\n"); + + if (deleteFileOnServer->deleteFileFromDirectory("1", "all.bob")) + waitForDone(); + else + printf("Error deleting file\n"); + + if (deleteFileOnServer->deleteFileFromDirectory("1/3", "all.bob")) + waitForDone(); + else + printf("Error deleting file\n"); + + + if (deleteFileOnServer->deleteFileFromDirectory("fun", "all.bob")) + waitForDone(); + else + printf("Error deleting file\n"); + + if (deleteFileOnServer->deleteFileFromDirectory("argh", "all.bob")) + waitForDone(); + else + printf("Error deleting file\n"); + */ + + /* + done = false; + if (fileFromClient->putFileToDirectory("argh", "png", "app_logo.png", ArClientFileFromClient::SPEED_SLOW)) + waitForDone(); + else + printf("Error before sending file\n"); + */ + done = false; + if (fileFromClient->putFileToDirectory(NULL, "dox", "doxygen.conf", ArClientFileFromClient::SPEED_SLOW)) + waitForDone(); + else + printf("Error before sending file\n"); + + +/* + done = false; + if (fileFromClient->putFileToDirectory("argh", "png", "app_logo.png") + waitForDone(); + else + printf("Error before sending file\n"); + + done = false; + if (fileFromClient->putFileToDirectory(NULL, "dox", "doxygen.conf") + waitForDone(); + else + printf("Error before sending file\n"); +*/ +/* + fileLister->changeToTopDir(); + waitForDone(); + fileLister->changeToDir("argh"); + waitForDone(); + fileLister->log(true); + + fileToClient->getFileFromDirectory("argh\\um", "doxygen", "slashes"); + waitForDone(); + fileToClient->getFileFromDirectory("argh", "DOXYGEN.Conf", "blah.um.2"); + waitForDone(); + fileToClient->getFileFromDirectory("argh", "wehlkjadsf", "blah.um.2"); + waitForDone(); + fileToClient->getFileFromDirectory("argh", "1", "blah.um"); + waitForDone(); + fileToClient->getFileFromDirectory(NULL, "1", "blah.um.2"); + waitForDone(); + */ + /* + fileToClient->getFileFromDirectory(NULL, "all.map", "all.map.2"); + waitForDone(); + + fileToClient->getFileFromDirectory(NULL, "um.map", "all.map.2"); + waitForDone(); + + fileToClient->getFileFromDirectory(NULL, "all.map", "all.map.3"); + waitForDone(); + + fileToClient->getFileFromDirectory(NULL, "configClient.txt", "something"); + waitForDone(); + + */ + + /* + fileLister->changeToTopDir(); + waitForDone(); + fileLister->changeToDir("0level"); + waitForDone(); + fileLister->changeToDir("1level"); + waitForDone(); + fileLister->upOneDir(); + waitForDone(); + fileLister->changeToDir("1level2"); + waitForDone(); + */ + + + + Aria::shutdown(); + return 0; + +} + + + + diff --git a/Legacy/Aria/ArNetworking/tests/fileClientRaw.cpp b/Legacy/Aria/ArNetworking/tests/fileClientRaw.cpp new file mode 100644 index 0000000..5dd0ee2 --- /dev/null +++ b/Legacy/Aria/ArNetworking/tests/fileClientRaw.cpp @@ -0,0 +1,228 @@ +#include "Aria.h" +#include "ArNetworking.h" + +ArClientBase client; + +void getDirListing(ArNetPacket *packet) +{ + char name[2048]; + char directory[2048]; + time_t atime; + time_t mtime; + unsigned int num; + unsigned int ret; + unsigned int i; + + ret = packet->bufToUByte2(); + if (ret != 0) + { + printf("Bad return %d\n", ret); + exit(1); + } + packet->bufToStr(directory, sizeof(directory)); + printf("In directory '%s'\n", directory); + num = packet->bufToUByte2(); + printf("%d directories\n", num); + for (i = 0; i < num; i++) + { + packet->bufToStr(name, sizeof(name)); + atime = packet->bufToUByte4(); + mtime = packet->bufToUByte4(); + printf("\t%s\n", name); + printf("\t\t%s", ctime(&atime)); + printf("\t\t%s", ctime(&mtime)); + } + num = packet->bufToUByte2(); + printf("%d files\n", num); + for (i = 0; i < num; i++) + { + packet->bufToStr(name, sizeof(name)); + atime = packet->bufToUByte4(); + mtime = packet->bufToUByte4(); + printf("\t%s\n", name); + printf("\t\t%s", ctime(&atime)); + printf("\t\t%s", ctime(&mtime)); + } + exit(0); +} + +FILE *file = NULL; + +void netGetFile(ArNetPacket *packet) +{ + int ret; + char fileName[2048]; + ret = packet->bufToUByte2(); + packet->bufToStr(fileName, sizeof(fileName)); + if (ret != 0) + { + printf("Bad return %d on file %s\n", ret, fileName); + exit(1); + } + if (file == NULL) + { + printf("Getting file %s\n", fileName); + if ((file = ArUtil::fopen("fileClientRaw.dump", "w")) == NULL) + { + printf("Can't open fileClientRaw.dump to dump file into\n"); + exit(2); + } + } + ArTypes::UByte4 numBytes; + char buf[32000]; + // file should be good here, so just write into it + numBytes = packet->bufToUByte4(); + if (numBytes == 0) + { + printf("Got all of file %s\n", fileName); + fclose(file); + exit(0); + } + else + { + printf("Got %d bytes of file %s\n", numBytes, fileName); + packet->bufToData(buf, numBytes); + fwrite(buf, 1, numBytes, file); + } +} + +void netPutFile(ArNetPacket *packet) +{ + int ret; + char fileName[2048]; + + ret = packet->bufToUByte2(); + packet->bufToStr(fileName, sizeof(fileName)); + + printf("Ret of '%s' is %d\n", fileName, ret); +} + +void putFile(char *fileName, char *asFileName) +{ + ArNetPacket sendPacket; + size_t ui; + size_t len; + + FILE *file; + if ((file = ArUtil::fopen(fileName, "r")) == NULL) + { + ArLog::log(ArLog::Normal, + "putFile: can't open file '%s'", fileName); + return; + } + + // tell the server we're sending + + sendPacket.empty(); + sendPacket.uByte2ToBuf(0); + sendPacket.strToBuf(asFileName); + client.requestOnce("putFile", &sendPacket); + printf("Starting send of file %s\n", fileName); + + char buf[30000]; + size_t ret; + // now send the file + while ((ret = fread(buf, 1, sizeof(buf), file)) == sizeof(buf)) + { + sendPacket.empty(); + sendPacket.uByte2ToBuf(1); + sendPacket.strToBuf(asFileName); + sendPacket.uByte4ToBuf(ret); + sendPacket.dataToBuf(buf, ret); + client.requestOnce("putFile", &sendPacket); + printf("Sent packet with %d\n", ret); + } + if (ferror(file)) + { + ArLog::log(ArLog::Normal, "ArServerFileToClient: Error sending file %s", + fileName); + sendPacket.empty(); + sendPacket.uByte2ToBuf(3); + sendPacket.strToBuf(asFileName); + client.requestOnce("putFile", &sendPacket); + return; + } + + sendPacket.empty(); + sendPacket.uByte2ToBuf(1); + sendPacket.strToBuf(asFileName); + sendPacket.uByte4ToBuf(ret); + sendPacket.dataToBuf(buf, ret); + client.requestOnce("putFile", &sendPacket); + printf("Sent packet with %d\n", ret); + + + sendPacket.empty(); + sendPacket.uByte2ToBuf(2); + sendPacket.strToBuf(asFileName); + client.requestOnce("putFile", &sendPacket); + + if (feof(file)) + { + ArLog::log(ArLog::Normal, "ArServerFileToClient: Sent file %s", fileName); + } + + fclose(file); +} + +void netDeleteFile(ArNetPacket *packet) +{ + int ret; + char fileName[2048]; + + ret = packet->bufToUByte2(); + packet->bufToStr(fileName, sizeof(fileName)); + + printf("Delete file ret of '%s' is %d\n", fileName, ret); +} + +int main(int argc, char **argv) +{ + + std::string hostname; + Aria::init(); + //ArLog::init(ArLog::StdOut, ArLog::Verbose); + + if (argc == 1) + hostname = "localhost"; + else + hostname = argv[1]; + if (!client.blockingConnect(hostname.c_str(), 7272)) + { + printf("Could not connect to server, exiting\n"); + exit(1); + } + + + /* + ArGlobalFunctor1<ArNetPacket *> getDirListingCB(&getDirListing); + client.addHandler("getDirListing", &getDirListingCB); + //client.requestOnceWithString("getDirListing", ""); + + ArGlobalFunctor1<ArNetPacket *> getFileCB(&netGetFile); + client.addHandler("getFile", &getFileCB); + client.requestOnceWithString("getFile", "all.bob"); + + ArGlobalFunctor1<ArNetPacket *> netPutFileCB(&netPutFile); + client.addHandler("putFile", &netPutFileCB); + putFile("doxygen.conf", "ArGH/DoxYGEN"); + */ + + ArGlobalFunctor1<ArNetPacket *> deleteFileCB(&netDeleteFile); + client.addHandler("deleteFile", &deleteFileCB); + client.requestOnceWithString("deleteFile", "1/all.bob"); + + client.runAsync(); + + while (client.getRunningWithLock()) + { + ArUtil::sleep(1); + } + Aria::shutdown(); + return 0; + +} + + + + diff --git a/Legacy/Aria/ArNetworking/tests/fileServer.cpp b/Legacy/Aria/ArNetworking/tests/fileServer.cpp new file mode 100644 index 0000000..50d0f3a --- /dev/null +++ b/Legacy/Aria/ArNetworking/tests/fileServer.cpp @@ -0,0 +1,20 @@ +#include "Aria.h" +#include "ArNetworking.h" + +int main(int argc, char **argv) +{ + Aria::init(); + ArServerBase server; + + if (!server.open(7272)) + { + printf("Could not open server port\n"); + exit(1); + } + + ArServerFileLister fileLister(&server, "."); + ArServerFileToClient fileToClient(&server, "."); + ArServerFileFromClient fileFromClient(&server, ".", "/tmp"); + ArServerDeleteFileOnServer fileDeleter(&server, "."); + server.run(); +} diff --git a/Legacy/Aria/ArNetworking/tests/fileToServer.cpp b/Legacy/Aria/ArNetworking/tests/fileToServer.cpp new file mode 100644 index 0000000..42e7fc7 --- /dev/null +++ b/Legacy/Aria/ArNetworking/tests/fileToServer.cpp @@ -0,0 +1,155 @@ +#include "Aria.h" +#include "ArNetworking.h" + +ArClientFileLister *fileLister; +ArClientFileToClient *fileToClient; +ArClientFileFromClient *fileFromClient; +ArClientDeleteFileOnServer *deleteFileOnServer; + +bool done = false; + +void updated(int ret) +{ + done = true; + if (ret == 0) + fileLister->log(false); + else + printf("Bad update %d\n", ret); +} + +void fileReceived(int ret) +{ + done = true; + if (ret == 0) + printf("Got file '%s'\n", fileToClient->getFileName()); + else + printf("Didn't get file '%s' because %d\n", fileToClient->getFileName(), + ret); +} + +void fileSent(int ret) +{ + done = true; + if (ret == 0) + printf("Sent file '%s'\n", fileFromClient->getFileName()); + else + printf("Didn't send file '%s' because %d\n", + fileFromClient->getFileName(), + ret); +} + +void fileDeleted(int ret) +{ + done = true; + if (ret == 0) + printf("Deleted file '%s'\n", deleteFileOnServer->getFileName()); + else + printf("Didn't delete file '%s' because %d\n", + deleteFileOnServer->getFileName(), + ret); +} + +void waitForDone(void) +{ + while (!done && Aria::getRunning()) + ArUtil::sleep(1); + done = false; +} + +int main(int argc, char **argv) +{ + std::string hostname; + Aria::init(); + //ArLog::init(ArLog::StdOut, ArLog::Verbose); + ArClientBase client; + + + ArArgumentParser parser(&argc, argv); + + ArClientSimpleConnector clientConnector(&parser); + + parser.loadDefaultArguments(); + + ArClientFileFromClient::SendSpeed speed = ArClientFileFromClient::SPEED_AUTO; + + + if (parser.checkArgument("-speed_fast")) + { + ArLog::log(ArLog::Normal, "Putting file with speed_fast"); + speed = ArClientFileFromClient::SPEED_FAST; + } + else if (parser.checkArgument("-speed_slow")) + { + ArLog::log(ArLog::Normal, "Putting file with speed_slow"); + speed = ArClientFileFromClient::SPEED_SLOW; + } + else + { + ArLog::log(ArLog::Normal, "Putting file with speed_auto"); + } + + bool pauseAfterSend; + + if (parser.checkArgument("-pauseAfterSend")) + { + ArLog::log(ArLog::Normal, "Will pause after send"); + pauseAfterSend = true; + } + else + { + ArLog::log(ArLog::Normal, "Will not pause after send"); + pauseAfterSend = false; + } + + /* Check for -help, and unhandled arguments: */ + if (!Aria::parseArgs() || !parser.checkHelpAndWarnUnparsed(1) || + parser.getArgc() <= 1) + { + ArLog::log(ArLog::Normal, "%s <fileName> [-speed_fast] [-speed_slow] [-pauseAfterSend]", + argv[0]); + ArLog::log(ArLog::Normal, "Default send speed is speed_auto"); + ArLog::log(ArLog::Normal, ""); + Aria::logOptions(); + exit(0); + } + + const char *fileName = parser.getArg(1); + + + + /* Connect our client object to the remote server: */ + if (!clientConnector.connectClient(&client)) + { + if (client.wasRejected()) + printf("Server '%s' rejected connection, exiting\n", client.getHost()); + else + printf("Could not connect to server '%s', exiting\n", client.getHost()); + exit(1); + } + + fileFromClient = new ArClientFileFromClient(&client); + fileFromClient->addFileSentCallback( + new ArGlobalFunctor1<int>(&fileSent)); + + client.runAsync(); + + done = false; + if (!fileFromClient->putFileToDirectory(NULL, fileName, fileName, + speed)) + { + printf("Error before sending file\n"); + Aria::exit(1); + } + + waitForDone(); + + if (pauseAfterSend) + ArUtil::sleep(10000); + + Aria::exit(0); + return 255; +} + + + + diff --git a/Legacy/Aria/ArNetworking/tests/idleClient.cpp b/Legacy/Aria/ArNetworking/tests/idleClient.cpp new file mode 100644 index 0000000..bc92d6f --- /dev/null +++ b/Legacy/Aria/ArNetworking/tests/idleClient.cpp @@ -0,0 +1,58 @@ +#include "Aria.h" +#include "ArNetworking.h" + + +void idleProcessingPending(ArNetPacket *packet) +{ + if (packet->bufToByte() == 1) + printf("Idle processing pending\n"); + else + printf("No idle processing pending\n"); +} + +int main(int argc, char **argv) +{ + + Aria::init(); + ArLog::init(ArLog::StdOut, ArLog::Normal); + ArClientBase client; + + ArArgumentParser parser(&argc, argv); + + ArClientSimpleConnector clientConnector(&parser); + parser.loadDefaultArguments(); + + if (!clientConnector.parseArgs() || !parser.checkHelpAndWarnUnparsed()) + { + clientConnector.logOptions(); + exit(0); + } + + if (!clientConnector.connectClient(&client)) + { + if (client.wasRejected()) + printf("Server '%s' rejected connection, exiting\n", client.getHost()); + else + printf("Could not connect to server '%s', exiting\n", client.getHost()); + exit(1); + } + + ArGlobalFunctor1<ArNetPacket *> idleProcessingPendingCB( + &idleProcessingPending); + client.addHandler("idleProcessingPending", &idleProcessingPendingCB); + client.request("idleProcessingPending", -1); + + client.runAsync(); + while (client.getRunningWithLock()) + { + ArUtil::sleep(1); + //printf("%d ms since last data\n", client.getLastPacketReceived().mSecSince()); + } + Aria::shutdown(); + return 0; + +} + + + + diff --git a/Legacy/Aria/ArNetworking/tests/infoDrawingClient.cpp b/Legacy/Aria/ArNetworking/tests/infoDrawingClient.cpp new file mode 100644 index 0000000..2c3404a --- /dev/null +++ b/Legacy/Aria/ArNetworking/tests/infoDrawingClient.cpp @@ -0,0 +1,133 @@ +#include "Aria.h" +#include "ArNetworking.h" + +ArClientBase client; + +// suppress the output of drawings until we get the whole list in and then for a few seconds beyond that +bool getDrawingListDone = true; +ArTime getDrawingListDoneTime; + +void drawingData(ArNetPacket *packet) +{ + if (getDrawingListDone && getDrawingListDoneTime.secSince() < 5) + return; + + int x, y; + int numReadings; + int i; + + numReadings = packet->bufToByte4(); + + if (numReadings == 0) + { + printf("No readings for sensor %s\n\n", client.getName(packet)); + return; + } + + printf("Readings (%d) for %s:", numReadings, client.getName(packet)); + for (i = 0; i < numReadings; i++) + { + x = packet->bufToByte4(); + y = packet->bufToByte4(); + printf(" (%d %d)", x, y); + } + printf("\n\n"); +} + +ArGlobalFunctor1<ArNetPacket *> drawingDataCB(&drawingData); + +void getDrawingList(ArNetPacket *packet) +{ + int numDrawings; + int i; + char name[512]; + char shape[512]; + char visibility[512]; + long primary, size, layer, secondary; + unsigned long refresh; + + if (packet->getDataReadLength() == packet->getDataLength()) + { + ArLog::log(ArLog::Normal, ""); + ArLog::log(ArLog::Normal, "Done with getDrawingList, will begin logging drawing data in 5 seconds"); + getDrawingListDone = true; + getDrawingListDoneTime.setToNow(); + return; + } + + packet->bufToStr(name, sizeof(name)); + packet->bufToStr(shape, sizeof(shape)); + primary = packet->bufToByte4(); + size = packet->bufToByte4(); + layer = packet->bufToByte4(); + refresh = packet->bufToByte4(); + secondary = packet->bufToByte4(); + packet->bufToStr(visibility, sizeof(visibility)); + + ArLog::log(ArLog::Normal, "name %-40s shape %20s", name, shape); + ArLog::log(ArLog::Normal, + "\tprimary %08x size %2d layer %2d refresh %4u secondary %08x", + primary, size, layer, refresh, secondary); + + if (strcasecmp(visibility, "On") == 0 || + strcasecmp(visibility, "DefaultOn") == 0) + { + client.addHandler(name, &drawingDataCB); + client.request(name, refresh); + ArLog::log(ArLog::Normal, "\tRequesting %s since visibilty %s", name, visibility); + } + else + { + ArLog::log(ArLog::Normal, "\tNot requesting %s since visibilty %s", name, visibility); + } + +} + +int main(int argc, char **argv) +{ + + std::string hostname; + ArGlobalFunctor1<ArNetPacket *> getDrawingListCB(&getDrawingList); + Aria::init(); + //ArLog::init(ArLog::StdOut, ArLog::Verbose); + + + + ArArgumentParser parser(&argc, argv); + + ArClientSimpleConnector clientConnector(&parser); + + parser.loadDefaultArguments(); + + /* Check for -help, and unhandled arguments: */ + if (!Aria::parseArgs() || !parser.checkHelpAndWarnUnparsed()) + { + Aria::logOptions(); + exit(0); + } + + /* Connect our client object to the remote server: */ + if (!clientConnector.connectClient(&client)) + { + if (client.wasRejected()) + printf("Server '%s' rejected connection, exiting\n", client.getHost()); + else + printf("Could not connect to server '%s', exiting\n", client.getHost()); + exit(1); + } + + printf("Connected to server.\n"); + + client.addHandler("getDrawingList", &getDrawingListCB); + client.requestOnce("getDrawingList"); + + client.runAsync(); + while (client.getRunningWithLock()) + { + ArUtil::sleep(1); + //printf("%d ms since last data\n", client.getLastPacketReceived().mSecSince()); + } + Aria::shutdown(); + return 0; + +} diff --git a/Legacy/Aria/ArNetworking/tests/infoDrawingServer.cpp b/Legacy/Aria/ArNetworking/tests/infoDrawingServer.cpp new file mode 100644 index 0000000..41c263f --- /dev/null +++ b/Legacy/Aria/ArNetworking/tests/infoDrawingServer.cpp @@ -0,0 +1,30 @@ +#include "Aria.h" +#include "ArNetworking.h" + +void sendEmpty(ArServerClient *client, ArNetPacket *packet) +{ + ArNetPacket sendingPacket; + sendingPacket.byteToBuf(0); + client->sendPacketTcp(&sendingPacket); +} + +int main(int argc, char **argv) +{ + Aria::init(); + ArServerBase server; + ArGlobalFunctor2<ArServerClient *, ArNetPacket *> sendEmptyCB(&sendEmpty); + if (!server.open(7272)) + { + printf("Could not open server port\n"); + exit(1); + } + + ArServerInfoDrawings drawing(&server); + + ArDrawingData arrows("polyarrow", ArColor(0, 0, 255), 5, 50); + ArDrawingData dots("polydots", ArColor(0, 255, 0), 12, 50); + drawing.addDrawing(&arrows, "arrows", &sendEmptyCB); + drawing.addDrawing(&dots, "dots", &sendEmptyCB); + server.run(); + +} diff --git a/Legacy/Aria/ArNetworking/tests/mapClient.cpp b/Legacy/Aria/ArNetworking/tests/mapClient.cpp new file mode 100644 index 0000000..9db6041 --- /dev/null +++ b/Legacy/Aria/ArNetworking/tests/mapClient.cpp @@ -0,0 +1,79 @@ +#include "Aria.h" +#include "ArNetworking.h" + +ArMap arMap; +ArClientBase client; +ArTime start; + +void handleGetMapName(ArNetPacket *packet) +{ + char buffer[512]; + + packet->bufToStr(buffer, sizeof(buffer)); + printf("MapFile: %s\n", buffer); +} + +void handleGetMap(ArNetPacket *packet) +{ + char buffer[10000]; + + if (packet->getDataReadLength() == packet->getDataLength()) + { + printf("Empty packet signifying end of map (for central forward)\n"); + return; + } + + packet->bufToStr(buffer, sizeof(buffer)); + // if we got an end of line char instead of a line it means the map is over + if (buffer[0] == '\0') + { + printf("Map took %g seconds\n", start.mSecSince() / 1000.0); + arMap.parsingComplete(); + arMap.writeFile("mapExample.map"); + //client.disconnect(); + //exit(0); + } + else + { + //printf("line '%s'\n", buffer); + arMap.parseLine(buffer); + } + +} + +int main(int argc, char **argv) +{ + + ArGlobalFunctor1<ArNetPacket *> getMapNameCB(handleGetMapName); + ArGlobalFunctor1<ArNetPacket *> getMapCB(handleGetMap); + + Aria::init(); + //ArLog::init(ArLog::StdOut, ArLog::Verbose); + + ArArgumentParser parser(&argc, argv); + + ArClientSimpleConnector clientConnector(&parser); + + parser.loadDefaultArguments(); + + /* Check for -help, and unhandled arguments: */ + if (!Aria::parseArgs() || !parser.checkHelpAndWarnUnparsed()) + { + Aria::logOptions(); + exit(0); + } + /* Connect our client object to the remote server: */ + if (!clientConnector.connectClient(&client)) + { + exit(1); + } + + client.addHandler("getMap", &getMapCB); + client.addHandler("getMapName", &getMapNameCB); + client.requestOnce("getMapName"); + start.setToNow(); + client.requestOnce("getMap"); + + client.run(); + +} diff --git a/Legacy/Aria/ArNetworking/tests/mapServer.cpp b/Legacy/Aria/ArNetworking/tests/mapServer.cpp new file mode 100644 index 0000000..2d13dce --- /dev/null +++ b/Legacy/Aria/ArNetworking/tests/mapServer.cpp @@ -0,0 +1,27 @@ +#include "Aria.h" +#include "ArNetworking.h" + + +int main(int argc, char **argv) +{ + Aria::init(); + //ArLog::init(ArLog::StdOut, ArLog::Verbose); + ArServerBase server; + ArMap arMap; + + if (argc < 2) + { + printf("Usage: %s <mapToServe>\n", argv[0]); + exit(2); + } + arMap.readFile(argv[1]); + if (!server.open(7272)) + { + printf("Could not open server port\n"); + exit(1); + } + + ArServerHandlerMap netMap(&server, &arMap); + server.run(); + +} diff --git a/Legacy/Aria/ArNetworking/tests/md5test.cpp b/Legacy/Aria/ArNetworking/tests/md5test.cpp new file mode 100644 index 0000000..94f4e03 --- /dev/null +++ b/Legacy/Aria/ArNetworking/tests/md5test.cpp @@ -0,0 +1,143 @@ +/* + The test program (called md5main.c by them) that came with the md5 + package from http://sourceforge.net/project/showfiles.php?group_id=42360 +*/ + +/* + Copyright (C) 2002 Aladdin Enterprises. All rights reserved. + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + L. Peter Deutsch + ghost@aladdin.com + + */ +/* + Independent implementation of MD5 (RFC 1321). + + This code implements the MD5 Algorithm defined in RFC 1321, whose + text is available at + http://www.ietf.org/rfc/rfc1321.txt + The code is derived from the text of the RFC, including the test suite + (section A.5) but excluding the rest of Appendix A. It does not include + any code or documentation that is identified in the RFC as being + copyrighted. + + The original and principal author of md5.c is L. Peter Deutsch + <ghost@aladdin.com>. Other authors are noted in the change history + that follows (in reverse chronological order): + + 2002-04-13 lpd Splits off main program into a separate file, md5main.c. + */ + +#include "md5.h" +#include <math.h> +#include <stdio.h> +#include <string.h> + +/* + * This file builds an executable that performs various functions related + * to the MD5 library. Typical compilation: + * gcc -o md5main -lm md5main.c md5.c + */ +static const char *const usage = "\ +Usage:\n\ + md5main --test # run the self-test (A.5 of RFC 1321)\n\ + md5main --t-values # print the T values for the library\n\ + md5main --version # print the version of the package\n\ +"; +static const char *const version = "2002-04-13"; + +/* Run the self-test. */ +static int +do_test(void) +{ + static const char *const test[7*2] = { + "", "d41d8cd98f00b204e9800998ecf8427e", + "a", "0cc175b9c0f1b6a831c399e269772661", + "abc", "900150983cd24fb0d6963f7d28e17f72", + "message digest", "f96b697d7cb7938d525a2f31aaf161d0", + "abcdefghijklmnopqrstuvwxyz", "c3fcd3d76192e4007dfb496cca67e13b", + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", + "d174ab98d277d9f5a5611c2c9f419d9f", + "12345678901234567890123456789012345678901234567890123456789012345678901234567890", "57edf4a22be3c955ac49da2e2107b67a" + }; + int i; + int status = 0; + + for (i = 0; i < 7*2; i += 2) { + md5_state_t state; + md5_byte_t digest[16]; + char hex_output[16*2 + 1]; + int di; + + md5_init(&state); + md5_append(&state, (const md5_byte_t *)test[i], strlen(test[i])); + md5_finish(&state, digest); + for (di = 0; di < 16; ++di) + sprintf(hex_output + di * 2, "%02x", digest[di]); + if (strcmp(hex_output, test[i + 1])) { + printf("MD5 (\"%s\") = ", test[i]); + puts(hex_output); + printf("**** ERROR, should be: %s\n", test[i + 1]); + status = 1; + } + } + if (status == 0) + puts("md5 self-test completed successfully."); + return status; +} + +/* Print the T values. */ +static int +do_t_values(void) +{ + int i; + for (i = 1; i <= 64; ++i) { + unsigned long v = (unsigned long)(4294967296.0 * fabs(sin((double)i))); + + /* + * The following nonsense is only to avoid compiler warnings about + * "integer constant is unsigned in ANSI C, signed with -traditional". + */ + if (v >> 31) { + printf("#define T%d /* 0x%08lx */ (T_MASK ^ 0x%08lx)\n", i, + v, (unsigned long)(unsigned int)(~v)); + } else { + printf("#define T%d 0x%08lx\n", i, v); + } + } + return 0; +} + +/* Main program */ +int +main(int argc, char *argv[]) +{ + if (argc == 2) { + if (!strcmp(argv[1], "--test")) + return do_test(); + if (!strcmp(argv[1], "--t-values")) + return do_t_values(); + if (!strcmp(argv[1], "--version")) { + puts(version); + return 0; + } + } + puts(usage); + return 0; +} diff --git a/Legacy/Aria/ArNetworking/tests/modeInfoClient.cpp b/Legacy/Aria/ArNetworking/tests/modeInfoClient.cpp new file mode 100644 index 0000000..e03bd14 --- /dev/null +++ b/Legacy/Aria/ArNetworking/tests/modeInfoClient.cpp @@ -0,0 +1,86 @@ +#include "Aria.h" +#include "ArNetworking.h" + + +void getModeDataList(ArNetPacket *packet) +{ + char mode[512]; + char data[512]; + int numData; + int i; + + numData = packet->bufToByte4(); + printf("%d data in modes\n", numData); + for (i = 0; i < numData; i++) + { + packet->bufToStr(mode, sizeof(mode)); + packet->bufToStr(data, sizeof(data)); + printf("%-20s%s\n", mode, data); + } +} + +void getModeInfo(ArNetPacket *packet) +{ + char mode[512]; + unsigned char locked; + unsigned char willUnlock; + + packet->bufToStr(mode, sizeof(mode)); + locked = packet->bufToUByte(); + willUnlock = packet->bufToUByte(); + + printf("Mode: %s locked: %d willUnlockIfRequested: %d\n", + mode, locked, willUnlock); + +} + + + +int main(int argc, char **argv) +{ + + Aria::init(); + ArLog::init(ArLog::StdOut, ArLog::Normal); + ArClientBase client; + + ArArgumentParser parser(&argc, argv); + + ArClientSimpleConnector clientConnector(&parser); + parser.loadDefaultArguments(); + + if (!clientConnector.parseArgs() || !parser.checkHelpAndWarnUnparsed()) + { + clientConnector.logOptions(); + exit(0); + } + + if (!clientConnector.connectClient(&client)) + { + if (client.wasRejected()) + printf("Server '%s' rejected connection, exiting\n", client.getHost()); + else + printf("Could not connect to server '%s', exiting\n", client.getHost()); + exit(1); + } + + ArGlobalFunctor1<ArNetPacket *> getModeDataListCB(&getModeDataList); + ArGlobalFunctor1<ArNetPacket *> getModeInfoCB(&getModeInfo); + client.addHandler("getModeDataList", &getModeDataListCB); + client.requestOnce("getModeDataList"); + client.addHandler("getModeInfo", &getModeInfoCB); + client.request("getModeInfo", -1); + + client.runAsync(); + while (client.getRunningWithLock()) + { + ArUtil::sleep(1); + //printf("%d ms since last data\n", client.getLastPacketReceived().mSecSince()); + } + Aria::shutdown(); + return 0; + +} + + + + diff --git a/Legacy/Aria/ArNetworking/tests/reloadConfig.cpp b/Legacy/Aria/ArNetworking/tests/reloadConfig.cpp new file mode 100644 index 0000000..cb47080 --- /dev/null +++ b/Legacy/Aria/ArNetworking/tests/reloadConfig.cpp @@ -0,0 +1,48 @@ +#include "Aria.h" +#include "ArNetworking.h" + +int main(int argc, char **argv) +{ + Aria::init(); + ArClientBase client; + std::string host; + + + ArArgumentParser parser(&argc, argv); + ArClientSimpleConnector clientConnector(&parser); + + parser.loadDefaultArguments(); + + /* Check for -help, and unhandled arguments: */ + if (!clientConnector.parseArgs() || !parser.checkHelpAndWarnUnparsed()) + { + clientConnector.logOptions(); + exit(0); + } + + + /* Connect our client object to the remote server: */ + if (!clientConnector.connectClient(&client)) + { + if (client.wasRejected()) + printf("Server rejected connection, exiting\n"); + else + printf("Could not connect to server, exiting\n"); + exit(1); + } + + + client.requestOnce("reloadConfig"); + + + ArTime start; + start.setToNow(); + while (Aria::getRunning() && client.isConnected()) + { + client.loopOnce(); + ArUtil::sleep(ArMath::random() % 10000); + client.requestOnce("reloadConfig"); + } + Aria::shutdown(); + return 0; +} diff --git a/Legacy/Aria/ArNetworking/tests/serverTest.vcproj b/Legacy/Aria/ArNetworking/tests/serverTest.vcproj new file mode 100644 index 0000000..1035a85 --- /dev/null +++ b/Legacy/Aria/ArNetworking/tests/serverTest.vcproj @@ -0,0 +1,182 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="7.10" + Name="serverTest" + ProjectGUID="{3C7E4CF6-F6E6-452B-99F8-ACF4266730F4}" + SccProjectName="" + SccLocalPath=""> + <Platforms> + <Platform + Name="Win32"/> + </Platforms> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory=".\../../binNet" + IntermediateDirectory=".\../../objNet" + ConfigurationType="1" + UseOfMFC="0" + ATLMinimizesCRunTimeLibraryUsage="FALSE" + CharacterSet="2"> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="..\include,..\..\include" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" + StringPooling="TRUE" + BasicRuntimeChecks="0" + RuntimeLibrary="0" + EnableFunctionLevelLinking="TRUE" + PrecompiledHeaderFile=".\../../objNet/serverTest.pch" + AssemblerListingLocation=".\../../objNet/" + ObjectFile=".\../../objNet/" + ProgramDataBaseFileName=".\../../objNet/" + BrowseInformation="1" + WarningLevel="3" + SuppressStartupBanner="TRUE" + DebugInformationFormat="3" + CompileAs="0"/> + <Tool + Name="VCCustomBuildTool"/> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="Aria.lib ArNetworking.lib odbc32.lib odbccp32.lib" + OutputFile=".\../../binNet/serverTest.exe" + Version="1.0" + LinkIncremental="1" + SuppressStartupBanner="TRUE" + AdditionalLibraryDirectories="..\..\libNet" + GenerateDebugInformation="TRUE" + SubSystem="1" + TargetMachine="1"/> + <Tool + Name="VCMIDLTool" + TypeLibraryName=".\../../bin/serverTest.tlb" + HeaderFileName=""/> + <Tool + Name="VCPostBuildEventTool"/> + <Tool + Name="VCPreBuildEventTool"/> + <Tool + Name="VCPreLinkEventTool"/> + <Tool + Name="VCResourceCompilerTool" + PreprocessorDefinitions="_DEBUG" + Culture="1033"/> + <Tool + Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCWebDeploymentTool" + RelativePath="binNet"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory=".\../../binNet" + IntermediateDirectory=".\../../objNet" + ConfigurationType="1" + UseOfMFC="0" + ATLMinimizesCRunTimeLibraryUsage="FALSE" + CharacterSet="2"> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + InlineFunctionExpansion="1" + AdditionalIncludeDirectories="..\include,..\..\include" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" + StringPooling="TRUE" + BasicRuntimeChecks="0" + RuntimeLibrary="0" + EnableFunctionLevelLinking="TRUE" + PrecompiledHeaderFile=".\../../objNet/serverTest.pch" + AssemblerListingLocation=".\../../objNet/" + ObjectFile=".\../../objNet/" + ProgramDataBaseFileName=".\../../objNet/" + WarningLevel="3" + SuppressStartupBanner="TRUE" + CompileAs="0"/> + <Tool + Name="VCCustomBuildTool"/> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="Aria.lib ArNetworking.lib odbc32.lib odbccp32.lib" + OutputFile=".\../../binNet/serverTest.exe" + Version="1.0" + LinkIncremental="1" + SuppressStartupBanner="TRUE" + AdditionalLibraryDirectories="..\..\libNet" + SubSystem="1" + TargetMachine="1"/> + <Tool + Name="VCMIDLTool" + TypeLibraryName=".\../../bin/serverTest.tlb" + HeaderFileName=""/> + <Tool + Name="VCPostBuildEventTool"/> + <Tool + Name="VCPreBuildEventTool"/> + <Tool + Name="VCPreLinkEventTool"/> + <Tool + Name="VCResourceCompilerTool" + PreprocessorDefinitions="NDEBUG" + Culture="1033"/> + <Tool + Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCWebDeploymentTool" + RelativePath="binNet"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"> + <File + RelativePath="serverTest.cpp"> + <FileConfiguration + Name="Debug|Win32"> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="" + PreprocessorDefinitions="" + BasicRuntimeChecks="3" + BrowseInformation="1"/> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32"> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + AdditionalIncludeDirectories="" + PreprocessorDefinitions=""/> + </FileConfiguration> + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl"> + </Filter> + <Filter + Name="Resource Files" + Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"> + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/Legacy/Aria/ArNetworking/tests/simpleServerTest.cpp b/Legacy/Aria/ArNetworking/tests/simpleServerTest.cpp new file mode 100644 index 0000000..a65ba48 --- /dev/null +++ b/Legacy/Aria/ArNetworking/tests/simpleServerTest.cpp @@ -0,0 +1,16 @@ +#include "Aria.h" +#include "ArServerBase.h" + + +int main(int argc, char **argv) +{ + Aria::init(); + ArServerBase server; + if (!server.open(7272)) + { + printf("Could not open server port\n"); + exit(1); + } + server.run(); + return 0; +} diff --git a/Legacy/Aria/ArNetworking/tests/standaloneClientDemo.cpp b/Legacy/Aria/ArNetworking/tests/standaloneClientDemo.cpp new file mode 100644 index 0000000..0ea8026 --- /dev/null +++ b/Legacy/Aria/ArNetworking/tests/standaloneClientDemo.cpp @@ -0,0 +1,161 @@ +#include "Aria.h" +#include "ArNetworking.h" + +class InputHandler +{ +public: + InputHandler(ArClientBase *client, ArKeyHandler *keyHandler); + virtual ~InputHandler(void); + void up(void); + void down(void); + void left(void); + void right(void); + void space(void); +protected: + ArClientBase *myClient; + ArKeyHandler *myKeyHandler; + ArFunctorC<InputHandler> myUpCB; + ArFunctorC<InputHandler> myDownCB; + ArFunctorC<InputHandler> myLeftCB; + ArFunctorC<InputHandler> myRightCB; + ArFunctorC<InputHandler> mySpaceCB; +}; + +InputHandler::InputHandler(ArClientBase *client, ArKeyHandler *keyHandler) : + myUpCB(this, &InputHandler::up), + myDownCB(this, &InputHandler::down), + myLeftCB(this, &InputHandler::left), + myRightCB(this, &InputHandler::right), + mySpaceCB(this, &InputHandler::space) +{ + myClient = client; + myKeyHandler = keyHandler; + myKeyHandler->addKeyHandler(ArKeyHandler::UP, &myUpCB); + myKeyHandler->addKeyHandler(ArKeyHandler::DOWN, &myDownCB); + myKeyHandler->addKeyHandler(ArKeyHandler::LEFT, &myLeftCB); + myKeyHandler->addKeyHandler(ArKeyHandler::RIGHT, &myRightCB); + myKeyHandler->addKeyHandler(ArKeyHandler::SPACE, &mySpaceCB); +} + +InputHandler::~InputHandler(void) +{ + +} + +void InputHandler::up(void) +{ + ArNetPacket packet; + packet.doubleToBuf(25); + myClient->requestOnce("deltaVel", &packet); +} + +void InputHandler::down(void) +{ + ArNetPacket packet; + packet.doubleToBuf(-25); + myClient->requestOnce("deltaVel", &packet); +} + +void InputHandler::left(void) +{ + ArNetPacket packet; + packet.doubleToBuf(3.2); + myClient->requestOnce("deltaHeading", &packet); +} + +void InputHandler::right(void) +{ + ArNetPacket packet; + packet.doubleToBuf(-3.2); + myClient->requestOnce("deltaHeading", &packet); +} + +void InputHandler::space(void) +{ + ArNetPacket packet; + packet.doubleToBuf(0.00001); + myClient->requestOnce("setVel", &packet); + myClient->requestOnce("deltaHeading", &packet); +} + +class OutputHandler +{ +public: + OutputHandler(ArClientBase *client); + virtual ~OutputHandler(void); + void handleOutput(ArNetPacket *packet); +protected: + double myX; + double myY; + double myTh; + double myVel; + double myRotVel; + double myVoltage; + ArClientBase *myClient; + ArFunctor1C<OutputHandler, ArNetPacket *> myHandleOutputCB; + +}; + +OutputHandler::OutputHandler(ArClientBase *client) : + myHandleOutputCB(this, &OutputHandler::handleOutput) +{ + myClient = client; + myClient->addHandler("output", &myHandleOutputCB); + myClient->request("output", 100); +} + +OutputHandler::~OutputHandler(void) +{ + myClient->requestStop("output"); +} + +void OutputHandler::handleOutput(ArNetPacket *packet) +{ + myX = packet->bufToByte4(); + myY = packet->bufToByte4(); + myTh = packet->bufToByte2()/10.0; + myVel = packet->bufToByte2(); + myRotVel = packet->bufToByte2(); + myVoltage = packet->bufToByte2()/10.0; + printf("\rx: %6.0f y: %6.0f th: %5.1f vel: %4.0f rotVel: %3.0f voltage: %4.1f", + myX, myY, myTh, myVel, myRotVel, myVoltage); + fflush(stdout); +} + + +void escape(void) +{ + Aria::shutdown(); +} + +int main(int argc, char **argv) +{ + char* host = "localhost"; + if(argc > 1) + host = argv[1]; + Aria::init(); + ArClientBase client; + ArGlobalFunctor escapeCB(&escape); + ArKeyHandler keyHandler; + Aria::setKeyHandler(&keyHandler); + + + printf("Connecting to standaloneServerDemo at %s:%d...\n", host, 7272); + if (!client.blockingConnect(host, 7272)) + { + printf("Could not connect to server, exiting\n"); + exit(1); + } + InputHandler inputHandler(&client, &keyHandler); + OutputHandler outputHandler(&client); + keyHandler.addKeyHandler(ArKeyHandler::ESCAPE, &escapeCB); + client.runAsync(); + while (client.getRunningWithLock()) + { + keyHandler.checkKeys(); + ArUtil::sleep(1); + } + keyHandler.restore(); + Aria::shutdown(); + return 0; +} diff --git a/Legacy/Aria/ArNetworking/tests/standaloneServerDemo.cpp b/Legacy/Aria/ArNetworking/tests/standaloneServerDemo.cpp new file mode 100644 index 0000000..3456b03 --- /dev/null +++ b/Legacy/Aria/ArNetworking/tests/standaloneServerDemo.cpp @@ -0,0 +1,191 @@ +#include "Aria.h" +#include "ArNetworking.h" + +class InputHandler +{ +public: + InputHandler(ArServerBase *server, ArRobot *robot); + virtual ~InputHandler(void); + void setVel(ArServerClient *client, ArNetPacket *packet); + void deltaVel(ArServerClient *client, ArNetPacket *packet); + void deltaHeading(ArServerClient *client, ArNetPacket *packet); +protected: + ArActionInput myActionInput; + ArRobot *myRobot; + ArServerBase *myServer; + ArFunctor2C<InputHandler, ArServerClient *, ArNetPacket *> mySetVelCB; + ArFunctor2C<InputHandler, ArServerClient *, ArNetPacket *> myDeltaVelCB; + ArFunctor2C<InputHandler, ArServerClient *, ArNetPacket *> myDeltaHeadingCB; +}; + +InputHandler::InputHandler(ArServerBase *server, ArRobot *robot) : + mySetVelCB(this, &InputHandler::setVel), + myDeltaVelCB(this, &InputHandler::deltaVel), + myDeltaHeadingCB(this, &InputHandler::deltaHeading) +{ + myRobot = robot; + myServer = server; + myRobot->addAction(&myActionInput, 50); + myServer->addData("setVel", "sets the velocity of the robot", &mySetVelCB, + "double: vel", "none"); + myServer->addData("deltaVel", "changes the velocity of the robot", + &myDeltaVelCB, "double: deltaVel", "none"); + myServer->addData("deltaHeading", "changes the heading of the robot", + &myDeltaHeadingCB, "double: deltaHeading", "none"); +} + +InputHandler::~InputHandler(void) +{ + myRobot->remAction(&myActionInput); + /*myServer->remData("setVel"); + myServer->remData("deltaVel"); + myServer->remData("deltaHeading");*/ +} + +void InputHandler::setVel(ArServerClient *client, ArNetPacket *packet) +{ + double vel = packet->bufToDouble(); + //printf("Vel %g\n", vel); + myActionInput.setVel(vel); +} + +void InputHandler::deltaVel(ArServerClient *client, ArNetPacket *packet) +{ + double delta = packet->bufToDouble(); + //printf("DeltaVel %g\n", delta); + //myActionInput.deltaVel(delta); // deltaVel has been removed from ArActionInput + myActionInput.setVel(myRobot->getVel() + delta); +} + +void InputHandler::deltaHeading(ArServerClient *client, ArNetPacket *packet) +{ + double delta = packet->bufToDouble(); + //printf("DeltaHeading %g\n", delta); + myActionInput.deltaHeadingFromCurrent(delta); +} + +class OutputHandler +{ +public: + OutputHandler(ArServerBase *server, ArRobot *robot); + virtual ~OutputHandler(void); + void buildOutput(void); + void output(ArServerClient *client, ArNetPacket *packet); + +protected: + ArServerBase *myServer; + ArRobot *myRobot; + ArMutex myPacketMutex; + ArNetPacket myBuiltPacket; + ArNetPacket mySendingPacket; + ArFunctor2C<OutputHandler, ArServerClient *, ArNetPacket *> myOutputCB; + ArFunctorC<OutputHandler> myTaskCB; +}; + +OutputHandler::OutputHandler(ArServerBase *server, ArRobot *robot) : + myOutputCB(this, &OutputHandler::output), + myTaskCB(this, &OutputHandler::buildOutput) +{ + myServer = server; + myRobot = robot; + myServer->addData("output", "gives the status of the robot", &myOutputCB, + "none", "byte4: x, byte4: y, byte2: th*10, byte2: vel, byte2: rotvel, byte2: battery*10"); + myRobot->addUserTask("output", 50, &myTaskCB); +} + +OutputHandler::~OutputHandler(void) +{ + +} + +void OutputHandler::buildOutput(void) +{ + myPacketMutex.lock(); + myBuiltPacket.empty(); + myBuiltPacket.byte4ToBuf(ArMath::roundInt(myRobot->getX())); + myBuiltPacket.byte4ToBuf(ArMath::roundInt(myRobot->getY())); + myBuiltPacket.byte2ToBuf(ArMath::roundInt(myRobot->getTh())); + myBuiltPacket.byte2ToBuf(ArMath::roundInt(myRobot->getVel())); + myBuiltPacket.byte2ToBuf(ArMath::roundInt(myRobot->getRotVel())); + myBuiltPacket.byte2ToBuf(ArMath::roundInt( + myRobot->getBatteryVoltage() * 10)); + myPacketMutex.unlock(); +} + +void OutputHandler::output(ArServerClient *client, ArNetPacket *packet) +{ + myPacketMutex.lock(); + mySendingPacket.duplicatePacket(&myBuiltPacket); + myPacketMutex.unlock(); + client->sendPacketTcp(&mySendingPacket); +} + +int main(int argc, char **argv) +{ + Aria::init(); + ArServerBase server; + // the serial connection (robot) + ArSerialConnection serConn; + // tcp connection (sim) + ArTcpConnection tcpConn; + // robot + ArRobot robot; + + // first open the server up + if (!server.open(7272)) + { + printf("Could not open server port\n"); + exit(1); + } + // attach stuff to the server + InputHandler inputHandler(&server, &robot); + OutputHandler outputHandler(&server, &robot); + // now let it spin off in its own thread + server.runAsync(); + + + tcpConn.setPort(); + // see if we can get to the simulator (true is success) + if (tcpConn.openSimple()) + { + // we could get to the sim, so set the robots device connection to the sim + printf("Connecting to simulator through tcp.\n"); + robot.setDeviceConnection(&tcpConn); + } + else + { + // we couldn't get to the sim, so set the port on the serial + // connection and then set the serial connection as the robots + // device + + // modify the next line if you're not using the first serial port + // to talk to your robot + serConn.setPort(); + printf( + "Could not connect to simulator, connecting to robot through serial.\n"); + robot.setDeviceConnection(&serConn); + } + + // try to connect, if we fail exit + if (!robot.blockingConnect()) + { + printf("Could not connect to robot... exiting\n"); + Aria::shutdown(); + return 1; + } + // enable the motors, disable amigobot sounds + robot.comInt(ArCommands::ENABLE, 1); + robot.comInt(ArCommands::BUMPSTALL, 0); + + // run the robot, true here so that the run will exit if connection lost + robot.run(true); + + // now exit + Aria::shutdown(); + + + + return 0; +} + + diff --git a/Legacy/Aria/ArNetworking/tests/switchServer.cpp b/Legacy/Aria/ArNetworking/tests/switchServer.cpp new file mode 100644 index 0000000..64a6069 --- /dev/null +++ b/Legacy/Aria/ArNetworking/tests/switchServer.cpp @@ -0,0 +1,61 @@ +#include "Aria.h" +#include "ArNetworking.h" + + +void forwarderAdded(ArCentralForwarder *forwarder) +{ + printf("@ Forwarder added for %s\n", + forwarder->getRobotName()); +} + +void forwarderRemoved(ArCentralForwarder *forwarder) +{ + printf("@ Forwarder removed for %s\n", + forwarder->getRobotName()); +} + +int main(int argc, char **argv) +{ + Aria::init(); + + ArServerBase robotServer; + if (!robotServer.open(5000)) + { + printf("Could not open robot server port\n"); + Aria::exit(1); + } + + ArServerBase clientServer; + if (!clientServer.open(7272)) + { + printf("Could not open robot server port\n"); + Aria::exit(1); + } + + ArCentralManager switchManager(&robotServer, &clientServer); + + switchManager.addForwarderAddedCallback( + new ArGlobalFunctor1<ArCentralForwarder *>(&forwarderAdded), + 100); + switchManager.addForwarderRemovedCallback( + new ArGlobalFunctor1<ArCentralForwarder *>(&forwarderRemoved), + 100); + + // Start a small handler to monitor communication between the server and + // client. + ArServerHandlerCommMonitor commMonitor(&clientServer); + + ArServerHandlerCommands commands(&clientServer); + commands.setPrefix("CentralServer"); + + ArServerSimpleServerCommands serverCommands(&commands, &clientServer, + false); + commands.addCommand( + "NetworkLogConnections", "Logs the connections to the central server, and to all the forwarded connections", + new ArFunctorC<ArCentralManager> + (&switchManager, &ArCentralManager::logConnections)); + + clientServer.runAsync(); + robotServer.run(); + Aria::exit(0); +} diff --git a/Legacy/Aria/ArNetworking/tests/switchWatcher.cpp b/Legacy/Aria/ArNetworking/tests/switchWatcher.cpp new file mode 100644 index 0000000..6ebe91b --- /dev/null +++ b/Legacy/Aria/ArNetworking/tests/switchWatcher.cpp @@ -0,0 +1,105 @@ +#include "Aria.h" +#include "ArNetworking.h" + + +void clientListHandler(ArNetPacket *packet) +{ + int numClients; + int i; + char hostName[512]; + int port; + char robotName[512]; + char flags[512]; + char robotIP[512]; + + + numClients = packet->bufToUByte2(); + printf("%d clients connected to server\n", numClients); + for (i = 0; i < numClients; i++) + { + packet->bufToStr(hostName, sizeof(hostName)); + port = packet->bufToUByte2(); + packet->bufToStr(robotName, sizeof(robotName)); + packet->bufToStr(flags, sizeof(flags)); + packet->bufToStr(robotIP, sizeof(robotIP)); + printf("\tHost: '%s' Port: %d ID: '%s' Flags: %s IP: %s\n", hostName, port, robotName, flags, robotIP); + } + printf("\n"); +} + + +void clientRemovedHandler(ArNetPacket *packet) +{ + char hostName[512]; + int port; + char robotName[512]; + char flags[512]; + char robotIP[512]; + + packet->bufToStr(hostName, sizeof(hostName)); + port = packet->bufToUByte2(); + packet->bufToStr(robotName, sizeof(robotName)); + packet->bufToStr(flags, sizeof(flags)); + packet->bufToStr(robotIP, sizeof(robotIP)); + printf("Removed Host: '%s' Port: %d ID: '%s' Flags: %s IP: %s\n", hostName, port, robotName, flags, robotIP); +} + +void clientAddedHandler(ArNetPacket *packet) +{ + char hostName[512]; + int port; + char robotName[512]; + char flags[512]; + char robotIP[512]; + + packet->bufToStr(hostName, sizeof(hostName)); + port = packet->bufToUByte2(); + packet->bufToStr(robotName, sizeof(robotName)); + packet->bufToStr(flags, sizeof(flags)); + packet->bufToStr(robotIP, sizeof(robotIP)); + printf("Added Host: '%s' Port: %d ID: '%s' Flags: %s IP: %s\n", hostName, port, robotName, flags, robotIP); +} + +int main(int argc, char **argv) +{ + Aria::init(); + ArGlobalFunctor1<ArNetPacket *> clientListHandlerCB(&clientListHandler); + ArGlobalFunctor1<ArNetPacket *> clientAddedHandlerCB(&clientAddedHandler); + ArGlobalFunctor1<ArNetPacket *> clientRemovedHandlerCB(&clientRemovedHandler); + ArNetPacket packet; + + ArClientBase client; + + ArArgumentParser parser(&argc, argv); + + ArClientSimpleConnector clientConnector(&parser); + + parser.loadDefaultArguments(); + + if (!Aria::parseArgs() || !parser.checkHelpAndWarnUnparsed()) + { + Aria::logOptions(); + exit(0); + } + + if (!clientConnector.connectClient(&client)) + { + if (client.wasRejected()) + printf("Server '%s' rejected connection, exiting\n", client.getHost()); + else + printf("Could not connect to server '%s', exiting\n", client.getHost()); + exit(1); + } + + printf("Connected to server.\n"); + + client.addHandler("clientList", &clientListHandlerCB); + client.requestOnce("clientList"); + client.addHandler("clientRemoved", &clientRemovedHandlerCB); + client.request("clientRemoved", -1); + client.addHandler("clientAdded", &clientAddedHandlerCB); + client.request("clientAdded", -1); + client.run(); + Aria::shutdown(); + return 0; +} diff --git a/Legacy/Aria/ArNetworking/tests/testClient.cpp b/Legacy/Aria/ArNetworking/tests/testClient.cpp new file mode 100644 index 0000000..8d8a607 --- /dev/null +++ b/Legacy/Aria/ArNetworking/tests/testClient.cpp @@ -0,0 +1,53 @@ +#include "Aria.h" +#include "ArNetworking.h" + +void test(ArNetPacket *packet) +{ + printf("command %d\n", packet->getCommand()); +} + +int main(int argc, char **argv) +{ + ArClientBase client; + ArGlobalFunctor1<ArNetPacket *> testCB(&test); + + Aria::init(); + //ArLog::init(ArLog::StdOut, ArLog::Verbose); + ArTime startTime; + startTime.setToNow(); + if (!client.blockingConnect("localhost", 7273)) + { + printf("Could not connect to server, exiting\n"); + exit(1); + } + printf("Took %ld msec to connect\n", startTime.mSecSince()); + + client.runAsync(); + + client.lock(); + client.addHandler("test", &testCB); + client.addHandler("test2", &testCB); + client.addHandler("test3", &testCB); + client.logDataList(); + + client.requestOnce("test"); + client.request("test2", 100); + client.request("test3", -1); + client.unlock(); + ArUtil::sleep(1000); + printf("Changing speed\n"); + client.lock(); + client.request("test2", 300); + client.unlock(); + ArUtil::sleep(1000); + client.lock(); + client.requestStop("test2"); + client.unlock(); + + ArUtil::sleep(1000); + client.lock(); + client.disconnect(); + client.unlock(); + ArUtil::sleep(50); + exit(0); +} diff --git a/Legacy/Aria/ArNetworking/tests/testRequestOnce.cpp b/Legacy/Aria/ArNetworking/tests/testRequestOnce.cpp new file mode 100644 index 0000000..dd67165 --- /dev/null +++ b/Legacy/Aria/ArNetworking/tests/testRequestOnce.cpp @@ -0,0 +1,71 @@ +#include "Aria.h" +#include "ArNetworking.h" + +void handleUpdate(ArNetPacket *packet) +{ + if (packet->getPacketSource() == ArNetPacket::TCP) + printf("Tcp ... \n"); + else + printf("Udp ... \n"); +} + +int main(int argc, char **argv) +{ + ArClientBase client; + ArGlobalFunctor1<ArNetPacket *> handleUpdateCB(&handleUpdate); + + Aria::init(); + //ArLog::init(ArLog::StdOut, ArLog::Verbose); + ArTime startTime; + startTime.setToNow(); + + /* Aria components use this to get options off the command line: */ + ArArgumentParser parser(&argc, argv); + + /* This will be used to connect our client to the server, including + * various bits of handshaking (e.g. sending a password, retrieving a list + * of data requests and commands...) + * It will get the hostname from the -host command line argument: */ + ArClientSimpleConnector clientConnector(&parser); + + parser.loadDefaultArguments(); + + /* Check for -help, and unhandled arguments: */ + if (!Aria::parseArgs() || !parser.checkHelpAndWarnUnparsed()) + { + Aria::logOptions(); + exit(0); + } + + + /* Connect our client object to the remote server: */ + if (!clientConnector.connectClient(&client)) + { + if (client.wasRejected()) + printf("Server '%s' rejected connection, exiting\n", client.getHost()); + else + printf("Could not connect to server '%s', exiting\n", client.getHost()); + exit(1); + } + + printf("Took %ld msec to connect\n", startTime.mSecSince()); + + client.runAsync(); + + client.lock(); + client.addHandler("update", &handleUpdateCB); + + client.requestOnce("update"); + client.unlock(); + ArUtil::sleep(1000); + + client.lock(); + client.requestOnceUdp("update"); + client.unlock(); + ArUtil::sleep(1000); + client.lock(); + client.disconnect(); + client.unlock(); + ArUtil::sleep(50); + exit(0); +} diff --git a/Legacy/Aria/ArNetworking/tests/testServer.cpp b/Legacy/Aria/ArNetworking/tests/testServer.cpp new file mode 100644 index 0000000..42d8500 --- /dev/null +++ b/Legacy/Aria/ArNetworking/tests/testServer.cpp @@ -0,0 +1,35 @@ +#include "Aria.h" +#include "ArNetworking.h" + +void testFunction(ArServerClient *client, ArNetPacket *packet) +{ + ArNetPacket sending; + printf("responding to a packet of command %d\n", packet->getCommand()); + client->sendPacketTcp(&sending); +} + +int main(int argc, char **argv) +{ + Aria::init(); + ArGlobalFunctor2<ArServerClient *, ArNetPacket *> testCB(&testFunction); + ArServerBase server; + //ArLog::init(ArLog::StdOut, ArLog::Verbose); + ArNetPacket packet; + + server.addData("test", "some wierd test", &testCB, "none", "none"); + server.addData("test2", "another wierd test", &testCB, "none", "none"); + server.addData("test3", "yet another wierd test", &testCB, "none", "none"); + if (!server.open(7273)) + { + printf("Could not open server port\n"); + exit(1); + } + server.runAsync(); + while (server.getRunningWithLock()) + { + ArUtil::sleep(1000); + server.broadcastPacketTcp(&packet, "test3"); + } + Aria::shutdown(); + return 0; +} diff --git a/Legacy/Aria/ArNetworking/tests/testStatic.vcproj b/Legacy/Aria/ArNetworking/tests/testStatic.vcproj new file mode 100644 index 0000000..b5b2f57 --- /dev/null +++ b/Legacy/Aria/ArNetworking/tests/testStatic.vcproj @@ -0,0 +1,157 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="7.10" + Name="testStatic" + ProjectGUID="{7AEA7E4D-0984-4A16-8A3F-AF36B1A27836}" + SccProjectName="" + SccLocalPath=""> + <Platforms> + <Platform + Name="Win32"/> + </Platforms> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory=".\../../bin" + IntermediateDirectory=".\../../obj/debug" + ConfigurationType="1" + UseOfMFC="0" + ATLMinimizesCRunTimeLibraryUsage="FALSE" + CharacterSet="2"> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="..\include,..\..\include" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;ARIA_STATIC" + StringPooling="TRUE" + BasicRuntimeChecks="0" + RuntimeLibrary="1" + BufferSecurityCheck="FALSE" + EnableFunctionLevelLinking="FALSE" + RuntimeTypeInfo="TRUE" + BrowseInformation="1" + WarningLevel="3" + SuppressStartupBanner="TRUE" + DebugInformationFormat="3" + CompileAs="0"/> + <Tool + Name="VCCustomBuildTool"/> + <Tool + Name="VCLinkerTool" + Version="1.0" + LinkIncremental="1" + SuppressStartupBanner="TRUE" + AdditionalLibraryDirectories="..\..\lib" + GenerateDebugInformation="TRUE" + SubSystem="1" + TargetMachine="1"/> + <Tool + Name="VCMIDLTool" + TypeLibraryName=".\../../bin/testStatic.tlb" + HeaderFileName=""/> + <Tool + Name="VCPostBuildEventTool"/> + <Tool + Name="VCPreBuildEventTool"/> + <Tool + Name="VCPreLinkEventTool"/> + <Tool + Name="VCResourceCompilerTool" + PreprocessorDefinitions="_DEBUG" + Culture="1033"/> + <Tool + Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCWebDeploymentTool" + RelativePath="binNet"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory=".\../../bin" + IntermediateDirectory=".\../../obj/release" + ConfigurationType="1" + UseOfMFC="0" + ATLMinimizesCRunTimeLibraryUsage="FALSE" + CharacterSet="2"> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + InlineFunctionExpansion="1" + AdditionalIncludeDirectories="..\include,..\..\include" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;ARIA_STATIC" + StringPooling="FALSE" + BasicRuntimeChecks="0" + RuntimeLibrary="0" + BufferSecurityCheck="FALSE" + EnableFunctionLevelLinking="FALSE" + RuntimeTypeInfo="TRUE" + WarningLevel="3" + SuppressStartupBanner="TRUE" + CompileAs="0"/> + <Tool + Name="VCCustomBuildTool"/> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="winmm.lib wsock32.lib" + Version="1.0" + LinkIncremental="1" + SuppressStartupBanner="TRUE" + AdditionalLibraryDirectories="..\..\lib" + SubSystem="1" + TargetMachine="1"/> + <Tool + Name="VCMIDLTool" + TypeLibraryName=".\../../bin/testStatic.tlb" + HeaderFileName=""/> + <Tool + Name="VCPostBuildEventTool"/> + <Tool + Name="VCPreBuildEventTool"/> + <Tool + Name="VCPreLinkEventTool"/> + <Tool + Name="VCResourceCompilerTool" + PreprocessorDefinitions="NDEBUG" + Culture="1033"/> + <Tool + Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCWebDeploymentTool" + RelativePath="binNet"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"> + <File + RelativePath=".\proprietarySeekurDrive.cpp"> + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl"> + </Filter> + <Filter + Name="Resource Files" + Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"> + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/Legacy/Aria/ArNetworking/tests/userServerTest.cpp b/Legacy/Aria/ArNetworking/tests/userServerTest.cpp new file mode 100644 index 0000000..fd503f7 --- /dev/null +++ b/Legacy/Aria/ArNetworking/tests/userServerTest.cpp @@ -0,0 +1,152 @@ +#include "Aria.h" +#include "ArNetworking.h" + + +int main(int argc, char **argv) +{ + Aria::init(); + //ArLog::init(ArLog::StdOut, ArLog::Verbose); + // robot + ArRobot robot; + /// our server + ArServerBase server; + + // set up our parser + ArArgumentParser parser(&argc, argv); + // set up our simple connector + ArSimpleConnector simpleConnector(&parser); + + // set up a gyro + ArAnalogGyro gyro(&robot); + + // load the default arguments + parser.loadDefaultArguments(); + + // parse the command line... fail and print the help if the parsing fails + // or if the help was requested + if (!simpleConnector.parseArgs() || !parser.checkHelpAndWarnUnparsed()) + { + simpleConnector.logOptions(); + exit(1); + } + + if (!server.loadUserInfo("userServerTest.userInfo")) + { + printf("Could not load user info, exiting\n"); + exit(1); + } + + server.logUsers(); + + // first open the server up + if (!server.open(7272)) + { + printf("Could not open server port\n"); + exit(1); + } + + // sonar, must be added to the robot + ArSonarDevice sonarDev; + // add the sonar to the robot + robot.addRangeDevice(&sonarDev); + + ArIRs irs; + robot.addRangeDevice(&irs); + + ArBumpers bumpers; + robot.addRangeDevice(&bumpers); + + // a laser in case one is used + ArSick sick(361, 180); + // add the laser to the robot + robot.addRangeDevice(&sick); + + + + + // attach stuff to the server + ArServerInfoRobot serverInfoRobot(&server, &robot); + ArServerInfoSensor serverInfoSensor(&server, &robot); + ArServerInfoDrawings drawings(&server); + drawings.addRobotsRangeDevices(&robot); + + // ways of moving the robot + ArServerModeStop modeStop(&server, &robot); + ArServerModeDrive modeDrive(&server, &robot); + ArServerModeRatioDrive modeRatioDrive(&server, &robot); + ArServerModeWander modeWander(&server, &robot); + modeStop.addAsDefaultMode(); + modeStop.activate(); + + // set up the simple commands + ArServerHandlerCommands commands(&server); + // add the commands for the microcontroller + ArServerSimpleComUC uCCommands(&commands, &robot); + // add the commands for logging + ArServerSimpleComMovementLogging loggingCommands(&commands, &robot); + // add the commands for the gyro + ArServerSimpleComGyro gyroCommands(&commands, &robot, &gyro); + + // add the commands to enable and disable safe driving to the simple commands + modeDrive.addControlCommands(&commands); + + // Forward any video if we have some to forward.. this will forward + // from SAV or ACTS, you can find both on our website + // http://robots.activmedia.com, ACTS is for color tracking and is + // charged for but SAV just does software A/V transmitting and is + // free to all our customers... just run ACTS or SAV before you + // start this program and this class here will forward video from it + // to MobileEyes + ArHybridForwarderVideo videoForwarder(&server, "localhost", 7070); + + // make a camera to use in case we have video + ArPTZ *camera = NULL; + ArServerHandlerCamera *handlerCamera = NULL; + // if we have video then set up a camera + if (videoForwarder.isForwardingVideo()) + { + bool invertedCamera = false; + camera = new ArVCC4(&robot, invertedCamera, + ArVCC4::COMM_UNKNOWN, true, true); + camera->init(); + handlerCamera = new ArServerHandlerCamera(&server, &robot, camera); + } + + server.logCommandGroups(); + server.logCommandGroupsToFile("userServerTest.commandGroups"); + + // now let it spin off in its own thread + server.runAsync(); + + // set up the robot for connecting + if (!simpleConnector.connectRobot(&robot)) + { + printf("Could not connect to robot... exiting\n"); + Aria::shutdown(); + return 1; + } + + // set up the laser before handing it to the laser mode + simpleConnector.setupLaser(&sick); + + robot.enableMotors(); + // start the robot running, true so that if we lose connection the run stops + robot.runAsync(true); + + sick.runAsync(); + + // connect the laser if it was requested + if (!simpleConnector.connectLaser(&sick)) + { + printf("Could not connect to laser... exiting\n"); + Aria::shutdown(); + return 1; + } + + robot.waitForRunExit(); + // now exit + Aria::shutdown(); + exit(0); +} + + diff --git a/Legacy/Aria/ArNetworking/tests/userServerTest.userInfo b/Legacy/Aria/ArNetworking/tests/userServerTest.userInfo new file mode 100644 index 0000000..f5242b4 --- /dev/null +++ b/Legacy/Aria/ArNetworking/tests/userServerTest.userInfo @@ -0,0 +1,4 @@ +UserInfoVersion1 +user bob isFUN RobotInfo +user user activmedia CustomCommands Movement RobotInfo SensorInfo Stop UnsafeMovement +user administrator activmedia all \ No newline at end of file diff --git a/Legacy/Aria/ArNetworking/tests/watchDockInfo.cpp b/Legacy/Aria/ArNetworking/tests/watchDockInfo.cpp new file mode 100644 index 0000000..583a0fa --- /dev/null +++ b/Legacy/Aria/ArNetworking/tests/watchDockInfo.cpp @@ -0,0 +1,103 @@ +#include "Aria.h" +#include "ArNetworking.h" + +void dockInfoChanged(ArNetPacket *packet) +{ + int state = packet->bufToUByte(); + int forcedDock = packet->bufToUByte(); + int secondsToShutdown = packet->bufToUByte2(); + + std::string stateStr; + std::string forcedStr; + + if (state == 0) + stateStr = " Undocked"; + else if (state == 1) + stateStr = " Docking"; + else if (state == 2) + stateStr = " Docked"; + else if (state == 3) + stateStr = "Undocking"; + else + stateStr = " Unknown"; + + if (forcedDock == 0) + forcedStr = "false"; + else if (forcedDock == 1) + forcedStr = " true"; + else + forcedStr = "unknown"; + + if (secondsToShutdown == 0) + ArLog::log(ArLog::Normal, "State: %s Forced: %s Shutdown: never", + stateStr.c_str(), forcedStr.c_str()); + else + ArLog::log(ArLog::Normal, "State: %s Forced: %s Shutdown: %d", + stateStr.c_str(), forcedStr.c_str(), secondsToShutdown); + +} + + + +/* Key handler for the escape key: shutdown all of Aria. */ +void escape(void) +{ + printf("esc pressed, shutting down aria\n"); + Aria::shutdown(); +} + +int main(int argc, char **argv) +{ + Aria::init(); + + ArClientBase client; + + ArArgumentParser parser(&argc, argv); + + ArClientSimpleConnector clientConnector(&parser); + + parser.loadDefaultArguments(); + + if (!Aria::parseArgs() || !parser.checkHelpAndWarnUnparsed()) + { + Aria::logOptions(); + exit(0); + } + + if (!clientConnector.connectClient(&client)) + { + if (client.wasRejected()) + printf("Server '%s' rejected connection, exiting\n", client.getHost()); + else + printf("Could not connect to server '%s', exiting\n", client.getHost()); + exit(1); + } + + printf("Connected to server.\n"); + + + /* Create a key handler and also tell Aria about it */ + ArKeyHandler keyHandler; + Aria::setKeyHandler(&keyHandler); + + /* Global escape-key handler to shut everythnig down */ + ArGlobalFunctor escapeCB(&escape); + keyHandler.addKeyHandler(ArKeyHandler::ESCAPE, &escapeCB); + + client.addHandler("dockInfoChanged", new ArGlobalFunctor1<ArNetPacket *>(&dockInfoChanged)); + client.requestOnce("dockInfoChanged"); + client.request("dockInfoChanged", -1); + + client.runAsync(); + + while (client.getRunningWithLock()) + { + keyHandler.checkKeys(); + ArUtil::sleep(100); + } + + /* The client stopped running, due to disconnection from the server, general + * Aria shutdown, or some other reason. */ + Aria::shutdown(); + return 0; +} diff --git a/Legacy/Aria/Aria-Reference.html b/Legacy/Aria/Aria-Reference.html new file mode 100644 index 0000000..48d1b0e --- /dev/null +++ b/Legacy/Aria/Aria-Reference.html @@ -0,0 +1,16 @@ +<html> +<head> +<title>ARIA Documentation + + + +

ARIA Index

+
+
+
+
+
(If the ARIA index isn't loaded automatically,
please click +the above hyperlink,
or locate the index.html page in +docs/.)
+ + diff --git a/Legacy/Aria/Changes.txt b/Legacy/Aria/Changes.txt new file mode 100644 index 0000000..6bb4c20 --- /dev/null +++ b/Legacy/Aria/Changes.txt @@ -0,0 +1,1450 @@ +Aria 2.8.0 +August 22, 2013 +--------------------------- + +This release adds support for the Pioneer LX. The Pioneer LX is the first +of a new type of robots referred to as the MTX generation or type. MTX is +largely compatible with previous Pioneer type robots, with the exception of +connections to sonar, battery, LCD, IO and some other components. The +ARIA API is largely the same, remaining transparently compatible, but you may +need to use some MTX-specific classes for certain MTX-specific fetaures, in +particular general purpose IO via the ArMTXIO class. See the MTX-specific +example programs in the examples/ directory for examples of use of these +features. A more detailed summary of classes added or changes made for MTX is +below. + +2.8.0 has been released for Linux only. A release with Windows support is +forthcoming. + +MTX LCD display implementation is incomplete in 2.8.0. An update will be +released in the future with complete LCD support (with robot firmware upgrade +if needed.) + +Analog IO support is incomplete, this will also be added in the next update. + +Additional changes made in this release of ARIA include: + * Support for the SICK TiM300 laser rangefinder. Use the tim3xx laser type + identifier in robot configuration or command-line parameters. (Implemented + internally as a variant in ArLMS1xx class) + * ArRobot disables the robot motors explicitly before disconnecting on exit + * ArActionDeceleratingLimiter now has option to limit rotation as well as + translation + * ArActionLimiterRot added, which can be used to limit rotation separately + from other actions. + * ArActionTriangleDriveTo improved + * List parameter type added (and other API changes) to ArConfig, though not + generally used in ARIA or ARNL yet. + * ArRobotJoyHandler can now be connected to ArConfig for user control of + some parameters. + * SICK S300 support has been improved + * RS-422 support in ArSerialConnection now available in Windows as well as + Linux + * ArSonarAutoDisabler can now be temporarily supressed with a method or + functor call. + * ArSoundsQueue can call callbacks before and after each item is played. + * Signed and unsigned long int values can now be added to ArStringInfoGroup + * strSuffixCmp(), strSuffixCaseCmp(), stripQuotes() methods added to ArUtil + * Equal and not equal (== and !=) operators added to ArLine + * Negative and positive rotational velocity limits separated in + ArActionDesired + * ArArgumentBuilder handling of spaces and quotes can be customized a bit + * State of charge, lateral velocity, and battery data added to ArDataLogger. + * ArLog::logBacktrace() added for Linux, which calls Linux backtrace() system + call. + * Diagnostic ArMutex lock timing can be used on Windows now. + * ArFunctor classes added which can pass five arguments + +ArNetworking changes include: + * Number of connected clients can be limited in ArServerBase + * ArServerHandlerMapping can call callbacks before and after mapping is done, + and can also be given additional ArLaser interfaces to include in the scan + log. + * ArServerMode objects have a new "extended status" field which can hold + details in addition to mode name and status field. This is also provided + to clients for the active server mode by ArServerInfoRobot in addition to + existing mode name and status. Extended status may contain multiple lines + (normal status is expected to not contain any newlines) + +Details of MTX (Pioneer LX) additions: + * ArMTXIO class added. Communicates with "mtx" operating system driver to + interface with MTX digital general purpose IO and power control. + * ArSonarConnector and ArSonarMTX classes. By default the connection to MTX sonar + is handled automatically by ArRobotConnector, no changes to existing + software need to be made. The existing ArSonarDevice and ArRobot API can be + used with MTX sonar. + * ArBatteryConnector and ArBatteryMTX classes. By default, the connection to MTX + battery is handled automatically by ArRobotConnector, no changes to existing + software needs to be made. The state of charge and other information is + available in the existing ArRobot API. Extra diagnostic information about + the batter(ies) is provided in ArBatteryMTX objects which can be obtained + from ArRobot. + * Default Pioneer LX parameters have been built in to ARIA for "pioneer-lx" + type robots and a pioneer-lx.p + parameter file is included in the params directory. Early revisions of + the MTX core report a robot subtype of "marc_devel" which is assumed to be + an LX. + * A Pioneer LX model has been added to MobileSim 0.7.3 + * mtxIO, mtxPowerControl and mtxWheelLights examples added. Other examples + including demo have been updated to use ArRobotConnector and other current + classes for MTX/LX compatability. + * New command identifiers added to ArCommands + + + +Aria 2.7.6 +March 29, 2013 +--------------------------- +* Added ArPTZConnector, which can automatically create ArPTZ subclass instances + based on configuration information read from robot parameer files (params/.p, + params/.p) and program command line arguments. (See also the new ArVideo library + now available with this ARIA release.) Some common functionality (inverted, limits) has + also been moved from individual ArPTZ subclasses into the ArPTZ class. +* Robot parameters (ArRobotParams, defaults, and .p files) now contain parameters for PTZ and video devices + (used by new ArPTZConnector and ArVideo library) +* The way subclasses of ArPTZ implement methods has changed. Inverting the axes + and other common functionality is now done in ArPTZ, subclasses implement _i + internal methods instead. This is transparent to most users, but if you have + created a new subclass of ArPTZ you may need to update your class. +* Increased GPS connection timeout to 20sec. +* Added support for simulated or dummy GPS +* Added new NMEA messages: GPHDG, GPHDM, GPHDT (for receivers with integrated compass) +* Misc. documentation fixes and improvements, including class categories (e.g. essential, + optional, device interfaces, actions, etc.) +* Desired sound playback volume can be set in ArSoundPlayer (implemented for Linux with + sox tool). +* Some SWIG and Windows DLL export fixes. +* ArUtil::isOnlyNumeric() and ArUtil::isOnlyAlphaNumeric() now accept '+' and + '-' characters as valid parts of numeric and alphanumeric strings. + +Aria 2.7.5.2 +August 2, 2012 +--------------------------- + +* Fixed regression in which start and end FOV angles couldn't be set in + robot parameter files for LMS1xx laser rangefinders. + +Aria 2.7.5.1 +July 9, 2012 +--------------------------- + +* ArRVisionPTZ now defaults to automatically connecting through serial port + COM3, rather than requring you to manually set it up with an + ArDeviceConnection object (though this is still possible.) +* Fixed system installation of Python pacakges on Debian -- + now installs in correct Python version directory + /usr/lib/python2.5/site-pacakges instead of old 2.4 directory. + +Aria 2.7.5 +June 12, 2012 +--------------------------- + +* Fixed bug in ArLMS1xx class that prevented connecting to LMS-100 or LMS-111. + It now has correct default resolution option, and allow selecting both half or + quarter degree resolution. +* You can now select one, half or quarter degree resolution if connecting to an + LMS-500, rather than just one as in 2.7.4. +* Made some minor updates to examples. Added new example lasers.cpp showing + how to connect to one or more lasers (from parameters) and obtain data from + them. Added rvisionCameraExample.cpp (conect to RVision camera). Added seekurPower.cpp + utility (control seekur power ports). +* Default position for a second laser on a Seekur Jr. corrected (reverse-mounted on the + back of the robot. this can be changed in parameters.) +* Default/builtin laser parameter type for Seekur changed to lms1xx +* ArDPPTU now reads the PTU's position back from the device. This position is returned for + getPan() and getTilt() and canGetRealPanTilt() now returns true if this data has been + received from the device. +* ArDPPTU now queries the position resolution (conversion factor) from the device itself + rather than requiring specifying D46 or D47 in the constructor. (But you can still specify + these to force hardcoded conversion factors for those specific models.) + +Aria 2.7.4 +March 13, 2012 +--------------------------- + +* Added SICK LMS-500 support. +* Added SICK S-300 and S-3000 support +* Added Keyence SZ series laser support +* Added lms1xx robot types to automatic parameter generation (generated by + utils/makeParams) +* Added RS-422 support (for Linux) to ArSerialConnection +* Added more Visual Studio 2010 projects (for most libraries and examples) +* Fixed bug in ArTime::mSecSince(ArTime since) in which very large value would be + truncated in internal arithmetic resulting in incorrect output. Now valid within range of a long. (Note ArTime also has + methods that return "long long" values, which should be used in situations + when very long time differences are possible.) +* Change to ArPTZ to allow Pan/tilt/zoom cameras to now be connected to the + third auxilliary robot serial port (AUX3), which is available in newer SH + Pioneers. (Previously only AUX1 and AUX2 were possible.) +* Minor fix to NMEA parser +* Better error reporting in ArSocket +* Minor fix to baud selection in ArSerialConnection on Windows + +This version of Aria is compatible with other Aria 2.7 releases and will work +with any software built with Aria 2.7. + +Aria 2.7.3 +September 8, 2011 +--------------------------- + +* Fixed minor bug in ArLMS1XX (was not ignoring some invalid readings, if the + LMS100 was returning a nonzero but impossibly small range) +* Fixed minor bug in demo's laser mode (would show incorrect values initially) +* Fixed minor bug in examples/sickLogger.cpp, which would prevent the laser + log from being processed by Mapper3. Also updated sickLogger.cpp to change + use of deprecated classes to their replacements. +* Includes support for URG SCIP 2.0 via ArUrg_2.0 class and "urg2.0" laser + type. +* Fixed bug in ArActionLimiterBackwards +* Added parameter files p3dx-sh-lms1xx.p, p3at-sh-lms1xx.p, + peoplebot-sh-lms1xx.p with standard mounting locations of SICK LMS-100/111 + laser, and lms1xx laser type selected for primary laser. +* Added project files for Visual Studio 2010 + +Aria 2.7.2 +January 7, 2010 +--------------------------- + +* Added Seekur Jr. support +* Added support for distinct "research patrolbot" robot type +* Added SICK LMS 100 support +* Added experimental Novatel SPAN GPS support +* Fixed a bug in ArLaser (not enough space in buffer for all laser readings if + more than 180) +* Added parameter files researchPB.p, mt400.p, seekurjr.p. + +This version of libAria should be compatible with libAria 2.7.0 and dependent +libraries built with 2.7.0 should work with this version. + + + +Aria 2.7.1 +September 9, 2009 +--------------------------- + +Bugs fixed: + * Fixed problems connecting to laser, mainly in demo: Serial port + is now opened when entering laser mode (when laser is really connected + to) rather than on startup, and fixed an uninitialized variable in ArLM2xx. + * Fixed possible incorrect error return when connecting to an URG laser + with ArUrg::blockingConnect(). + +This version of libAria is compatible with libAria 2.7.0 and dependent +libraries built with 2.7.0 will work with this version. + + + +Aria 2.7.0 +April 30, 2009 +--------------------------- + +Summary: + +Among many other changes and improvements, Aria 2.7.0 includes: + * New ArRobotConnector and ArLaserConnector classes replace the old + ArSimpleConnector. ArSimpleConnector is still available however. + * New improved support for multiple heterogenous laser rangefinding + devices in ArLaserConnector, ArRobot, and generally in ARIA. Configure + what devices are available on an individual robot, and device options, + in the robot parameter file, Aria.args file, or program command line options. + * Visual Studio 2008 project files are included; VC2003 project files + have been renamed. + * Java 1.6 is now used to build Java libraries rather than 1.4; you must + either upgrade to 1.6 (J2SE JDK release 6), or rebuild the Java + wrapper libraries with 1.4 if you must continue using 1.4. + * Java wrapper libraries are now contained in Java packages: + com.mobilerobots.Aria for ARIA, and com.mobilerobots.ArNetworking for + ArNetworking. + * On Windows, the ws2_32 sockets library is now used instead of the + older wsock32 library. + * On Linux, a better monotonic clock is used if the OS supports it. + This requires that all programs now link with librt (-lrt) on Linux. + * Aria now includes classes to support the RVision PTZ camera, Hokuyo URG + laser, some additional GPS data (if receiver provides it), lateral motion + on a Seekur robot, and various other miscellaneous improvements and features. + +Read below for a complete list and more information. Upgrading MobileEyes +to 2.2.4 or later is also recommended for teleoperation to work right. + +Important Linux compilation change: + + * ARIA now uses the monotonic system clock if available, via the librt + system library. Therefore all programs using ARIA must now link to + librt using the -lrt link flag, in addition to libAria, libpthread + and libdl as before. The ARIA examples and tests Makefiles have + been updated, but you must update your own Makefiles or other + build systems. This change only applies to building on Linux. + +Important laser range device class changes: + + * Made support for lasers much more generic, this involves the rest + of the changes in this section. There's compatibility classes for + all of the old code, so existing code should still compile. The + one exception to this is the 'second laser' parameters in the .p + file will no longer be read so you'll need to change them to 'Laser + 2 settings'. + * There is now an ArLaser class that does most everything that ArSick + used to do in terms of filtering and callbacks and such, the names + and arguments are sometimes slightly different. ArLaser is a + superset of everything that can be set on any of the lasers, so + that it can be generically configured. + * Made a new ArLMS2xx class to replace ArSick. ArSick is now a + legacy class with all of the old functions on it that old code + should still work. + * Added ArUrg class to support for Hokuyo URG URG-04LX if using the + SCIP 1.1 protocol). + * Made ArRobotConnector and ArLaserConnector to replace + ArSimpleConnector (which is now a legacy class that uses the new + classes). ArRobotConnector has the same functionality as before, + but can autoParse the args when blockingConnect is called. + ArLaserConnector will create lasers and add them to the robot and + configure them with the arguments from the command line (though it + does pull the device connection information from the .p file). + Lasers wind up named _ (except the legacy + sick of course). Lasers themselves will configure themselves with + the information in the .p file (as long as that parameter wasn't + already set by the command line). + * Made the laser type and parameter information so that it is stored + in the .p and can be passed into the command line. + * Made it so that the robot should be connected (with + ArRobotConnector) before the Aria::parseArgs call, so that the + types in the .p files and what not can be used. The legacy code + works without this (because it only works with one type of laser). + * ArUtil now has a createLaser call that will create a laser of a + given type, and a getCreateLaserTypes that will list the types that + can be created. This is mostly for use by the new ArLaserConnector. + * ArUtil now has a createDeviceConnection call that will create a + device connection of a given type and try to connect it to a given + port, and a getCreateDeviceConnectionTypes that will list the + device connection types that can be created. This is mostly for + use by the new ArLaserConnector, but could be used by other things + too. + * Made ArRobot so that it has a mapping of laser numbers to lasers, + so that classes can pull out lasers without as much work. It + doesn't do anything with these at all. Lasers are automatically + added to the robot by ArLaserConnector now... They still have to be + added as range devices to do anything, which automatically happens + in the ArLaserConnector now. The calls for this are + ArRobot::addlaser, ArRobot::remLaser, ArRobot::findLaser, and + ArRobot::getLaserMap + * The LaserIgnore parameter in the .p file and the corresponding + command line arguments (-laserAdditionalIgnoreReadings) can now + take ranges (begin-end), the multiple arguments can be separated by + commas (with or without extra spaces), or it can be separated + simply by spaces as the old ones were (though that won't work from + the command line). + * Simulated lasers are now done totally differently than before + (unless you are using the ArSick legacy class where the behavior is + unchanged). There is new class called ArSimulatedLaser that + basically takes over for the normal laser class of that type and + can be configured the exact same way, but gets its readings from + the simulator. This is all handled transparently by + ArLaserConnector. Right now this will only deal with 1 laser, but + later there will be modifications to MobileSim and Aria to allow it + to work with multiple lasers. These wind up with the name + sim__. + * Made ArModeLaser (the laser mode in demo) so that it would work + with multiple lasers + * Lasers maximum range can now be set in the .p file. This is mostly + for if you want to shorten it from the default. + * Lasers now don't have a current buffer size passed in, it is now + set to whatever the maximum number of readings will be when the + laser connects (based on degrees and increment). ArSick remains + the same as it was. + * Lasers cumulative buffer size can now be set in the .p file, the + default is now 200. ArSick remains the same as it was. + +See also changes in ARIA 2.6.0, below. + +Changes: + * Project files for Visual Studio 2008 (Version 9) are now + included. These are named with a "-vc2008" at the end, and + libraries built using these projects are named with a "VC9" suffix + before the .lib or .dll extension. Project files for Visual Studio + 2003 (Version 7) have been (mostly) renamed to end with "-vc2003", + though libraries built using these projects have the same names as + before. + * Java 1.6 is now used to build the Java wrapper library on Windows + and Debian Linux. You should upgrade to Java 1.6 if you are still + using 1.4. If you get an error message referring to a "bad class + file" in Aria.jar, that the "wrong version 50.0, should be 48.0", then + it's due to using 1.4 with the Aria classes built using Java 1.6. + * Java wrapper libraries are now contained in packages: com.mobilerobots.Aria + for Aria, and com.mobilerobots.ArNetworking for ArNetworking. You must change + Java programs to import the Aria and ArNetworking packages by adding these + lines (near the top of the program file): + import com.mobilerobots.Aria.*; + import com.mobilerobots.ArNetworking.*; + * On Windows, ArSocket now uses the better ws2_32 sockets library, rather + than the old wsock32 library. Aria and ArNetworking project files (for + libraries and example programs) have been changed to link to this + library, but you should also remove the wsock32 "additional library + dependency" from the Linker settings of any project files + for programs that might still have it. Linux ArSocket is unchanged. + * For non-windows platforms ArTime will use a monotonic clock + (clock_gettime) if it is supported by the OS (it looks like linux + kernel 2.6 and up support this). If it isn't available it'll + continue to use the non-monotonic clock (gettimeofday) that has + issues if the time on the platform is changed. In Windows the + clock was always monotonic (timeGetTime). + ArTime::usingMonotonicClock is available to see if the clock is + monotonic (make sure you've done an Aria::init before you use it + though). + * ArArgumentParser now takes const char* arguments instead of char* + * Made ArSocket (and therefore ArTcpConnection) so that if you give + the hostname as hostname:port that it will override the passed in + port number. This is mostly for default ports on the laser, but + could be useful for other device connections (so there don't need + to be multiple arguments to each thing). + * Some changes to ArArgumentParser with how it deals with the + wasReallySet parameters, described more in the documentation for + the class. + * ArServerModeRatioDrive now expects to receive commands every 2 + seconds (or faster) from a client; if it doesn't receive a new + command after 2 seconds, it stops the robot. This stops the robot + if there is a loss or degradation of network connectivity while + driving. You must upgrade to MobileEyes 2.2.4 or later for teleoperation + to work correctly with this version of Aria. + +See also the changes in ARIA 2.6.0 below. + +Additions: + * In ArNetworking, there are now server simple commands for + microcontrollerCommand and microcontrollerMotionCommand, + microcontrollerMotionCommand will susped the normal state + reflection so that you can just send motion commands down (like 'd' + mode in demo). + * Added ArUrg (laser) class. + * Added support for the newer DP PTU-D47 to the ArDPPTU class. Select + the D47 by passing PANTILT_PTUD47 as second argument to the ArDPPTU + constructor. + * Added support for the RVision PTZ camera + * ArUtil now has a setFileCloseOnExec() function call. This function + makes a call to fork() or exec() close a file or socket. + * ArUtil now has fopen, open, open, creat, and popen functions that + will call the new setFileCloseOnExec() function for the new + file or socket. It is recommended that these functions always + be used to avoid resource leaks if a program uses exec() or fork(). + * Made ArKeyHandler so that it could take a FILE * pointer instead of + always using stdin, and has the option to not take the keys in the + constructor... these will only do anything in non Windows platforms + * ArGPS reads and provides some additional GPS info (if the receiver + provides it) + * ArFunctor and ArCallbackList now have setNameVar, and ArMutex now + has setLogNameVar. These functions take printf style arguments to + make it easier to set the names for more complicated uses + * There is now an Aria::remExitCallback which will make sure that it + isn't exiting before removing a callback, since that would break + the looping. Aria::addExitCallback will now make sure it isn't + exiting before adding a callback (which shouldn't be needed, + but...) + +Bug fixes: + + * In Windows the ArThread::self and ArThread::osSelf previously did + not work at all since it was returning a constant that meant the + current thread (it used GetCurrentThread instead of + GetCurrentThreadId)... they do now work, but the + ArThread::ThreadType has been redefined to be a DWORD instead of a + HANDLE... all existing code should work after a recompile as long + as it was using the ThreadType define. ArThread in windows now + keeps track of the thread handle separately so uses it where it + used to. This bug also means that some of the thread + infrastructure wasn't entirely working in Windows (like shutting + the threads all down on a shutdown). + * Modified ArSocket::open() (and therefore ArNetServer and ArServerBase) + so that it calls setLinger(0), setReuseAddress(), setNonBlock() + between creating the socket and binding the port, since apparently + SO_REUSEADDR does not work unless you use it this way. This should + prevent the times when programs couldn't start because they were + waiting for a port that was just closed. + * The Linux part of ArMutex was checking all of the return values + wrong... so would never return an actual error happened... that's + been fixed. This probably didn't matter except with tryLock() which + would return that it had the lock when it really didn't (tryLock() + is never used by ARIA itself or any example programs, and is rarely + needed in most programs). + * ArNetServer and ArServerBase now have a member socket they use to + accept new client connections instead of creating a new socket + (and all the resources that go along with that) every single time + they were called. + * Modified the ArPose constructor so that it normalizes the given theta + to be in the range -180 to 180. This is consistent with the + behavior of the setPose() and setTh() methods. + * ArSocket will now set its socket file descriptors so that they will be closed + if an exec() system call is used. + * Fixed bug in ArDPPTU that crashed given pan values < -51 when in PTUD47 mode. + (or possibly effectively ignored the pan value on some computers.) + * In ArMap (and ArMapInterface-related classes), if built on Windows, when loading + or saving a file, a filename starting with a possible Windows drive letter is + recognized as an absolute path rather than a relative path within ArMap's baseDirectory + path. (The file name must start with "x:\" where x is any one upper- or lowercase + alphabetic character, i.e. a-z or A-Z.) + * Fixed various errors reported by GCC versions 4+. + + +See also the changes in ARIA 2.6.0 below. + +Aria 2.6.0 +August 3, 2007 +--------------------------- + +(Limited release) + +Important changes and bug fixes: + * Support for Seekur's lateral velocity (sideways motion) in ArRobot, Actions, + and ArNetworking teleoperation servers. + * Java wrapper libraries are now contained in packages: com.mobilerobots.Aria + for Aria, and com.mobilerobots.ArNetworking for ArNetworking. You must change + Java programs to import the Aria and ArNetworking packages by adding these + lines (near the top of the program file): + import com.mobilerobots.Aria.*; + import com.mobilerobots.ArNetworking.*; + * ArActionDeceleratingLimiter change to contructor so it can work + with the lateral motion, it takes an enum now instead of a bool, + old true would be ArActionDeceleratingLimiter::FORWARDS, and old + false would be ::BACKWARDS + * New firmware has a kinematics delay value it sends us (because + using the gyro can cause the microcontroller to send us older but + more correct odometry). ArRobot now takes this delay into account + when putting information in for the pose interpolation. + This change should be transparent to everyone... but there + might be more forward projection in data returned from + ArRobot::getPoseInterpPosition() and + ArRobot::getEncoderPoseInterpPosition(). ArSick already takes this + into account. The forward projection on ArInterpolation is more + forgiving of future projections too (allows 50% projection instead + of 3%) + * Made it so an Aria.args file that was empty no longer resulted in + an uninitialized string (change was to ArUtil::getStringFromFile) + * ArSoundsQueue::speak() has been renamed to speakf(), and replaced + by a new speak() method which does not take printf-style varargs. + * Added support for a TCM2 compass connected directly to the + computer. The ArTCM2 class is now an interface to both kinds of + compass. Use an ArCompassConnector to create a compass object based + on command-line arguments (default is ArTCM2Robot), and call + blockingConnect()to connect to the compass (see demo.cpp for + example). Almost everyone should use ArTCM2Robot ("robot" type). + * Fixed various errors reported by GCC 4+. + +Enhancements: + * ArSimpleConnector now has arguments to log packets received and + sent, movement received and sent, velocity received, and actions. + * Moved timeout configuration into a section called 'Connection timeouts' and + renamed them to be clearer + * Made ArNetworking timeouts for To as well as From, these relate to if the data + is backing up and is to prevent extreme memory usage that could + kill the program, and would happen if a connection from a + client/robot/centralServer wouldn't take more data but didn't get + closed (which is really a networking problem) + * Added support for Trimble AgGPS, improved ArGPS class interface. + * NMEA parser (used for GPS and compass data) is now available seperately + for use with other NMEA devices as needed. + * Information about laser height and a possible second laser may be given + in robot params (won't generally be used for most robots). + * More optional diagnostic logging, especially in ArMutex objects + * Added "odometer" and "trip odometer" to ArRobot. These keep track of total + distance travelled and turned over the course of the program run. + "Trip" odometer may be reset at different events. + + + + +Aria 2.5.1 +February 22, 2007 +--------------------------- + + * Adds support for gyro-corrected heading automatically calculated by + the microcontroller firmware (requires updated firmware), and for + obtaining the odometry calculation delay (firmware's delay between + reading odometers and reporting heading and pose to to the + client). If the firmware supports it, ARIA now normally uses the + firmware's integrated gyro heading rather than calculating it on + the client side. + * Fixes memory leak in ArNetworking (some stored packets were not + deleted if ArNetPacketSenderTcp was destroyed) + * Fixed method declarations in ArSystemStatus to be legal C++ and + work with GCC 4 + + + +Aria 2.5.0 +December 1, 2006 +--------------------------- + +Important Changes and Bug Fixes: + * The ArServerHandlerMapping start and end mapping callbacks now have + the robot locked (they didn't used to) + * Modified ArPTZ so that the functions for pan and tilt take doubles + instead of integers so we can get finer grained movement, updated + ArVCC4, ArSonyPTZ, ArAMPTU, and ArDPPTU for this. Tested ArVCC4 + and ArSonyPTZ and they worked fine, if there are problems with this + or with the AMPTU or ArDPPTU send email to aria-users. Modified + ArServerHandlerCamera to fix for the change too. + * ArNetworking: Removed some functions from ArServerInfoStrings to manually + add items. Instead, ArServerInfoStrings receives data from Aria's new + ArStringInfoGroup global data store. + * ArActionDesired behavior changed slightly in that now for the + transMaxVel, transNegMaxVel, transAccel, transDecel, rotMaxVel, + rotAccel, and rotDecel can now just use the slowest value (so that + if you have multiple things trying to set a maximum speed they + don't have to coordinate each can just set the slowest and the + slowest is what is used) (note of course that decel uses the + fastest decel instead). You can specify the old behavior when you + do the sets on these if you want to (its not recommended and won't + work with the built in actions). + * All libraries are built with -fPIC for greater binary compatability when + linking at runtime. + * Added Aria::parseArgs() and Aria::logOptions(), and the functions + Aria::addParseArgsCB() and Aria::addLogOptionsCB() for classes/modules + to add functors that parseArgs() and logOptions() call; modified all + the things that parse arguments and log options to use these new functions + (old code will still work since the functions still work when called directly, + but this usage is deprecated) + * ArNetworking: ArServerBase and ArClientBase should be threadsafe, + you shouldn't need to worry about locking and unlocking them when doing + things and may cause problems if you do + * ArServerBase::broadcastPacketTcp and + ArServerBase::broadcastPacketUdp will no longer take clients to not + send the data too, this is because that behavior does not work with + the central server... there's now a WithExclusion command for each + of these if you need that behavior (its not recommended) + * Python wrapper now requires Python 2.4, except on RedHat 7.3 where it + still uses Python 2.2 (which is the last Python released for RHL). + You can install python2.4 if on Debian, or download for Windows or other + systems at . + +Enhancements: + * Added new ArSonarAutoDisabler that turns off the sonar if the + robot is stopped for a period of time and re-enables them when the robot + moves; ArNetworking's ArServerModeStop no longer turns off the sonar. + * Made ArArgumentParser::loadDefaultArguments so it can put them in + something other than the first position + * Modified ArConfig so that it can save unknown sections and + parameters, so that information isn't lost if nothing knows about it + this run + * Added ArActionDriveDistance, an action which will just take a + distance and drive forward that distance + * ArNetworking: Added ArServerMode::setWillUnlockIfRequested and + getWillUnlockIfRequested to get the info about whether we'll unlock + if requested or not (so other things can tell if docking is forced + or not) + * ArNetworking: Added code so that ArServerMode can keep track of + which data (commands) belong to which mode and a test program for + that (ArNetworking/tests/modeInfoClient.cpp) and added the new call + to ArServerMode::addData to all existing ArServerModes. + ArNetworking clients can get this information + * Added new simulator commands to ArCommands enum + * Added support for SICK reflectance (for reflector markers); also + added support for retrieving extended-info laser packets from the + simulator (which contain reflectance information) + * ArNetworking: Added boolean to ArServerMode::lockMode (defaults to + old behavior) which indicates if the mode will unlock if requested + or not and added ArServerMode::willUnlockIfRequested to get the + info about whether we'll unlock if requested or not + * ArNetworking: Added code to ArServerBase so that clients can get + which mode is active and if its locked or not, and if it'll unlock + if requested or not + * New class ArSystemStatus (for Linux only). + * Modifed some code in ArKeyHandler and ArNetworking/ArNetpacketReceiverTcp + so that they'd work better on Mac OS X + * There's now network usage tracking in ArNetworking (by packet type) + see logTracking and resetTracking in ArServerBase, there's also an + ArServerSimpleServerCommands that'll let you do these things over + the network + * Fixed a crash bug on shutdown with adding actions to ArActionGroups + then deleting them + * Fixed the Aria::signalHandlerCB and Aria::exit so that it + couldn't loop anymore (previously it would loop if you did an + Aria::shutdown and that caused a segfault) + * Added ArServerClient::hasGroupAccess so that an ArNetworking call + can check to see if a client has access to some group, note that + this is generally not needed since the command won't be called if + the user doesn't have access to that group (its for the next enhancement) + * Made ArServerModeRatioDrive so that if a user didn't have access to + unsafe drive mode and tried to drive the robot while it was in + unsafe mode the mode would kick back over into safe driving mode + * Made ArSickLogger so that it takes in a robot joy handler too and + changed the way it takes goals a little, now if you press a button + for a goal you have to let it go before another goal is taken (this + is instead of a time/distance/turn based check) Also changed it so + that if you were adding goals it'd only check if you had a + keyhandler, it wouldn't add a keyhandler + * Made ArServerModeMapping so that when it makes a new ArSickLogger + it passes in Aria::getJoyHandler and Aria::getRobotJoyHandler as + well as now telling it to add goals + * ArServerHandlerCamera now has different modes and can look at goals + as it is driving to them, look at points, and can adjust its + position relative to the image, and some commands to set the + position on the camera but play well with the modes while doing + it... + * Added ArNetServer calls to send to a specific client, this is so + that one doesn't have to worry about if the socket was closed or + not... this may have a better method later + * Added some calls to the ArServerHandlerConfig to make it a little + more generically usable + * Added requestOnceUdp and findCommandByName to ArClientBase + * Added examples/gotoActionExample.cpp + * Added ArRobot::getRobotLengthFront and ArRobot::getRobotLengthRear + with associated entries in the parameters file, if either value is + zero then it will be set to half of the robot length + * Added ArRobot::getAbsoluteMaxTransAccel, + ArRobot::getAbsoluteMaxTransDecel, ArRobot::getAbsoluteMaxRotAccel, + and ArRobot::getAbsoluteMaxRotDecel which will report the top + values (accel and decel are the same on the pioneers now but + someday may not be)... these (like the versions for the max vels) + are set from the config packet if its there, otherwise they are set + to an arbitrary value (unlike the max vel ones which come from a + param file).... made ArActionMovementParams use this value + * ArMapObject now has getFromToSegments which can get the rotated + line segments so that everyone doesn't have to calculate the + rotated rectangles on their own + * New ArGPS, ArGPSConnector and ArNovatelGPS classes to receive data + from Global Positioning System devices, and the Novatel ProPak G2 + in particular. + * Made ArRobot so that it has a new method isTryingToMove that is set + to true if the robot is trying to move even if it isn't moving + (this is mainly for where the robot isn't moving because an action + is stopping it from hitting something), there's a forceTryingToMove + to go with this for things that want the robot always look like its + trying to move + * Made ArSonarAutoDisabler so that it'd use the new isTryingToMove + flag and so that it would assume its the only thing changing the + sonar, since the ArRobot::areSonarEnabled will return false if the + robot has no sonar, or if they are disabled + * Added a flag to range devices so they can say if they're location + dependent or not (for use with the next enhancement) + * Added a flag to the ArRobot functions that check all the range + devices to say whether to ignore range devices that are location + dependent (so that its easy to say ignore forbidden lines from the + robot joystick) + + +Aria 2.4.3 +December 7, 2005 +--------------------------- + + Uses -fPIC flag when building Linux shared libraries for greater compatability. + +Aria 2.4.1 +October 14, 2005 +--------------------------- + +Fixes: + * Moved accessors for protected static members in ArSoundPlayer out of header file + (MSVC tried to inline them, and failed to link because the members were not + exported from the DLL) + +Aria 2.4.0 +September 15, 2005 +--------------------------- + + +Fixes: + * Made ArActionDeceleratingLimiter honor the UseEStop flag + * Changed ArSignalHandler_LIN to work with the newer + Linux kernels/libs (e.g. in Debian), changes are documented in runThread + for the curious (It seems that if you try and hit control c in near the + time of a system call sometimes it will break signal handling but that + looked like it happened before this revision too) + * Improvements to ArSocket so that it doesn't try and look up + localhost when it opens (since it uses INADDR_ANY anyways, and all + the look up would do is slow down things on some machines without + DNS setup), also in Linux a failed lookup on a host will no longer + then try localhost (it never should have) + * Changed ArAnalogGyro so that if it got no encoder readings from + the robot but did get readings from the gyro that it would just use the + gyro readings + * Revamped ArActionInput... + * removed deltaHeading and deltaVel function from ArActionInput + (since they weren't used and are broken), if you need them send + email to the aria-users list and we'll put it (or something that + takes care of that function) back in... + * added setHeading and made the stuff there simpler + * Made it so that sonar readings are set to be ignored until they have gotten + data + +Important Changes: + * If ArRobot can't find a parameter file for a robot AND has no internal + parameters for the robot type, it will now fail the connection rather than + using (probably unsuitable) default values. + * The wrapper Java code is now distributed as Aria.jar and + ArNetworking.jar rather than separate .class files. + +Enhancements: + * Added access to ArRobot for the interpolated encoder position, this is + now used for the encoder pose on the SICK raw readings + (ArRobot::getEncoderPoseInterpPosition) + * ArSick::processPacket: the name and meaning of the deinterlacePose + is now deinterlaceDelta, I don't imagine anyone uses it except for + some internal code or I'd make it more backwards compatible + * Added ArServerInfoStrings to the ArNetworking library, it can send + arbitrary strings from a server out to MobileEyes for MobileEyes to + display + * Added the ability to log abitrary strings (ie like above) to + ArDataLogger + * Added ArConstFunctors and ArConstRetFunctors so that you could use + the above string functions with the const functions in ArRobot. + * NOTE: In a future release some currently non-const methods will become + const. + * Generalized some ArSoundsQueue callbacks. Some public methods have been deprecated. + addItem(ItemType, const char*, int) has been replaced by addItem(Item), and + createDefaultSpeechItem() and createDefaultFileItem() were added. + * Added a setIgnoreThisReading on the ArSensorReading class + * ArNetworking library now has Python and Java wrappers! (Thanks to Swig) + * Changed things a little so that ArRangeBuffer now additionally has + getClosestPolarInList and getClosestBoxInList so that you can do + these operations on arbitrary lists of readings (for instance from + transformed readings) more easily (you can also just make your own buffer) + * Added a targetPose to ArRangeBuffer box checking so that you can + see if a point is closer to someplace other than the robot + * ArArgumentParser functions now generally have arguments so you + avoid just get one argument (previously it'd always recurse and + find you the last argument) + + + + + +Aria 2.3.3 +May 31, 2005 +--------------------------- + +Fixes: + * Position mode can display some new flags + * Initialize a variable in position mode + + + +Aria 2.3.2 +May 24, 2005 +--------------------------- + +Fixes: + * Cleans up some warning messages seen in Windows + * Companion to ARNL 1.3-2 with important fixes. + * Fixes uninitialized variable in ArModePosition. + + +Aria 2.3.1 +May 23, 2005 +--------------------------- + +Fixes: + * Fixed a bug in the filtering of ArRangeDevice readings that caused odd + behavior in Windows + * Put a log message into the default signal handling if exit was occuring + +Enhancements: + * Modified ArServerModeStop so it doesn't always turn off sonar when stopped + (depends on an argument in the constructor), SONARNL uses the new behavior + so that you don't need to move before you can localize + + +Aria 2.3.0 +May 16, 2005 +---------------------------- + +Critical Changes: + + * Aria::exit has been enhanced with callbacks (see Aria::addExitCallback) + and will now just exit the program instead of trying to get threads to cooperate. + * This has been made the default way to exit on signals (segfaults + and control C for instance). + * Exit has also been made the default way that ArRobot will call if escape is + pressed to shut things down (see ArRobot::setKeyHandler for the + way to use the old behavior). + * Aria::init and ArRobot::ArRobot now have new parameters to control + this behavior. Java code will require updating for this new parameter. + This is so that things can be more consistent between programs and exit + conditions with less code required in the programs, generally it just works + better. + * SRIsim binary has been removed. Use MobileSim instead. + * MS Visual C++ 6 project files have been moved into the vc++6 subdirectory, + and are no longer maintained. Use Visual C++ 7.1 (.NET) instead. + +Fixes: + * Bug fix in ArSoundsQueue::resume(). + * ArFileParser can now remove its remainder handlers in remHandler + +Enhancements: + * ArMap now deals with lines (for SONARNL, MobileSim, etc.) + * ArMap now deals with RouteInfo (for ARAM, just ignore for Aria and Arnl) + * Added ability to track velocities coming back from the robot, see + ArRobot::setLogVelocitiedReceived, also added it to + ArServerSimpleComMovementLogging + * Added ability to track packets received and sent more easily, see + ArRobot::setPacketsReceivedTracking and + ArRobot::setPacketsSentTracking. Also added these to the + ArServerSimpleComMovementLogging. + * polySegments shape added to ArDrawingData + +Aria 2.2-0 +March 29, 2005 +---------------------------- + +Critical Changes: + * Sonar position parameters are now given from center of rotation + * Replaced old ArSpeech library with three new rewritten libraries. + +Fixes: + * Bug fix in ArNetworking TCP packet sender which might have caused some + data to be lost + * Removed problematic methods ArPTZ::getReal{Pan,Tilt,Zoom} + * Removed all the references to using a std::string in ariaUtil's ArUtil + that would allocate or modify memory since if used in windows dll's + these'll cause major problems, made them take char *, + ArUtil::splitString is removed (use ArArgumentBuilder), commented out + stripDir and stripFile since they have problems and it doesn't seem + worth fixing + +Enhancements: + * ArRobot returns the actual battery voltage from the robot (Rather than + scaling to 13v) if you call ArRobot::getRealBatteryVoltage and have a + recent OS on the microcontroller (otherwise gives the scaled value) + * New robot parameter files for SH-based robots (p3dx-sh, p3at-sh, + patrolbot-sh, peoplebot-sh, powerbot-sh). Fixed P3AT's laser Y position + to 0. + * ArConfig: improved error handling, sections now operate fully and permit + the same parameter in multiple sections to be handled properly. + * New ArUtil and ArMath functions: findMax, findMin, log2, isOnlyAlphaNumeric + * ArActionTriangleDriveTo improved for greater accuracy + * ArRobot::getRobotLength() and ArRobot::getRobotWidth() added + * ArActionMovementParameters added, it can set all the vels and accels/decels + in the action so that you can have different action groups drive more + differently easier + * New Joydrive and Input classes (ArActionRatioInput and ArRatioInput*), + and server mode and handlers in ArNetworking for "Ratio drive", + to which you give front/back/left/right percentages of a maximum velocity. + Server can also enable/disable safe drive mode. + * New ArRobotJoyHandler class for getting joystick information from recent + OS on the microcontroller + * New ArNetworing classes: ArServerSimpleOpener, ArClientSimpleConnector. + * New class: ArActionGotoStraight + * New class: ArDataLogger + * Changed ArRobot::moveTo to keep range devices locked the whole time its + modifying things and now it doesn't use applyTransform (which probably + shouldn't be used) + * Added new action ArActionDeceleratingLimiter which will crank up the + deceleration to avoid a collision if it needs to (up to throwing an estop) + * New ArActionGroupNewInput using the new ArioInput + * New ArSoundsQueue and ArSoundPlayer classes + * New speech synthesis and recognition design, with implementations using + Festival and Cepstral (synthesis) and Sphinx (recognition) in separate + libraries. Aria now has a common base class for synthesis, ArSpeechSynth. + (Replace old ArSpeech library) + * ArKeyHandler supports more special function keys + * ArSimpleConnector may be used in Java and Python by passing in the + language's normal argv object (main() argument in Java, sys.argv in Python) + * New classes in ArNetworking in ArServerFileUtils and ArClientFileUtils for + transfering files over the ArNetworking connection, really only works in + Linux (and is mostly for the new feature in Mapper3) + * User and password information can now be required to connect with + ArNetworking, see the ArNetworking overview in the documentation for more + details (and ArNetworking/examples/serverDemo.userInfo); + +Aria 2.1-3 +October 12, 2004 +---------------------------- + * Special prerelease, with various Aria changes, and new ArSpeech_* setup [reed] + +Aria 2.1-2 +?? +---------------------------- + * Special prerelease? + +Aria 2.1-1 +23 August 2004 +--------------------------- + + ? + +Aria 2.1 +11 August 2004 +---------------------------- + + ArRangeDevices now have some information about how they should be + drawn in programs like MobileEyes (see the ArNetworking notes on + ArServerInfoDrawings). See setCurrentDrawingData and + setCumulativeDrawingData. + + ArTCM2 class added to handle the TCM2 compass. + + ArRobot now has information about the IR on a robot (stored in the .p + files). + + ArSick can now ignore readings at certain angles (stored in the .p + files). + + demo now has a command mode which will send commands down to the robot + directly. This stops state reflection (with the new + ArRobot::stopStateReflection) so you can send motion commands to the + robot without problems. + + demo's position mode can now activate and deactivate the gyro and now + has a mode where it can control just one of heading or velocity. + + demo now has a mode for viewing the TCM2 compass data. + + New range devices, ArForbiddenRangeDevice (makes forbidden lines in a + map into range device readings), ArBumpers (makes bumper triggers into + range device readings), and ArIRs (makes IRs into range device + readings). + + You can now activate and deactivate the ArAnalogGyro. + + ArActionBumpers now works dynamically with differing bumper numbers. + + ArArgumentBuilder will now take a set of strings (addStrings) and will + allow you put put them a particular place in the list. + + ArArgumentParser will now let you load default arguments that will + then be parsed as if passed in on the command line + (loadDefaultArguments loads these). This is for things like passing + in the robot port or laser port to all your programs. See the class + description for more details. Aria::init and Arnl::init add files to + the list, for Aria its the file /etc/Aria.args and environmental + variable $ARIAARGS and for Arnl it adds /etc/Arnl.args and + environmental variable $ARNLARGS. The parser therefor has a function + checkHelpAndWarnUnparsed to call instead of the old check against + argc. If you use this new feature you'll want to check against + parser.getArgc if you care about variable count since after + loadDefaultArguments is called the parser will no longer be using + the argc passed in (since it had to add). + + ArSimpleConnector can now configure a sick to use the different number + of degrees and the different increments. + + ArVCC4 can now handle some other Cannon camera types. + + Changed things to check #ifndef WIN32 instead of #ifdef linux to make + things easier for people using Aria on non linux but still unix + platforms. + + The priorities for ArConfig are now different (there are only 3). + + ArNetworking Changes + -------------------- + + ArServerInfoDrawing takes range devices (or all the range devices on a + robot) and provides it through an ArNetworking server (to draw in MobileEyes). + They will then be drawing by MobileEyes. The supported types + right now are PolyDots (takes a list of points and draw dots of a + given size at those points), PolyPoints (takes a list of points and + draw small points at those points), PolyLine (takes a list of points + through which it draws a line), PolyArrow (takes a list of points + through which it draws arrows pointing at the robot). + ArServerInfoDrawing can also just take a functor which'll return a + packet to draw so that you can draw whatever arbitrary information you + like. + + ArServerHandlerCommands provides a list of commands through the ArNetworking + server, and calls a functor or a functor with string argument when the command + is received (These are displayed as "Custom Commands" in MobileEyes). + + ArServerSimpleCommandsUC is a class which will hook into + ArServerHandlerCommands and let you send commands to the + microcontroller (uC). Note that if you use motion commands with this + the ArRobot state reflection on the server is still going on so you'll + want to hold enter (for the tool) or control s (for the toolbar) in + MobileEyes. + + New ArServerHandlerCamera class to control an ArPTZ through ArNetworking + + ArHybridForwardVideo will connect to a running video server and + forward video from that server out through its server. + These video servers are either our color tracking + software (ACTS, purchased separately) or our SAV (software a/v) + transmission software (free to all our customers). + + ArClientBase::logDataList will now log not only the name and + description of the data available but also the return description and + argument description. + + ArNetPacket now has doubleToBuf and bufToDouble. + + ArServerHandlerMap now optionally take a map instance in the + constructor in which case it won't worry about loading a map itself + and will instead use the given map (and hook into the its map + reloaded callback). + + ArConfig information can be passed from the server to the client and + vice versa now. MobileEyes has a GUI editing tool for configuration + data (ARNL guiServer lets people edit arnl.p). + + ArClientBase requestOnceWithString does a request once on the given + name using a packet with the string passed in put in the buffer. + + + + +Aria 2.0 +11 February 2004 +---------------------------- + + ArNetworking library added! ARNL and MobileEyes were also released. + + ArConfig now a new class ArConfigArg instead of ArArg, ArConfigArg can + also makememory to hold things and is more set up for working with + ArNetworking (and hides some things from people just trying to use the + base ArArg stuff). ArConfig::writeFile now writes priorities of the + config out but has a parameter not to. + + ArConfig now has sections to it and doesn't need to be subclassed + from, there is also an Aria::getConfig so that you can have one config + for all the options in a program without as much coordination + required. + + The demo program and ArSimpleConnector now have shortcuts for arguments + along with a new flag -connectLaser which will have it connect the + laser (only in demo and ArNetworking example serverDemo right now). + You can also now just pass one hyphen (-) but two (--) will still work + fine. + + The simulator will now use rotational and translational accelerations + and decelerations independently and respond appropriately to these. + Previously rotational acceleration was linked to translational + acceleration and there was no deceleration parameter as acceleration + parameter was used for deceleration too. If you set the accel/decel + params in your robot's parameter file these will be sent to the + simulator which will respond appropriately. Note that too large + values will cause the simulator to act erratically. + + ArRangeDevice now has generic code to keep current and cumulative + readings. + + Signal handling should work appropriately now. + + New params in the parameter file. GyroScaler and LaserTh, RobotWidth + and RobotLength. GyroScaler is used with an ArAnalogGyro to calibrate + it (figure out the error and then adjust this scaler to compensate). + + There is new code in that deinterlaces sick laser readings if you are + operating at 1/2 degree increments (the reading aren't interlaced with + any other mode). Mapping does not yet take advantage of this. + + ArArgumentParser has some new functions to make life easier and now + tries parsin with a - extra) + + ArUtil has a few new functions e.g. ArUtil::atof which deals with inf + and -inf correctly (to help Windows). + + ArNetServer can log data sent and received. + + ArRobot has some new functions (requestIOPackets, stopIOPackets, + requestEncoderPackets, stopEncoderPackets, getIOAnalogVoltage (which + like all the getIO calls you need to call requestIOPackets to use), + getLeftEncoder and getRightEncoder (which you have to call + requestEncoderPackets to use)) + + There's a new class ArLineFinder which finds lines from a range device + that puts in rawReadings which at this point is really only the ArSick + class. It will find the lines in a reading which can be used to do + different things. ArActionTriangleDriveTo now exists which uses this + class, these are used with the docking stations that we have. + + Other miscellaneous small fixes. + + + +Aria 1.3-2 +8 September 2003 +---------------------------- + + RequestIOPackets was on for all robots instead of just the newer + PeopleBots which wound up sending too much data and broke a few + things. Its off now except for the PeopleBots that need it, but the + following fixes are in place so that things will still work well with + that amount of data. + + Before if you had a lot of data (a gyro, lots of sonar data, and were + requesting IO) you could wind up where Aria would spend all of its + time receiving data and none doing anything with it, this was only at + 9600 baud and more data than most people ever send back and forth. It + did this because it tried to process all incoming data before running + its loop, now it'll only try to do this for a half a cycle's worth of + time. + + The warning messages for when things take too long now clearly + indicate that they are in fact merely warnings. + + A new release of AROS should be out this week, if you are using this + version (1.9) or newer and are connecting over a serial port the + connection will be automatically shifted up to 38.4 baud after the + connection is made. Aria sends a command to the robot to tell it to + change baud rates, then changes its own baud rate in reflection. If + either side doesn't hear from the other for a half second it fails + back over to the previous baud rate. You can disable this behavior by + changing SwitchToBaudRate to 0 in your parameter files. You can also + set it higher (up to 115200) if you wish, you must use the normal baud + rates of 9600 19200 38400 56800 or 115200. + + +Aria 1.3 ? +11 August 2003 +---------------------------- + + (BasicSuite Mapper and LaserMapper (ScanStudio) were both also released) + + Code for the new gyroscopic correction system is integrated in with + the base level Aria code. The class is ArAnalogGyro. If your robot + has a gyro mode then in the Aria demo in position mode the raw gyro + and raw robot headings will show up. + + ArRobot now requests a configPacket from the robot after it connects + and waits for that before saying it is connected (it times out within + a few seconds so it will work okay with pioneer 1s and other old + robots, but everyone with anything but a pioneer 1 should get the new + AROS or P2OS version since it has one critical bug fix). + + ArActions have gotten a major upgrade as they can now set the + accelerations and decelerations the robot uses. The values an action + sets will be used as long as an action sets an accel, decel, or rot + vel max when an action isn't setting them anymore these values all + reset to the values the robot had at connection (the reason the + configPacket reader was implemented). trans vel max is still taken + care of in software. You can also set these values on the robot so + that ArRobot will ignore the ones from the configPacket, look at + setRotVelMax, setRotAccel, setRotDecel, setTransVelMax, setTransAccel + and setTransDecel. You can now also use rot vel with the actions, + note that this does not mix at all with the heading modes and that + whichever mode is used first is what will be used the other will be + ignored. + + ArRobot has a stabilizing time that can be set with + ArRobot::setStabilizingTime so that it will wait a set amount of time + after the initial connection is made before saying it is connected and + calling the connect callbacks. This stabilizing time right now is + only used for the gyro (since needs to find the center while the + robots not moving before it can be used). + + There is now a warning time for the robot cycle time + (ArRobot::setWarningTime). If the robot sync tasks take longer than + this time a warning is issued. If any individual task takes longer + then that task is also warned over. Default is 200 ms, 0 disables it. + + The sick filtering code has been changed. Look at that class for + specifics but one main thing is that readings will now be filtered and + thrown away if they are too old, but this like all filtering is + configurable. There was code that ignored some readings on the sides + of the robot but this was gotten rid of since it sometimes caused + trouble because it would sometimes hold readings that should have been + discarded. + + New class called ArConfig for having configuration + files of different sorts, the mechanism that reads/writes .p files was + overhauled to use this instead of the old ArPref* system that has been + removed. The new system is much more robust and usable than the old + system. + + The wrapper.i file needed for rebuilding the Java and Python wrappers + is now included. If you have any trouble with the wrappers in the + stock Aria please send me an email. + + The demo and anything using the ArSimpleConnector can now change the + baud by using the switch --robotBaud in the command line. + + The code for ArVCC4 has been upgraded a little bit and now has the + ability to enable or disable the getting of the position from the + camera. + + The option not to do state reflecting has been removed from the + constructor since no one I'd heard of used it and it was making things + too complicated for little benefit. + + The general Aria static class now has functions for setting and + getting ArJoyHandlers like it has for key handlers. + + ArUtil had strcasecmp functions added for comparing the cases of + strings and char *s without paying attention to case. Also has a + function call to convert a value to true or false for easier + logging/understanding. There's also a function to lower an entire + string. + + A few other minor bug fixes and additions. + +Aria 1.2 +4 March 2003 +---------------------------- + + Aria now supports Java and Python (Wrappers generated by Swig). + A number of names of member functions have changed to accomodate this + (since they were keywords in one of these languages). The most important + one is that the different print members are now called log (since thats + what they do). + + There are a couple of more complicated features that don't work yet in + these languages. The only unimplemented feature of SWIG is virtual + function overloading which means that you will not be able to make + your own ArActions in Java or Python, but you can always add them to + the C++ library and use them in Java or Python. + You also will not be able to make your own ArFunctors + for callbacks, but again where thats needed you can make objects in + the C++ library and use them in Java or Python. For this deficiency + language specific workarounds could likely be written by users, which + I could incorporate or if there are large numbers of people using + these wrappers we may develop these on our own. + + Also note with python, if you use non-interactive mode the program + will crash on exit. In interactive mode you should do + robot.disconnect(); Aria.shutdown() before you exit to avoid a crash, + or you can add these to the simple.py for non-interactive mode. + + Note that there are no Java or Python wrappers for anything but Aria. + If people use this wrapper and want wrappers for the other packages I + will probably make them. If you use either of the wrappers and have + feedback about it, feel free to send it to me. + + ArSick now has a cumulative buffer (it had none before) which + is filtered for readings that the laser doesn't see anymore (ie + transient obstacles). + + ArRangeDevice now has a buffer that is ArPoseWithTime instead of + ArPose, people may need to change their iterators. Cumulative + readings older than a certian time can now be flushed. + + Accessors in Aria are now const. Some functions have both a const and + non const function. No one should really even notice this except for + the people who want to use it. + + The Cannon VCC4 camera got an improvement in that it now uses + bidirectioncal communication. + + New ArSimpleConnector class that should make it easier to connect to + the simulator or real robot with an ArRobot or ArSick. Also supports + the command line options the demo uses. It is used in + examples/demo.cpp examples/wander.cpp examples/teleop.cpp + examples/sickWander.cpp examples/sickTeleop.cpp. + + As always there were more bug fixes and improvements. + + +Aria 1.1-11b +29 Jan 2003 +--------------------------- + + * Fixes errors in windows packages + +Aria 1.1-11 +23 Jan 2003 +---------------------------- + + ? + +Aria 1.1-10 +13 November 2002 +---------------------------- + + ? + +Aria 1.1-8 +10 October 2002 +---------------------------- + + ? + +Aria 1.1-7 ? +5 September 2002 +---------------------------- + + * The addition of new robot types for use with the new H8 controller + * Preventing the robot from jumping to the origin on connect + * Fixed a memory leak in ArBasePacket + * Fixed a corrupted file in the Windows distribution of ArSpeech. + + +Aria 1.1-5 ? +12 July 2002 +---------------------------- + + This mostly fixes some problems with sonars from an over-agressive other + bug fix I did. It didn't process the last parameter of the sonar and + wound up thinking it was pointing forward (0, 0, 0). It has a few + other small fixes but nothing major (some previous parsing errors used + to crash Saphira but Kurt fixed it so it didn't). + + This may fix the sonar localization issue reported today, I'm not + sure. If not you can try doing an mcSetGauss after moving a robot + back to locate the samples there. If that works and it isn't an issue + let me know. + + +Aria 1.1-2 +10 May 2002 +---------------------------- + + * rewritten ipthru program (examples/ipthru.cpp) + * Fixes and minor additions + +Aria 1.1 +11 March 2002 +---------------------------- + + * ArSick class added to support the Sick laser rangefinder. + * New unified demo program that'll control basically everything on the + robot, gripper, camera, all that. + * New examples sickWander.cpp and sickTeleop.cpp which + demonstrate how to configure the laser. + + +Aria 1.0-3 +26 February 2002 +---------------------------- + + * ArActionGroup added. + * Minor bug fixes. + + +Aria 1.0-2 +?? +---------------------------- + + ? + +Aria 1.0-1 +?? +---------------------------- + + ? + + +Aria 1.0 +21 December 2001 +---------------------------- + + * First full, official ARIA release! + + * ArAction::run renamed to ArAction::fire + * Better documentation + * ArKeyHandler added + + +Aria 0.71 +8 November 2001 +---------------------------- + +Fix to the simulator in Windows + +Aria 0.7 +6 November 2001 +---------------------------- + +First public beta + +You can now do a setPort on an ArSerialConnection or ArTcpConnection +instead of having to open it... the robot connect will then open it +(and fail if it can't open it). The only time you really need to open +it yourself is if you want to do error checking and do different +things if the open fails. + +The sync loop now just waits in the packet handler all the time, and +the packet handler finally returns (which runs the main sync loop) as +soon as it gets a SIP from the packet. There is a flag to the ArRobot +contructor if you don't want to use this new behavior. + + +Aria 0.6 +13 September 2001 +---------------------------- + + * Internal beta + diff --git a/Legacy/Aria/CommandLineOptions.txt b/Legacy/Aria/CommandLineOptions.txt new file mode 100644 index 0000000..99c9236 --- /dev/null +++ b/Legacy/Aria/CommandLineOptions.txt @@ -0,0 +1,370 @@ + +ARIA 2.8.0 + +Summary of command line options + +Some classes in ARIA and ArNetworking check a program's run time options to +specify parameters and options. These options are used to configure run time +accessory device parameters (ports, speeds, etc.) used by ARIA; host names, +port numbers, etc. used by ArNetworking; and various other run time options. +Options may be given as program arguments on the command line, or globally +saved as defaults in the file /etc/Aria.args if on Linux, or in the ARIAARGS +environment variable. Arguments given on the command line may override some +internal defaults or values read from the robot parameter files. + +Note, an option will be available only in programs that instantiate an +object of the class that uses it. Some programs may also check for +program-specific command line options. + +Use the special "-help" command line option to cause a program to +print out its available options. + +A list of options used by each class follows. + + +ArRobotConnector +---------------- +Options for ArRobotConnector (see docs for more details): + +Robot options: +-remoteHost +-rh +-robotPort +-rp +-robotBaud +-rb +-remoteRobotTcpPort +-rrtp +-remoteIsSim +-ris +-remoteIsNotSim +-rins +-robotLogPacketsReceived +-rlpr +-robotLogPacketsSent +-rlps +-robotLogMovementReceived +-rlmr +-robotLogMovementSent +-rlms +-robotLogVelocitiesReceived +-rlvr +-robotLogActions +-rla + +ArLaserConnector +---------------- +Laser types and options may also be set in the robot parameter file. See the +ARIA reference documentation for details. + +If a program supports multiple lasers, then options for additional lasers +after the first are given by appending the laser number (e.g. -laserType2) +To enable use of a laser, choose its type with the -laserType options +(e.g.: -laserType lms2xx -laserType2 urg2.0) + +The default laser type for the primary laser (laser 1) is specified in the +robot type parameter file in the ARIA "params" directory. For many robots +it is "lms2xx", the SICK LMS200. For some it is "lms1xx", for the SICK +LMS100 or LMS111. + +Instruct a program to connect to a laser using the -connectLaser option +or by setting LaserAutoConnect to true in the robot's parameter file. +If a program requires use of a laser it usually always attempts to connect to +the primary laser, however. + +The index number is optional in any options for the primary laser; i.e. 1 is +assumed if the index number is omitted. + + + +For laser type "lms2xx" (SICK LMS-200): + +-laserPort +-lp +-laserPortType +-lpt +-remoteLaserTcpPort +-rltp +-laserFlipped +-lf +-laserMaxRange +-lmr + is an unsigned int less than 32000 +-laserDegrees <100|180> +-ld <100|180> +-laserIncrement +-li +-laserUnits <1mm|1cm|10cm> +-lu <1mm|1cm|10cm> +-laserReflectorBits <1ref|2ref|3ref> +-lrb <1ref|2ref|3ref> +-laserPowerControlled +-lpc +-laserStartingBaud <9600|19200|38400> +-lsb <9600|19200|38400> +-laserAutoBaud <9600|19200|38400> +-lab <9600|19200|38400> +-laserAdditionalIgnoreReadings +-lair + is a string that contains readings to ignore separated by commas, where ranges are acceptable with a -, example '75,76,90-100,-75,-76,-90--100' + +For laser type "lms1xx" (SICK LMS-100, LMS-111, etc.): + +-laserPort +-lp +-laserPortType +-lpt +-remoteLaserTcpPort +-rltp +-laserFlipped +-lf +-laserMaxRange +-lmr + is an unsigned int less than 20000 +-laserDegreesStart +-lds + is a double between -135 and 135 +-laserDegreesEnd +-lde + is a double between -135 and 135 +-laserIncrement +-li +-laserReflectorBits +-lrb +-laserPowerControlled +-lpc +-laserAdditionalIgnoreReadings +-lair + is a string that contains readings to ignore separated by commas, where ranges are acceptable with a -, example '75,76,90-100,-75,-76,-90--100' + +For laser type "urg2.0" (URG with SCIP 2.0): + +-laserPort +-lp +-laserPortType +-lpt +-remoteLaserTcpPort +-rltp +-laserFlipped +-lf +-laserMaxRange +-lmr + is an unsigned int less than 262144 +-laserDegreesStart +-lds + is a double between -180 and 180 +-laserDegreesEnd +-lde + is a double between -180 and 180 +-laserIncrementByDegrees +-libd + is a double between 0 and 180 +-laserStartingBaud <0|019200|057600|115200|250000|500000|750000> +-lsb <0|019200|057600|115200|250000|500000|750000> +-laserAutoBaud <0|019200|057600|115200|250000|500000|750000> +-lab <0|019200|057600|115200|250000|500000|750000> +-laserAdditionalIgnoreReadings +-lair + is a string that contains readings to ignore separated by commas, where ranges are acceptable with a -, example '75,76,90-100,-75,-76,-90--100' + +For laser type "urg" (URG with old SCIP 1.0): + +-laserPort +-lp +-laserPortType +-lpt +-remoteLaserTcpPort +-rltp +-laserFlipped +-lf +-laserMaxRange +-lmr + is an unsigned int less than 4095 +-laserDegreesStart +-lds + is a double between -135 and 135 +-laserDegreesEnd +-lde + is a double between -135 and 135 +-laserIncrementByDegrees +-libd + is a double between 0 and 135 +-laserStartingBaud <019200|057600|115200|250000|500000|750000> +-lsb <019200|057600|115200|250000|500000|750000> +-laserAutoBaud <019200|057600|115200|250000|500000|750000> +-lab <019200|057600|115200|250000|500000|750000> +-laserAdditionalIgnoreReadings +-lair + is a string that contains readings to ignore separated by commas, where ranges are acceptable with a -, example '75,76,90-100,-75,-76,-90--100' + +For laser type "lms5XX" (SICK LMS-500): + +-laserPort +-lp +-laserPortType +-lpt +-remoteLaserTcpPort +-rltp +-laserFlipped +-lf +-laserMaxRange +-lmr + is an unsigned int less than 20000 +-laserIncrement +-li +-laserReflectorBits +-lrb +-laserPowerControlled +-lpc +-laserAdditionalIgnoreReadings +-lair + is a string that contains readings to ignore separated by commas, where ranges are acceptable with a -, example '75,76,90-100,-75,-76,-90--100' + +For laser type "sZseries" (Keyence SZ): + +-laserPort +-lp +-laserPortType +-lpt +-remoteLaserTcpPort +-rltp +-laserFlipped +-lf +-laserMaxRange +-lmr + is an unsigned int less than 16382 +-laserDegreesStart +-lds + is a double between -135 and -135 +-laserDegreesEnd +-lde + is a double between 135 and 135 +-laserIncrementByDegrees +-libd + is a double between 0.5 and 0.5 +-laserPowerControlled +-lpc +-laserStartingBaud <9600|19200|38400|57600|115200|230400|460800> +-lsb <9600|19200|38400|57600|115200|230400|460800> +-laserAdditionalIgnoreReadings +-lair + is a string that contains readings to ignore separated by commas, where ranges are acceptable with a -, example '75,76,90-100,-75,-76,-90--100' + +For laser type "s3series" (SICK S-300, S-3000, etc.): + +-laserPort +-lp +-laserPortType +-lpt +-remoteLaserTcpPort +-rltp +-laserFlipped +-lf +-laserMaxRange +-lmr + is an unsigned int less than 20000 +-laserDegreesStart +-lds + is a double between -135 and -135 +-laserDegreesEnd +-lde + is a double between 135 and 135 +-laserIncrement +-li +-laserPowerControlled +-lpc +-laserStartingBaud <9600|19200|38400|57600|115200|230400|460800> +-lsb <9600|19200|38400|57600|115200|230400|460800> +-laserAdditionalIgnoreReadings +-lair + is a string that contains readings to ignore separated by commas, where ranges are acceptable with a -, example '75,76,90-100,-75,-76,-90--100' + +For laser type "tim3XX" (SICK TiM300): + +-laserPort +-lp +-laserPortType +-lpt +-remoteLaserTcpPort +-rltp +-laserFlipped +-lf +-laserMaxRange +-lmr + is an unsigned int less than 20000 +-laserDegreesStart +-lds + is a double between -135 and 135 +-laserDegreesEnd +-lde + is a double between -135 and 135 +-laserIncrement +-li +-laserReflectorBits +-lrb +-laserPowerControlled +-lpc +-laserStartingBaud <115200> +-lsb <115200> +-laserAdditionalIgnoreReadings +-lair + is a string that contains readings to ignore separated by commas, where ranges are acceptable with a -, example '75,76,90-100,-75,-76,-90--100' + +ArPTZConnector +-------------- +Common PTU and Camera PTZ options: + + -ptzType Select PTZ/PTU type. Required. Available types are: + dpptu + rvision + sony + vcc + vcc4 + vcc50i + -ptzInverted If true, reverse tilt and pan axes for cameras mounted upside down. + +Only one of the following sets of connection parameters may be given: + +For computer serial port connections: + -ptzSerialPort Serial port name. + +For Pioneer robot auxilliary serial port connections: + -ptzRobotAuxSerialPort <1|2|3> Use specified Pioneer robot auxilliary serial port. + +For network connections: + -ptzAddress
Network address or hostname for network connection. + -ptzTcpPort TCP port number for network connections. + +Parameters for multiple cameras/units may be given like: -ptz1Type, -ptz2Type, -ptz3Type, etc. +Some PTZ/PTU types may accept additional type-specific options. Refer to option documentation text specific to those types. + +ArGPSConnector +-------------- +GPS options: +-gpsType Select GPS device type (default: standard) +-gpsPort Use the given serial port (default: /dev/ttyS1) +-gpsBaud Use the given serial Baud rate (default: 9600) +-remoteGpsTcpHost Use a TCP connection instead of serial, and connect to remote host +-remoteGpsTcpPort Use the given port number for TCP connection, if using TCP. (default 8103) + +ArCompassConnector +------------------ +Compass options: +-compassType Select compass device type (default: robot) +-compassPort Serial port for "serialTCM" type compass. (default: /dev/ttyS3) + +ArSonarConnector +---------------- +Options for ArSonarConnector: +-sonarLogPacketsReceived +-slpr +-sonarLogPacketsSent +-slps + +Options shown are for currently set up sonars. Activate sonars with -sonarType option +to see options for that sonar (e.g. "-help -sonarType1 sonarMTX"). +Valid sonar types are: mtx + +See docs for details. + + diff --git a/Legacy/Aria/INSTALL.txt b/Legacy/Aria/INSTALL.txt new file mode 100644 index 0000000..ceef64b --- /dev/null +++ b/Legacy/Aria/INSTALL.txt @@ -0,0 +1,7 @@ + +To install the contents of this .tgz package in /usr/local, +run "make install" as the root user, or "sudo make install" +if you have the "sudo" tool. + +See README.txt for more information on getting started. + diff --git a/Legacy/Aria/LICENSE.txt b/Legacy/Aria/LICENSE.txt new file mode 100644 index 0000000..0158861 --- /dev/null +++ b/Legacy/Aria/LICENSE.txt @@ -0,0 +1,424 @@ + + ARIA + MobileRobots Advanced Robotics Interface for Applications + + License + +Note that this license applies to programs which use ARIA +via both dynamic and static linking or loading, including +dynamic loading and linking at runtime (e.g. using ArModule, +Windows LoadLibrary, Unix dlopen, or similar. In other words +if you have a plugin which uses ARIA in any way that plugin +must also be distributed under this license.) + +(Also note that the text of the GPL below is copyrighted by the +Free Software Foundation, but that the instance of code that it +refers to (ARIA) is copyrighted by ActivMedia Robotics +LLC and MobileRobots Inc.) + +----------------------------------------------------------------- + + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away +your freedom to share and change it. By contrast, the GNU +General Public License is intended to guarantee your +freedom to share and change free software--to make sure the +software is free for all its users. This General Public +License applies to most of the Free Software Foundation's +software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is +covered by the GNU Library General Public License instead.) +You can apply it to your programs, too. + + When we speak of free software, we are referring to +freedom, not price. Our General Public Licenses are +designed to make sure that you have the freedom to +distribute copies of free software (and charge for this +service if you wish), that you receive source code or can +get it if you want it, that you can change the software or +use pieces of it in new free programs; and that you know +you can do these things. + + To protect your rights, we need to make restrictions that +forbid anyone to deny you these rights or to ask you to +surrender the rights. These restrictions translate to +certain responsibilities for you if you distribute copies +of the software, or if you modify it. + + For example, if you distribute copies of such a program, +whether gratis or for a fee, you must give the recipients +all the rights that you have. You must make sure that +they, too, receive or can get the source code. And you +must show them these terms so they know their rights. + + We protect your rights with two steps: (1) copyright the +software, and (2) offer you this license which gives you +legal permission to copy, distribute and/or modify the +software. + + Also, for each author's protection and ours, we want to +make certain that everyone understands that there is no +warranty for this free software. If the software is +modified by someone else and passed on, we want its +recipients to know that what they have is not the original, +so that any problems introduced by others will not reflect +on the original authors' reputations. + + Finally, any free program is threatened constantly by +software patents. We wish to avoid the danger that +redistributors of a free program will individually obtain +patent licenses, in effect making the program proprietary. +To prevent this, we have made it clear that any patent must +be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, +distribution and modification follow. + + GNU GENERAL PUBLIC LICENSE +TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work +which contains a notice placed by the copyright holder +saying it may be distributed under the terms of this +General Public License. The "Program", below, refers to +any such program or work, and a "work based on the Program" +means either the Program or any derivative work under +copyright law: that is to say, a work containing the +Program or a portion of it, either verbatim or with +modifications and/or translated into another language. +(Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as +"you". + +Activities other than copying, distribution and +modification are not covered by this License; they are +outside its scope. The act of running the Program is not +restricted, and the output from the Program is covered only +if its contents constitute a work based on the Program +(independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the +Program's source code as you receive it, in any medium, +provided that you conspicuously and appropriately publish +on each copy an appropriate copyright notice and disclaimer +of warranty; keep intact all the notices that refer to this +License and to the absence of any warranty; and give any +other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a +copy, and you may at your option offer warranty protection +in exchange for a fee. + + 2. You may modify your copy or copies of the Program or +any portion of it, thus forming a work based on the +Program, and copy and distribute such modifications or work +under the terms of Section 1 above, provided that you also +meet all of these conditions: + + a) You must cause the modified files to carry prominent + notices stating that you changed the files and the date of + any change. + + b) You must cause any work that you distribute or + publish, that in whole or in part contains or is derived + from the Program or any part thereof, to be licensed as a + whole at no charge to all third parties under the terms of + this License. + + c) If the modified program normally reads commands + interactively when run, you must cause it, when started + running for such interactive use in the most ordinary way, + to print or display an announcement including an + appropriate copyright notice and a notice that there is no + warranty (or else, saying that you provide a warranty) and + that users may redistribute the program under these + conditions, and telling the user how to view a copy of + this License. (Exception: if the Program itself is + interactive but does not normally print such an + announcement, your work based on the Program is not + required to print an announcement.) These requirements +apply to the modified work as a whole. If identifiable +sections of that work are not derived from the Program, and +can be reasonably considered independent and separate works +in themselves, then this License, and its terms, do not +apply to those sections when you distribute them as +separate works. But when you distribute the same sections +as part of a whole which is a work based on the Program, +the distribution of the whole must be on the terms of this +License, whose permissions for other licensees extend to +the entire whole, and thus to each and every part +regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights +or contest your rights to work written entirely by you; +rather, the intent is to exercise the right to control the +distribution of derivative or collective works based on the +Program. + +In addition, mere aggregation of another work not based on +the Program with the Program (or with a work based on the +Program) on a volume of a storage or distribution medium +does not bring the other work under the scope of this +License. + + 3. You may copy and distribute the Program (or a work +based on it, under Section 2) in object code or executable +form under the terms of Sections 1 and 2 above provided +that you also do one of the following: + + a) Accompany it with the complete corresponding + machine-readable source code, which must be distributed + under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least + three years, to give any third party, for a charge no more + than your cost of physically performing source + distribution, a complete machine-readable copy of the + corresponding source code, to be distributed under the + terms of Sections 1 and 2 above on a medium customarily + used for software interchange; or, + + c) Accompany it with the information you received as to + the offer to distribute corresponding source code. + (This alternative is allowed only for noncommercial + distribution and only if you received the program in + object code or executable form with such an offer, in + accord with Subsection b above.) + +The source code for a work means the preferred form of the +work for making modifications to it. For an executable +work, complete source code means all the source code for +all modules it contains, plus any associated interface +definition files, plus the scripts used to control +compilation and installation of the executable. However, +as a special exception, the source code distributed need +not include anything that is normally distributed (in +either source or binary form) with the major components +(compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself +accompanies the executable. + +If distribution of executable or object code is made by +offering access to copy from a designated place, then +offering equivalent access to copy the source code from the +same place counts as distribution of the source code, even +though third parties are not compelled to copy the source +along with the object code. + + + + 4. You may not copy, modify, sublicense, or distribute +the Program except as expressly provided under this +License. Any attempt otherwise to copy, modify, sublicense +or distribute the Program is void, and will automatically +terminate your rights under this License. However, parties +who have received copies, or rights, from you under this +License will not have their licenses terminated so long as +such parties remain in full compliance. + + 5. You are not required to accept this License, since you +have not signed it. However, nothing else grants you +permission to modify or distribute the Program or its +derivative works. These actions are prohibited by law if +you do not accept this License. Therefore, by modifying or +distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to +do so, and all its terms and conditions for copying, +distributing or modifying the Program or works based on it. + + 6. Each time you redistribute the Program (or any work +based on the Program), the recipient automatically receives +a license from the original licensor to copy, distribute or +modify the Program subject to these terms and conditions. +You may not impose any further restrictions on the +recipients' exercise of the rights granted herein. You are +not responsible for enforcing compliance by third parties +to this License. + + 7. If, as a consequence of a court judgment or allegation +of patent infringement or for any other reason (not limited +to patent issues), conditions are imposed on you (whether +by court order, agreement or otherwise) that contradict the +conditions of this License, they do not excuse you from the +conditions of this License. If you cannot distribute so as +to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a +consequence you may not distribute the Program at all. +For example, if a patent license would not permit +royalty-free redistribution of the Program by all those who +receive copies directly or indirectly through you, then the +only way you could satisfy both it and this License would +be to refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or +unenforceable under any particular circumstance, the +balance of the section is intended to apply and the section +as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to +infringe any patents or other property right claims or to +contest validity of any such claims; this section has the +sole purpose of protecting the integrity of the free +software distribution system, which is implemented by +public license practices. Many people have made generous +contributions to the wide range of software distributed +through that system in reliance on consistent application +of that system; it is up to the author/donor to decide if +he or she is willing to distribute software through any +other system and a licensee cannot impose that choice. + +This section is intended to make thoroughly clear what is +believed to be a consequence of the rest of this License. + + + + 8. If the distribution and/or use of the Program is +restricted in certain countries either by patents or by +copyrighted interfaces, the original copyright holder who +places the Program under this License may add an explicit +geographical distribution limitation excluding those +countries, so that distribution is permitted only in or +among countries not thus excluded. In such case, this +License incorporates the limitation as if written in the +body of this License. + + 9. The Free Software Foundation may publish revised +and/or new versions of the General Public License from time +to time. Such new versions will be similar in spirit to +the present version, but may differ in detail to address +new problems or concerns. + +Each version is given a distinguishing version number. If +the Program specifies a version number of this License +which applies to it and "any later version", you have the +option of following the terms and conditions either of that +version or of any later version published by the Free +Software Foundation. If the Program does not specify a +version number of this License, you may choose any version +ever published by the Free Software Foundation. + + 10. If you wish to incorporate parts of the Program into +other free programs whose distribution conditions are +different, write to the author to ask for permission. For +software which is copyrighted by the Free Software +Foundation, write to the Free Software Foundation; we +sometimes make exceptions for this. Our decision will be +guided by the two goals of preserving the free status of +all derivatives of our free software and of promoting the +sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE +IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING +THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE +PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER +EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND +PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM +PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY +SERVICING, REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR +AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY +OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM +AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING +ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES +ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM +(INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY +OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS +BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of +the greatest possible use to the public, the best way to +achieve this is to make it free software which everyone can +redistribute and change under these terms. + + To do so, attach the following notices to the program. +It is safest to attach them to the start of each source +file to most effectively convey the exclusion of warranty; +and each file should have at least the "copyright" line and +a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it + and/or modify it under the terms of the GNU General + Public License as published by the Free Software + Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be + useful, but WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A + PARTICULAR PURPOSE. See the GNU General Public License + for more details. You should have received a copy of + the GNU General Public License along with this program; + if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic +and paper mail. + +If the program is interactive, make it output a short +notice like this when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of + author Gnomovision comes with ABSOLUTELY NO WARRANTY; + for details type `show w'. This is free software, and + you are welcome to redistribute it under certain + conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show +the appropriate parts of the General Public License. Of +course, the commands you use may be called something other +than `show w' and `show c'; they could even be mouse-clicks +or menu items--whatever suits your program. + +You should also get your employer (if you work as a +programmer) or your school, if any, to sign a "copyright +disclaimer" for the program, if necessary. Here is a +sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest + in the program 'Gnomovision' (which makes passes at + compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating +your program into proprietary programs. If your program is +a subroutine library, you may consider it more useful to +permit linking proprietary applications with the library. +If this is what you want to do, use the GNU Library General +Public License instead of this License. + + + diff --git a/Legacy/Aria/Makefile b/Legacy/Aria/Makefile new file mode 100644 index 0000000..0bad62a --- /dev/null +++ b/Legacy/Aria/Makefile @@ -0,0 +1,776 @@ +#### +#### Aria top level makefile +#### +#### +#### Internal variables: +#### +#### CFILEEXT -- This is to denote the file extension that is used. This is +#### used by the build rules to figure out which files to build. +#### ie: cpp +#### ie: cxx +#### ie: cc + +# Make sure we're using a compiler (we probably don't need to define +# it but we have been so here it is unless it was already set) +ifndef CXX +CXX:=g++ +endif + +#### +#### General variables +#### + +CFILEEXT:=cpp +# this is set up with the extra layer since the python wrapper needs exceptions +# but I didn't want to have two sets of defines +BARECXXFLAGS:=-g -Wall -D_REENTRANT #-pg -fprofile-arcs +CXXFLAGS+=$(BARECXXFLAGS) -fno-exceptions +CXXINC:=-Iinclude +CXXLINK=-Llib -lAria +CXXSTATICLINK:=-Llib -Xlinker -Bstatic -lAria -Xlinker -Bdynamic + +host:=$(shell uname | cut -d _ -f 1) +ifeq ($(host),MINGW32) + $(info Building on MinGW) + #CXXFLAGS+=-mwindows -mms-bitfields -D__MINGW__ -DMINGW + CXXFLAGS+=-mms-bitfields -D__MINGW__ -DMINGW + CXXLINK+=-lpthreadGC2 -lwinmm -lws2_32 -lstdc++ + CXXSTATICLINK+=-Wl,-Bstatic -lpthread -Wl,-Bdynamic -lwinmm -lws2_32 -lstdc++ + binsuffix:=.exe +else + BARECXXFLAGS+=-fPIC + CXXLINK+=-lpthread -ldl -lrt + CXXSTATICLINK+=-Xlinker -Bdynamic -lpthread -ldl -lrt -Xlinker -Bstatic -lstdc++ -Xlinker -Bdynamic + binsuffix:= +endif + + +ifndef JAVAC +ifdef JAVA_BIN +JAVAC:=$(JAVA_BIN)/javac +else +JAVAC:=javac +endif #ifdef JAVA_BIN +endif #ifndef JAVAC + +ifndef JAR +ifdef JAVA_BIN +JAR:=$(JAVA_BIN)/jar +else +JAR:=jar +endif #ifdef JAVA_BIN +endif #ifndef JAR + +#### +#### Aria build variables +#### + +# Default targets to build in the default rule: +TARGETS:=lib/libAria.so examples/demo$(binsuffix) + +# Default static libraries and examples: +STATIC_TARGETS:=lib/libAria.a examples/demoStatic$(binsuffix) + +# Lots of targets, to build in the everything rule: +ALL_TARGETS:=lib/libAria.so utils examples tests docs params lib/libArNetworking.so swig arnetworking_docs arnetworking_swig clib/libArNetworking.a $(STATIC_TARGETS) + +CFILES:= \ + ArAction.cpp \ + ArActionAvoidFront.cpp \ + ArActionAvoidSide.cpp \ + ArActionBumpers.cpp \ + ArActionColorFollow.cpp \ + ArActionConstantVelocity.cpp \ + ArActionDeceleratingLimiter.cpp \ + ArActionDesired.cpp \ + ArActionDriveDistance.cpp \ + ArActionGoto.cpp \ + ArActionGotoStraight.cpp \ + ArActionGroup.cpp \ + ArActionGroups.cpp \ + ArActionInput.cpp \ + ArActionIRs.cpp \ + ArActionJoydrive.cpp \ + ArActionKeydrive.cpp \ + ArActionLimiterBackwards.cpp \ + ArActionLimiterForwards.cpp \ + ArActionLimiterRot.cpp \ + ArActionLimiterTableSensor.cpp \ + ArActionMovementParameters.cpp \ + ArActionMovementParametersDebugging.cpp \ + ArActionRatioInput.cpp \ + ArActionRobotJoydrive.cpp \ + ArActionStallRecover.cpp \ + ArActionStop.cpp \ + ArActionTriangleDriveTo.cpp \ + ArActionTurn.cpp \ + ArACTS.cpp \ + ArAMPTU.cpp \ + ArAnalogGyro.cpp \ + ArArg.cpp \ + ArArgumentBuilder.cpp \ + ArArgumentParser.cpp \ + ArASyncTask.cpp \ + ArBasePacket.cpp \ + ArBatteryConnector.cpp \ + ArBatteryMTX.cpp \ + ArBumpers.cpp \ + ArCameraCommands.cpp \ + ArCameraCollection.cpp \ + ArCondition_LIN.cpp \ + ArConfig.cpp \ + ArConfigArg.cpp \ + ArConfigGroup.cpp \ + ArDataLogger.cpp \ + ArDeviceConnection.cpp \ + ArDPPTU.cpp \ + ArFileParser.cpp \ + ArForbiddenRangeDevice.cpp \ + ArFunctorASyncTask.cpp \ + ArGPS.cpp \ + ArGPSConnector.cpp \ + ArGPSCoords.cpp \ + ArGripper.cpp \ + ArInterpolation.cpp \ + ArIrrfDevice.cpp \ + ArIRs.cpp \ + ArJoyHandler.cpp \ + ArKeyHandler.cpp \ + ArLaser.cpp \ + ArLaserConnector.cpp \ + ArLaserFilter.cpp \ + ArLaserLogger.cpp \ + ArLaserReflectorDevice.cpp \ + ArLCDConnector.cpp \ + ArLCDMTX.cpp \ + ArLineFinder.cpp \ + ArLMS1XX.cpp \ + ArLMS2xx.cpp \ + ArLMS2xxPacket.cpp \ + ArLMS2xxPacketReceiver.cpp \ + ArLog.cpp \ + ArLogFileConnection.cpp \ + ArMap.cpp \ + ArMapComponents.cpp \ + ArMapInterface.cpp \ + ArMapObject.cpp \ + ArMapUtils.cpp \ + ArMD5Calculator.cpp \ + ArMode.cpp \ + ArModes.cpp \ + ArModule.cpp \ + ArModuleLoader.cpp \ + ArMutex.cpp \ + ArMutex_LIN.cpp \ + ArNetServer.cpp \ + ArNMEAParser.cpp \ + ArNovatelGPS.cpp \ + ArP2Arm.cpp \ + ArPriorityResolver.cpp \ + ArPTZ.cpp \ + ArPTZConnector.cpp \ + ArRangeBuffer.cpp \ + ArRangeDevice.cpp \ + ArRangeDeviceThreaded.cpp \ + ArRatioInputKeydrive.cpp \ + ArRatioInputJoydrive.cpp \ + ArRatioInputRobotJoydrive.cpp \ + ArRecurrentTask.cpp \ + ArRobot.cpp \ + ArRobotBatteryPacketReader.cpp \ + ArRobotConfig.cpp \ + ArRobotConfigPacketReader.cpp \ + ArRobotConnector.cpp \ + ArRobotJoyHandler.cpp \ + ArRobotPacket.cpp \ + ArRobotPacketReceiver.cpp \ + ArRobotPacketReaderThread.cpp \ + ArRobotPacketSender.cpp \ + ArRobotParams.cpp \ + ArRobotTypes.cpp \ + ArRVisionPTZ.cpp \ + ArS3Series.cpp \ + ArSZSeries.cpp \ + ArSick.cpp \ + ArSimpleConnector.cpp \ + ArSimulatedLaser.cpp \ + ArSocket.cpp \ + ArSonarConnector.cpp \ + ArSonarDevice.cpp \ + ArSonarMTX.cpp \ + ArSensorReading.cpp \ + ArSonyPTZ.cpp \ + ArSoundsQueue.cpp \ + ArSoundPlayer.cpp \ + ArStringInfoGroup.cpp \ + ArSyncLoop.cpp \ + ArSyncTask.cpp \ + ArSystemStatus.cpp \ + ArSonarAutoDisabler.cpp \ + ArSpeech.cpp \ + ArTCM2.cpp \ + ArTCMCompassDirect.cpp \ + ArTCMCompassRobot.cpp \ + ArTcpConnection.cpp \ + ArThread.cpp \ + ArThread_LIN.cpp \ + ArTransform.cpp \ + ArTrimbleGPS.cpp \ + ArUrg.cpp \ + ArUrg_2_0.cpp \ + ArVCC4.cpp \ + Aria.cpp \ + ariaUtil.cpp \ + md5.cpp + +# Omit some Linux-only classes, and replace others with Win32 implementations. +ifeq ($(host),MINGW32) + CFILES+=ArSocket_WIN.cpp \ + ArJoyHandler_WIN.cpp \ + ArSerialConnection_WIN.cpp \ + ArSignalHandler_WIN.cpp +else + CFILES+=ArSocket_LIN.cpp \ + ArJoyHandler_LIN.cpp \ + ArSerialConnection_LIN.cpp \ + ArSignalHandler_LIN.cpp \ + ArVersalogicIO.cpp \ + ArMTXIO.cpp +endif + + + + +#### +#### Utility variables. No need to touch these. +#### + +OTFILES:=$(patsubst %.$(CFILEEXT),%.o,$(CFILES)) +OFILES:=$(patsubst %,obj/%,$(OTFILES)) +EXAMPLES_CPP:=$(shell find examples -name "*.$(CFILEEXT)" | grep -v Mod.cpp | grep -v proprietary) +EXAMPLES:=$(patsubst %.$(CFILEEXT),%$(binsuffix),$(EXAMPLES_CPP)) +EXAMPLES_STATIC:=$(patsubst %,%Static$(binsuffix),$(EXAMPLES)) +MOD_EXAMPLES_CPP:=$(shell find examples -name "*.$(CFILEEXT)" | grep Mod.cpp) +MOD_EXAMPLES:=$(patsubst %.$(CFILEEXT),%.so,$(MOD_EXAMPLES_CPP)) +TESTS_CPP:=$(shell find tests -name "*.$(CFILEEXT)" | grep -v Mod.cpp | grep -v proprietary) +MOD_TESTS_CPP:=$(shell find tests -name "*Mod.$(CFILEEXT)") +MOD_TESTS:=$(patsubst %.$(CFILEEXT),%.so,$(MOD_TESTS_CPP)) +TESTS:=$(patsubst %.$(CFILEEXT),%$(binsuffix),$(TESTS_CPP)) +TESTS_STATIC:=$(patsubst %,%Static$(binsuffix),$(TESTS)) +ADVANCED_CPP:=$(shell find advanced -name "*.$(CFILEEXT)" | grep -v Mod.cpp | grep -v proprietary) +ADVANCED:=$(patsubst %.$(CFILEEXT),%,$(ADVANCED_CPP)) +UTILS_CPP:=$(shell find utils -name "*.$(CFILEEXT)") +UTILS:=$(patsubst %.$(CFILEEXT),%$(binsuffix),$(UTILS_CPP)) +SRC_FILES:=$(patsubst %,src/%,$(CFILES)) +HEADER_FILES:=$(shell find include -type f -name \*.h) + + + + +#### +#### General rules for user invocation +#### + +# Default Rule +all: dirs $(TARGETS) + +# Build all targets, docs, params, etc. etc. +everything: dirs $(ALL_TARGETS) + +static: dirs $(STATIC_TARGETS) + +# Build everything required for distribution packages +dist-all: lib/libAria.so params docs CommandLineOptions.txt.in \ + lib/libArNetworking.so ArNetworking/CommandLineOptions.txt.in examples/demo \ + examples/demoStatic ArNetworking/examples/serverDemo \ + ArNetworking/examples/serverDemoStatic ArNetworking/examples/clientDemo \ + ArNetworking/examples/clientDemoStatic java python arnetworking_swig \ + arnetworking_docs + +examples: $(EXAMPLES) + +modExamples: $(MOD_EXAMPLES) + +tests: $(TESTS) $(MOD_TESTS) + +advanced: $(ADVANCED) + +utils: $(UTILS) + +cleanDep: + -rm Makefile.dep `find . -name Makefile.dep` + +# directories that might not exist: +dirs: + @mkdir -p -v obj + @mkdir -p -v lib + +docs: doc +doc: docs/index.html +docs/index.html: $(SRC_FILES) $(HEADER_FILES) $(EXAMPLES_CPP) docs/overview.dox docs/options/all_options.dox docs/params.dox + @echo Removing old documentation... + $(MAKE) cleanDoc + @echo Running dist/make-doc.sh to generate HTML API documentation... + dist/make-doc.sh dev ARIA_DIST_NO_NTP=1 + +arnetworking_swig: + $(MAKE) -C ArNetworking java python + +arnetworking_docs: + $(MAKE) -C ArNetworking docs + +help: + @echo To make most things, run \'make\' or \'make all\' + @echo Some useful targets include: + @echo " allLibs, cleanAllLibs, depAllLibs (do all subdirectories)" + @echo " clean" + @echo " dep" + @echo " cleanDep" + @echo " docs" + @echo " cleanAll (also cleans ArNetworking, java, python, etc.)" + @echo " examples" + @echo " tests" + @echo " utils" + @echo " python" + @echo " cleanPython" + @echo " java" + @echo " cleanJava" + @echo " examples/, where examples/.cpp is an example program source file." + @echo " tests/, where tests/.cpp is a test program source file." + @echo " allLibs (try to build all auxilliary libraries that you have installed by running make in each directory starting with \"Ar\")" + @echo " cleanAllLibs, depAllLibs (do make clean or make dep in the \"Ar*\" auxilliary libraries)" + @echo " install (if this is a source tar.gz package)" + +info: + @echo ARIA=$(ARIA) + @echo CXX=$(CXX) + @echo CXXFLAGS=$(CXXFLAGS) + @echo CXXINC=$(CXXINC) + @echo CXXLINK=$(CXXLINK) + @echo CXXSTATICLINK=$(CXXSTATICLINK) + @echo ALL_TARGETS=$(ALL_TARGETS) + @echo + @echo JAVAC=$(JAVAC) + @echo JAR=$(JAR) + @echo + @echo Use \'make moreinfo\' for info about individual files, etc. + +moreinfo: + @echo CFILES=$(CFILES) + @echo + @echo EXAMPLES=$(EXAMPLES) + @echo + @echo MOD_EXAMPLES=$(MOD_EXAMPLES) + @echo + @echo TESTS=$(TESTS) + @echo + @echo MOD_TESTS=$(MOD_TESTS) + @echo + @echo ADVANCED=$(ADVANCED) + @echo + @echo UTILS=$(UTILS) + @echo + @echo SRC_FILES=$(SRC_FILES) + @echo + @echo HEADER_FILES=$(HEADER_FILES) + + + +clean: cleanUtils cleanExamples cleanModules cleanTests cleanAdvanced + -rm -f lib/libAria.a lib/libAria.so $(OFILES) `find . -name core` `find . -name '*~'` obj/AriaPy.o obj/AriaJava.o + +cleanUtils: + -rm -f $(UTILS) + +cleanExamples: + -rm -f $(EXAMPLES) $(EXAMPLES_STATIC) + +cleanTests: + -rm -f $(TESTS) $(TESTS_STATIC) + +cleanAdvanced: + -rm -f $(ADVANCED) + +cleanModules: + -rm -f $(MOD_EXAMPLES) + +cleanDoc: + -rm docs/*.html docs/*.png docs/doxygen.css + +cleandoc: cleanDoc + +cleanPython: + -rm python/_AriaPy.so + -rm python/AriaPy.py + -rm python/AriaPy.pyc + -rm python/AriaPy_wrap.cpp + -rm python/AriaPy_wrap.h + -rm obj/AriaPy_wrap.o + +cleanpython: cleanPython + +dep: clean + if [ -f `echo src/*.cpp | cut -d' ' -f1` ]; then \ + $(CXX) $(CXXFLAGS) $(CXXINC) -MM src/*.cpp | \ + awk '$$1 ~ /:/{printf "obj/%s\n", $$0} $$1 !~ /:/' > Makefile.dep; fi + if [ -f `echo examples/*.cpp | cut -d' ' -f1` ]; then \ + $(CXX) $(CXXFLAGS) $(CXXINC) -MM examples/*.cpp | \ + awk '$$1 ~ /:/{printf "examples/%s$(binsuffix)\n", $$0} $$1 !~ /:/' | \ + sed 's/\.o//' >> Makefile.dep; fi + if [ -f `echo utils/*.cpp | cut -d' ' -f1` ]; then \ + $(CXX) $(CXXFLAGS) $(CXXINC) -MM utils/*.cpp | \ + awk '$$1 ~ /:/{printf "utils/%s$(binsuffix)\n", $$0} $$1 !~ /:/' | \ + sed 's/\.o//' >> Makefile.dep; fi + if [ -f `echo tests/*.cpp | cut -d' ' -f1` ]; then \ + $(CXX) $(CXXFLAGS) $(CXXINC) -MM tests/*.cpp | \ + awk '$$1 ~ /:/{printf "tests/%s$(binsuffix)\n", $$0} $$1 !~ /:/' | \ + sed 's/\.o//' >> Makefile.dep; fi + if [ -f `echo advanced/*.cpp | cut -d' ' -f1` ]; then \ + $(CXX) $(CXXFLAGS) $(CXXINC) -MM advanced/*.cpp | \ + awk '$$1 ~ /:/{printf "advanced/%s$(binsuffix)\n", $$0} $$1 !~ /:/' | \ + sed 's/\.o//' >> Makefile.dep; fi + +Makefile.dep: + $(MAKE) dep + +depAll: cleanDep + make dep; + for dir in `find . -maxdepth 1 -name "Ar*" -xtype d`; do cd $$dir; make dep; cd ..; done + +cleanAll: clean + rm -f lib/lib*.so* + for dir in `find . -maxdepth 1 -name "Ar*" -xtype d`; do cd $$dir; make clean; cd ..; done + $(MAKE) -C ArVideo cleanAll + $(MAKE) -C ArNetworking cleanAll + +fullCleanAll: cleanAll cleanJava cleanPython + rm -f lib/lib*.so* + rm -f obj/*.o* + for dir in `find . -maxdepth 1 -name "Ar*" -xtype d`; do cd $$dir; make fullClean; cd ..; done + + + +params: utils/makeParams$(binsuffix) + -mkdir params + utils/makeParams$(binsuffix) + +CommandLineOptions.txt.in docs/options/all_options.dox: utils/genCommandLineOptionDocs$(binsuffix) src/ArSimpleConnector.cpp src/ArGPSConnector.cpp src/ArTCM2.cpp + -mkdir docs/options + utils/genCommandLineOptionDocs$(binsuffix) + +alllibs: allLibs + +allLibs: all + find . -type d -and -name Ar\* -maxdepth 1 -exec $(MAKE) -C \{\} \; + +cleanAllLibs: clean cleanJava cleanPython cleanDep + for dir in `find . -maxdepth 1 -name "Ar*" -xtype d`; do $(MAKE) -C $$dir clean cleanAll; done + +cleanalllibs: cleanAllLibs + +checkAll: + $(MAKE) everything > checkAll.log 2>&1 + $(MAKE) allLibs >> checkAll.log 2>&1 + grep -n -v 'Error 1 (ignored)' checkAll.log | grep -C 4 'Error' > checkAll-Errors.log + @echo + @echo Errors were: + @echo + @cat checkAll-Errors.log + @echo + @echo Error log also saved as checkAll-Errors.log. Full log saved as checkAll.log. + +#### +#### Swig wrappers +#### + +ifndef SWIG +SWIG=swig +endif + +### Python wrapper: ### + + +ifdef PYTHON_INCLUDE +PYTHON_INCLUDE_FLAGS=-I$(PYTHON_INCLUDE) +else +ifdef DIST_INSTALL +$(warning WARNING using default value of /usr/include/python2.5 for PYTHON_INCLUDE directory. Set PYTHON_INCLUDE environment variable if you would like to use a different version of the Python C development library to build the Python ARIA wrapper.) +endif +PYTHON_INCLUDE:=/usr/include/python2.5 +PYTHON_INCLUDE_FLAGS=-I/usr/include/python2.5 +endif + +python: python/_AriaPy.so python/AriaPy.py + +py: python + +python-doc: python/AriaPy.html + +python/AriaPy.html: python/AriaPy.py + cd python; pydoc -w AriaPy + +python/AriaPy_wrap.cpp python/AriaPy.py: include/wrapper.i include/*.h + -rm -f `find python -maxdepth 1 -xtype f -name "*Aria*" | grep -v .ds | grep -v .sln | grep -v .vcproj` + cd python; $(SWIG) -Wall -c++ -python -modern -module AriaPy -Dlinux -DAREXPORT -o AriaPy_wrap.cpp -I../include ../include/wrapper.i + +python/_AriaPy.so: obj/AriaPy_wrap.o lib/libAria.so Makefile.dep + if ! test -f $(PYTHON_INCLUDE)/Python.h; then echo Error: $(PYTHON_INCLUDE)/Python.h not found. Is the Python development package installed on this system? Is PYTHON_INCLUDE set correctly?; exit 1; fi + $(CXX) -shared -o $(@) obj/AriaPy_wrap.o $(CXXLINK) + +obj/AriaPy_wrap.o: python/AriaPy_wrap.cpp + mkdir -p obj + @ if test -z "$(PYTHON_INCLUDE)"; then echo "*** Error: PYTHON_INCLUDE is not set, cannot build ARIA python wrapper"; fi + if ! test -f $(PYTHON_INCLUDE)/Python.h; then echo Error: $(PYTHON_INCLUDE)/Python.h not found. Is the Python development package installed on this system? Is PYTHON_INCLUDE set correctly?; exit 1; fi + $(CXX) -c $(BARECXXFLAGS) $(CXXINC) $(PYTHON_INCLUDE_FLAGS) $< -o $@ + + +### Java Wrapper: ### + + + +java: lib/libAriaJava.so java/Aria.jar + +java/Aria.jar: java/com/mobilerobots/Aria/ArRobot.class + cd java; $(JAR) cf Aria.jar com/mobilerobots/Aria/*.class + +cleanJava: + -rm -f `find java -xtype f -maxdepth 1 | grep -v .ds | grep -v .sln | grep -v .vcproj` + -rm lib/libAriaJava.so + -rm java/AriaJava_wrap.cpp + -rm java/AriaJava_wrap.h + -rm obj/AriaJava_wrap.o + +cleanjava: cleanJava + +cleanSwigJava: + -rm -r java/Aria.jar java/com/mobilerobots/Aria + +lib/libAriaJava.so: obj/AriaJava_wrap.o lib/libAria.so Makefile.dep + $(CXX) -shared -o $(@) obj/AriaJava_wrap.o $(CXXLINK) + +obj/AriaJava_wrap.o: java/AriaJava_wrap.cpp + @ if test -z "$(JAVA_INCLUDE)"; then echo "Error: JAVA_INCLUDE is not set, compiling AriaJava_wrap.cpp will fail!"; fi + @ test -n "$(JAVA_INCLUDE)" + @ if test \! -d "$(JAVA_INCLUDE)"; then echo "Error: JAVA_INCLUDE directory $(JAVA_INCLUDE) does not exist, compiling AriaJava_wrap.cpp will fail!"; fi + @ test -d "$(JAVA_INCLUDE)" + mkdir -p obj + $(CXX) -c $(BARECXXFLAGS) $(CXXINC) -I$(JAVA_INCLUDE) -I$(JAVA_INCLUDE)/linux $< -o $@ + +java/AriaJava_wrap.cpp java/com/mobilerobots/Aria/ArRobot.java: include/wrapper.i $(HEADER_FILES) + -mkdir -p java/com/mobilerobots/Aria; rm java/com/mobilerobots/Aria/*.java java/AriaJava_wrap.cpp java/AriaJava_wrap.h; $(SWIG) -Wall -c++ -java -package com.mobilerobots.Aria -outdir java/com/mobilerobots/Aria -module AriaJava -Dlinux -DAREXPORT -o java/AriaJava_wrap.cpp -Iinclude include/wrapper.i + +# The sed script is a hack to let subclasses outside of Aria work for ArFunctor; +# for some reason SWIG doesn't use my %typmeap(javabody) for ArFunctor. +# \ +# && sed 's/protected static long getCPtr/public ArFunctor() { this(0, false); } public static long getCPtr/' java/com/mobilerobots/Aria/ArFunctor.java > ArFunctor.java.tmp \ +# && mv ArFunctor.java.tmp java/com/mobilerobots/Aria/ArFunctor.java + +# It is much faster to compile them all at once. Use ArRobot.java/class as a +# stand-in for all java files and all class files. +java/com/mobilerobots/Aria/ArRobot.class: java/com/mobilerobots/Aria/ArRobot.java + rm java/com/mobilerobots/Aria/*.class; $(JAVAC) -classpath java java/com/mobilerobots/Aria/*.java + + +java/ArNetworking.jar: FORCE + $(MAKE) -C ArNetworking ../$@ + +lib/libArNetworkingJava.so: FORCE + $(MAKE) -C ArNetworking ../$@ + +python/ArNetworkingPy.py: FORCE + $(MAKE) -C ArNetworking ../$@ + +python/_ArNetworkingPy.so: FORCE + $(MAKE) -C ArNetworking ../$@ + + +#### +#### Targets to actually build binaries (libraries, programs) +#### + +lib/libAria.so: $(OFILES) Makefile.dep + $(CXX) -shared -o $(@) $(OFILES) + +lib/libAria.a: $(OFILES) Makefile.dep + ar -cr $(@) $(OFILES) + ranlib $(@) + +examples/%.so: examples/%.$(CFILEEXT) lib/libAria.so Makefile.dep + $(CXX) $(CXXFLAGS) $(CXXINC) -shared $< -o $@ + +examples/%$(binsuffix): examples/%.$(CFILEEXT) lib/libAria.so Makefile.dep + $(CXX) $(CXXFLAGS) $(CXXINC) $< -o $@ $(CXXLINK) + +examples/%Static$(binsuffix): examples/%.$(CFILEEXT) lib/libAria.a Makefile.dep + $(CXX) $(CXXFLAGS) $(CXXINC) $< -o $@ $(CXXSTATICLINK) + if test -n "$$NOSTRIP"; then strip $@; fi + +tests/%.so: tests/%.$(CFILEEXT) lib/libAria.so Makefile.dep + $(CXX) $(CXXFLAGS) $(CXXINC) -shared $< -o $@ + +tests/%$(binsuffix): tests/%.$(CFILEEXT) lib/libAria.so Makefile.dep + $(CXX) $(CXXFLAGS) $(CXXINC) $< -o $@ $(CXXLINK) + +tests/%Static$(binsuffix): tests/%.$(CFILEEXT) lib/libAria.a Makefile.dep + $(CXX) $(CXXFLAGS) $(CXXINC) $< -o $@ $(CXXSTATICLINK) + if test -n "$$NOSTRIP"; then strip $@; fi + +advanced/%.so: advanced/%.$(CFILEEXT) lib/libAria.so + $(CXX) $(CXXFLAGS) $(CXXINC) -shared $< -o $@ + +advanced/%$(binsuffix): advanced/%.$(CFILEEXT) lib/libAria.so Makefile.dep + $(CXX) $(CXXFLAGS) $(CXXINC) $< -o $@ $(CXXLINK) + +advanced/%Static$(binsuffix): advanced/%.$(CFILEEXT) lib/libAria.a Makefile.dep + $(CXX) $(CXXFLAGS) $(CXXINC) $< -o $@ $(CXXSTATICLINK) + #strip $@ + +utils/%$(binsuffix): utils/%.$(CFILEEXT) lib/libAria.so Makefile.dep + $(CXX) $(CXXFLAGS) $(CXXINC) $< -o $@ $(CXXLINK) + +utils/%Static$(binsuffix): utils/%.$(CFILEEXT) lib/libAria.a Makefile.dep + $(CXX) $(CXXFLAGS) $(CXXINC) $< -o $@ $(CXXSTATICLINK) + #strip $@ + +utils/genCommandLineOptionDocs$(binsuffix): utils/genCommandLineOptionDocs.cpp lib/libAria.so Makefile.dep + $(CXX) $(CXXFLAGS) -DFOR_ARIA $(CXXINC) $< -o $@ $(CXXLINK) + +ifneq ($(binsuffix),) +examples/%: examples/%$(binsuffix) +utils/%: utils/%$(binsuffix) +advanced/%: advanced/%$(binsuffix) +tests/%: tests/$(binsuffix) +endif + +obj/%.o : src/%.cpp Makefile.dep + @mkdir -p obj + $(CXX) -c $(CXXFLAGS) $(CXXINC) $< -o $@ + +obj/%.o : src/%.c Makefile.dep + @mjdir -p obj + $(CXX) -c $(CXXFLAGS) $(CXXINC) $< -o $@ + +include/%.i: include/%.h Makefile.dep + $(CXX) -E $(CXXFLAGS) $(CXXINC) $< -o $@ + +src/%.i: src/%.cpp Makefile.dep + $(CXX) -E $(CXXFLAGS) $(CXXINC) $< -o $@ + +# Don't build .o files if their library is up to date with respect to source files: +.INTERMEDIATE: $(OFILES) + +# But don't delete .o files if we do make them in order to make a library: +.PRECIOUS: $(OFILES) + + +# To build things in the ArNetworking subdirectory: + +lib/libArNetworking.so: FORCE + $(MAKE) -C ArNetworking ../$@ + +lib/libArNetworking.a: FORCE + $(MAKE) -C ArNetworking ../$@ + +ArNetworking/examples/%: ArNetworking/examples/%.cpp lib/libArNetworking.so + $(MAKE) -C ArNetworking examples/$* + +ArNetworking/examples/%Static: ArNetworking/examples/%.cpp lib/libArNetworking.a + $(MAKE) -C ArNetworking examples/$*Static + +#ArNetworking/docs/index.html: FORCE +# $(MAKE) -C ArNetworking docs/index.html + +ArNetworking/%: FORCE + $(MAKE) -C ArNetworking $* + +# This rule doesn't actually produce its target, so anything depending on it +# will always get remade. +FORCE: + + +#### +#### Installation and distribution +#### + + +ifndef INSTALL_DIR +INSTALL_DIR=/usr/local/Aria +endif + +ifndef SYSTEM_ETC_DIR +SYSTEM_ETC_DIR=/etc +endif + +# What to put in /etc/Aria: +ifndef STORED_INSTALL_DIR +STORED_INSTALL_DIR=$(INSTALL_DIR) +endif + +# How to run 'install' for the install rule: +ifndef INSTALL +INSTALL:=install --preserve-timestamps +endif + + +dist: FORCE + dist/dist.sh + +dist-install: install + +# Install rule. This can be used by users or ARIA developers; in the latter +# case it also installs various files needed to make a release distribution. +# Override installation locations with INSTALL_DIR environment variable. +# Things are installed group-writable so as to be hacked upon. +install: + @echo -------------------------------------- + @echo Installing ARIA in $(DESTDIR)$(INSTALL_DIR)... + @echo -------------------------------------- + $(INSTALL) -m 775 -d $(DESTDIR)$(INSTALL_DIR) + find include src tests utils params docs examples advanced maps \ + ArNetworking java javaExamples python pythonExamples obj \ + \( -name \*.o -or -name core -or -name CVS -or -name .\* -or -name \*~ -or -name tmp -or -name proprietary* -or -name \*.bak -or -name \*.class \) -prune \ + -or -type d -exec $(INSTALL) -d -m 777 $(DESTDIR)$(INSTALL_DIR)/\{\} \; \ + -or -type l -exec cp --no-dereference \{\} $(DESTDIR)$(INSTALL_DIR)/\{\} \; \ + -or -name \*.a -exec $(INSTALL) -D -m 666 \{\} $(DESTDIR)$(INSTALL_DIR)/\{\} \; \ + -or -perm +1 -exec $(INSTALL) -D --strip -m 777 \{\} $(DESTDIR)$(INSTALL_DIR)/\{\} \; \ + -or -exec $(INSTALL) -D -m 666 \{\} $(DESTDIR)$(INSTALL_DIR)/\{\} \; + $(INSTALL) -D -m 664 LICENSE.txt INSTALL.txt README.txt Makefile Aria-Reference.html version.txt Changes.txt CommandLineOptions.txt icon.png $(DESTDIR)$(INSTALL_DIR)/ + $(INSTALL) -D -m 666 Makefile.dep doxygen.conf $(DESTDIR)$(INSTALL_DIR)/ + $(INSTALL) -D -m 664 bin/SIMULATOR_README.txt $(DESTDIR)$(INSTALL_DIR)/bin/SIMULATOR_README.txt + $(INSTALL) -d -m 777 $(DESTDIR)$(INSTALL_DIR)/lib/ + $(INSTALL) -D --strip -m 666 lib/libAria.so lib/libArNetworking.so lib/libAriaJava.so lib/libArNetworkingJava.so $(DESTDIR)$(INSTALL_DIR)/lib/ + @if test -z "$(DIST_INSTALL)"; then \ + echo "if test \! -d $(DESTDIR)$(SYSTEM_ETC_DIR); then install -d $(DESTDIR)$(SYSTEM_ETC_DIR); fi" ;\ + if test \! -d $(DESTDIR)$(SYSTEM_ETC_DIR); then install -d $(DESTDIR)$(SYSTEM_ETC_DIR); fi ;\ + echo "echo $(STORED_INSTALL_DIR) > $(DESTDIR)$(SYSTEM_ETC_DIR)/Aria" ;\ + echo $(STORED_INSTALL_DIR) > $(DESTDIR)$(SYSTEM_ETC_DIR)/Aria ;\ + echo ------------------------------------------------------------------------------------ ;\ + echo ARIA has been installed in $(DESTDIR)$(INSTALL_DIR). ;\ + echo ;\ + echo To be able to use the ARIA libraries, you must now add $(DESTDIR)$(INSTALL_DIR)/lib ;\ + echo to your LD_LIBRARY_PATH environment variable, or to the /etc/ld.so.conf system file, ;\ + echo then run \'ldconfig\';\ + echo ------------------------------------------------------------------------------------ ;\ + fi + +# echo ;\ +# echo The files are owned by the group \"users\", and all members of that group ;\ +# echo can enter the directory, read files, and modify the \"examples\" directory. ;\ + +### +### Make optimization, tell it what rules aren't files: +### +.PHONY: all everything examples modExamples tests advanced utils cleanDep docs doc dirs help info moreinfo clean cleanUtils cleanExamples cleanTests cleanAdvanced cleanModules cleanDoc cleanPython dep depAll cleanAll params allLibs python python-doc java cleanJava install alllibs arnetworking_swig arnetworking_docs params swig help info moreinfo py python-doc cleanSwigJava checkAll + +### Autogenerated dependencies: +# Just see if there is a Makefile.dep, if so include one... there +# should be one because various rules above depend on Makefile.dep. +# Note, use this ifeq/wildcard hacok rather than "-include" directive to +# prevent Make from trying to create Makefile.dep itself if missing during the +# recursive call to $(MAKE) dep. (it just keeps +# calling make dep recursively). +ifeq (Makefile.dep,$(wildcard Makefile.dep)) +include Makefile.dep +# End of the Makefile.dep check +endif + diff --git a/Legacy/Aria/Makefile.dep b/Legacy/Aria/Makefile.dep new file mode 100644 index 0000000..298fc0b --- /dev/null +++ b/Legacy/Aria/Makefile.dep @@ -0,0 +1,14508 @@ +obj/ArACTS.o: src/ArACTS.cpp include/ArExport.h include/ariaOSDef.h \ + include/ArACTS.h include/ariaTypedefs.h include/ArTcpConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ariaOSDef.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArBasePacket.h include/ArSocket.h include/ArRobot.h \ + include/ArRobotPacketSender.h include/ArRobotPacket.h \ + include/ArRobotPacketReceiver.h include/ArSyncTask.h \ + include/ArTaskState.h include/ArSensorReading.h include/ArTransform.h \ + include/ArCondition.h include/ArSyncLoop.h include/ArASyncTask.h \ + include/ArThread.h include/ArRobotPacketReaderThread.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h +obj/ArAMPTU.o: src/ArAMPTU.cpp include/ArExport.h include/ariaOSDef.h \ + include/ArAMPTU.h include/ariaTypedefs.h include/ArBasePacket.h \ + include/ArPTZ.h include/ArFunctor.h include/ariaOSDef.h \ + include/ArCommands.h include/ArPTZConnector.h include/ariaUtil.h \ + include/ArLog.h include/ArMutex.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArRobotParams.h include/ArConfig.h \ + include/ArConfigArg.h include/ArFileParser.h include/ArHasFileName.h \ + include/ariaInternal.h include/ArStringInfoGroup.h include/ArCommands.h \ + include/ArLog.h include/ArRobot.h include/ArRobotPacketSender.h \ + include/ArRobotPacket.h include/ArRobotPacketReceiver.h \ + include/ArSyncTask.h include/ArTaskState.h include/ArSensorReading.h \ + include/ArTransform.h include/ArCondition.h include/ArSyncLoop.h \ + include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h +obj/ArASyncTask.o: src/ArASyncTask.cpp include/ArExport.h include/ariaOSDef.h \ + include/ArASyncTask.h include/ariaTypedefs.h include/ArFunctor.h \ + include/ariaOSDef.h include/ArThread.h include/ArMutex.h include/ArLog.h \ + include/ArLog.h +obj/ArAction.o: src/ArAction.cpp include/ArExport.h include/ariaOSDef.h \ + include/ArResolver.h include/ariaTypedefs.h include/ArActionDesired.h \ + include/ariaUtil.h include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ariaOSDef.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArAction.h include/ArArg.h \ + include/ArLog.h include/ArRobot.h include/ArRobotPacketSender.h \ + include/ArRobotPacket.h include/ArBasePacket.h \ + include/ArRobotPacketReceiver.h include/ArSyncTask.h \ + include/ArTaskState.h include/ArSensorReading.h include/ArTransform.h \ + include/ArCondition.h include/ArSyncLoop.h include/ArASyncTask.h \ + include/ArThread.h include/ArRobotPacketReaderThread.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArResolver.h \ + include/ArInterpolation.h include/ArKeyHandler.h +obj/ArActionAvoidFront.o: src/ArActionAvoidFront.cpp include/ArExport.h \ + include/ariaOSDef.h include/ArActionAvoidFront.h include/ariaTypedefs.h \ + include/ariaUtil.h include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ariaOSDef.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArAction.h include/ArArg.h \ + include/ArActionDesired.h include/ArResolver.h include/ArRobot.h \ + include/ArRobotPacketSender.h include/ArRobotPacket.h \ + include/ArBasePacket.h include/ArRobotPacketReceiver.h \ + include/ArSyncTask.h include/ArTaskState.h include/ArSensorReading.h \ + include/ArTransform.h include/ArCondition.h include/ArSyncLoop.h \ + include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArRobotParams.h \ + include/ArConfig.h include/ArConfigArg.h include/ArFileParser.h \ + include/ArHasFileName.h include/ArResolver.h include/ArInterpolation.h \ + include/ArKeyHandler.h include/ArLog.h +obj/ArActionAvoidSide.o: src/ArActionAvoidSide.cpp include/ArExport.h \ + include/ariaOSDef.h include/ArActionAvoidSide.h include/ariaTypedefs.h \ + include/ArAction.h include/ArArg.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ariaOSDef.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArActionDesired.h include/ArRobot.h \ + include/ArRobotPacketSender.h include/ArRobotPacket.h \ + include/ArBasePacket.h include/ArRobotPacketReceiver.h \ + include/ArSyncTask.h include/ArTaskState.h include/ArSensorReading.h \ + include/ArTransform.h include/ArCondition.h include/ArSyncLoop.h \ + include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArRobotParams.h \ + include/ArConfig.h include/ArConfigArg.h include/ArFileParser.h \ + include/ArHasFileName.h include/ArResolver.h include/ArInterpolation.h \ + include/ArKeyHandler.h +obj/ArActionBumpers.o: src/ArActionBumpers.cpp include/ArExport.h \ + include/ariaOSDef.h include/ArActionBumpers.h include/ariaTypedefs.h \ + include/ArAction.h include/ArArg.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ariaOSDef.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArActionDesired.h include/ArRobot.h \ + include/ArRobotPacketSender.h include/ArRobotPacket.h \ + include/ArBasePacket.h include/ArRobotPacketReceiver.h \ + include/ArSyncTask.h include/ArTaskState.h include/ArSensorReading.h \ + include/ArTransform.h include/ArCondition.h include/ArSyncLoop.h \ + include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArRobotParams.h \ + include/ArConfig.h include/ArConfigArg.h include/ArFileParser.h \ + include/ArHasFileName.h include/ArResolver.h include/ArInterpolation.h \ + include/ArKeyHandler.h +obj/ArActionColorFollow.o: src/ArActionColorFollow.cpp include/ArExport.h \ + include/ariaOSDef.h include/ArActionColorFollow.h include/ariaTypedefs.h \ + include/ariaUtil.h include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ariaOSDef.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArAction.h include/ArArg.h \ + include/ArActionDesired.h include/ArACTS.h include/ArTcpConnection.h \ + include/ArDeviceConnection.h include/ArBasePacket.h include/ArSocket.h \ + include/ArRobot.h include/ArRobotPacketSender.h include/ArRobotPacket.h \ + include/ArRobotPacketReceiver.h include/ArSyncTask.h \ + include/ArTaskState.h include/ArSensorReading.h include/ArTransform.h \ + include/ArCondition.h include/ArSyncLoop.h include/ArASyncTask.h \ + include/ArThread.h include/ArRobotPacketReaderThread.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArResolver.h \ + include/ArInterpolation.h include/ArKeyHandler.h include/ArPTZ.h \ + include/ArCommands.h include/ArPTZConnector.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArResolver.h include/ArRobot.h +obj/ArActionConstantVelocity.o: src/ArActionConstantVelocity.cpp \ + include/ArExport.h include/ariaOSDef.h \ + include/ArActionConstantVelocity.h include/ariaTypedefs.h \ + include/ArAction.h include/ArArg.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ariaOSDef.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArActionDesired.h +obj/ArActionDeceleratingLimiter.o: src/ArActionDeceleratingLimiter.cpp \ + include/ArExport.h include/ariaOSDef.h \ + include/ArActionDeceleratingLimiter.h include/ariaTypedefs.h \ + include/ArAction.h include/ArArg.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ariaOSDef.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArActionDesired.h include/ArRobot.h \ + include/ArRobotPacketSender.h include/ArRobotPacket.h \ + include/ArBasePacket.h include/ArRobotPacketReceiver.h \ + include/ArSyncTask.h include/ArTaskState.h include/ArSensorReading.h \ + include/ArTransform.h include/ArCondition.h include/ArSyncLoop.h \ + include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArRobotParams.h \ + include/ArConfig.h include/ArConfigArg.h include/ArFileParser.h \ + include/ArHasFileName.h include/ArResolver.h include/ArInterpolation.h \ + include/ArKeyHandler.h include/ArCommands.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArRobotConfigPacketReader.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h +obj/ArActionDesired.o: src/ArActionDesired.cpp include/ArExport.h \ + include/ariaOSDef.h include/ArActionDesired.h include/ariaTypedefs.h \ + include/ariaUtil.h include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ariaOSDef.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h +obj/ArActionDriveDistance.o: src/ArActionDriveDistance.cpp include/ArExport.h \ + include/ariaOSDef.h include/ArActionDriveDistance.h \ + include/ariaTypedefs.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ariaOSDef.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArAction.h include/ArArg.h include/ArActionDesired.h \ + include/ArRobot.h include/ArRobotPacketSender.h include/ArRobotPacket.h \ + include/ArBasePacket.h include/ArRobotPacketReceiver.h \ + include/ArSyncTask.h include/ArTaskState.h include/ArSensorReading.h \ + include/ArTransform.h include/ArCondition.h include/ArSyncLoop.h \ + include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArRobotParams.h \ + include/ArConfig.h include/ArConfigArg.h include/ArFileParser.h \ + include/ArHasFileName.h include/ArResolver.h include/ArInterpolation.h \ + include/ArKeyHandler.h +obj/ArActionGoto.o: src/ArActionGoto.cpp include/ArExport.h \ + include/ariaOSDef.h include/ArActionGoto.h include/ariaTypedefs.h \ + include/ariaUtil.h include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ariaOSDef.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArAction.h include/ArArg.h \ + include/ArActionDesired.h include/ArRobot.h \ + include/ArRobotPacketSender.h include/ArRobotPacket.h \ + include/ArBasePacket.h include/ArRobotPacketReceiver.h \ + include/ArSyncTask.h include/ArTaskState.h include/ArSensorReading.h \ + include/ArTransform.h include/ArCondition.h include/ArSyncLoop.h \ + include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArRobotParams.h \ + include/ArConfig.h include/ArConfigArg.h include/ArFileParser.h \ + include/ArHasFileName.h include/ArResolver.h include/ArInterpolation.h \ + include/ArKeyHandler.h +obj/ArActionGotoStraight.o: src/ArActionGotoStraight.cpp include/ArExport.h \ + include/ariaOSDef.h include/ArActionGotoStraight.h \ + include/ariaTypedefs.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ariaOSDef.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArAction.h include/ArArg.h include/ArActionDesired.h \ + include/ArRobot.h include/ArRobotPacketSender.h include/ArRobotPacket.h \ + include/ArBasePacket.h include/ArRobotPacketReceiver.h \ + include/ArSyncTask.h include/ArTaskState.h include/ArSensorReading.h \ + include/ArTransform.h include/ArCondition.h include/ArSyncLoop.h \ + include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArRobotParams.h \ + include/ArConfig.h include/ArConfigArg.h include/ArFileParser.h \ + include/ArHasFileName.h include/ArResolver.h include/ArInterpolation.h \ + include/ArKeyHandler.h +obj/ArActionGroup.o: src/ArActionGroup.cpp include/ArExport.h \ + include/ariaOSDef.h include/ArActionGroup.h include/ariaTypedefs.h \ + include/ArAction.h include/ArArg.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ariaOSDef.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArActionDesired.h include/ArRobot.h \ + include/ArRobotPacketSender.h include/ArRobotPacket.h \ + include/ArBasePacket.h include/ArRobotPacketReceiver.h \ + include/ArSyncTask.h include/ArTaskState.h include/ArSensorReading.h \ + include/ArTransform.h include/ArCondition.h include/ArSyncLoop.h \ + include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArRobotParams.h \ + include/ArConfig.h include/ArConfigArg.h include/ArFileParser.h \ + include/ArHasFileName.h include/ArResolver.h include/ArInterpolation.h \ + include/ArKeyHandler.h include/ArLog.h +obj/ArActionGroups.o: src/ArActionGroups.cpp include/ArExport.h \ + include/ariaOSDef.h include/ArActionGroup.h include/ariaTypedefs.h \ + include/ArActionGroups.h include/ArActionGroup.h \ + include/ArActionColorFollow.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ariaOSDef.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArAction.h include/ArArg.h include/ArActionDesired.h \ + include/ArACTS.h include/ArTcpConnection.h include/ArDeviceConnection.h \ + include/ArBasePacket.h include/ArSocket.h include/ArRobot.h \ + include/ArRobotPacketSender.h include/ArRobotPacket.h \ + include/ArRobotPacketReceiver.h include/ArSyncTask.h \ + include/ArTaskState.h include/ArSensorReading.h include/ArTransform.h \ + include/ArCondition.h include/ArSyncLoop.h include/ArASyncTask.h \ + include/ArThread.h include/ArRobotPacketReaderThread.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArResolver.h \ + include/ArInterpolation.h include/ArKeyHandler.h include/ArPTZ.h \ + include/ArCommands.h include/ArPTZConnector.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArActionLimiterTableSensor.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionInput.h include/ArActionStop.h \ + include/ArActionStallRecover.h include/ArActionBumpers.h \ + include/ArActionAvoidFront.h include/ArActionConstantVelocity.h \ + include/ArActionJoydrive.h include/ArJoyHandler.h \ + include/ArActionKeydrive.h include/ArActionDeceleratingLimiter.h \ + include/ArActionRatioInput.h include/ArRatioInputKeydrive.h \ + include/ArActionRatioInput.h include/ArRatioInputJoydrive.h \ + include/ArRatioInputRobotJoydrive.h +obj/ArActionIRs.o: src/ArActionIRs.cpp include/ArExport.h include/ariaOSDef.h \ + include/ArActionIRs.h include/ariaTypedefs.h include/ArAction.h \ + include/ArArg.h include/ariaUtil.h include/ArLog.h include/ArMutex.h \ + include/ArFunctor.h include/ariaOSDef.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArActionDesired.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArRobot.h \ + include/ArRobotPacketSender.h include/ArRobotPacket.h \ + include/ArBasePacket.h include/ArRobotPacketReceiver.h \ + include/ArSyncTask.h include/ArTaskState.h include/ArSensorReading.h \ + include/ArTransform.h include/ArCondition.h include/ArSyncLoop.h \ + include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArResolver.h \ + include/ArInterpolation.h include/ArKeyHandler.h include/ArCommands.h +obj/ArActionInput.o: src/ArActionInput.cpp include/ArExport.h \ + include/ariaOSDef.h include/ArActionInput.h include/ariaTypedefs.h \ + include/ArAction.h include/ArArg.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ariaOSDef.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArActionDesired.h include/ArRobot.h \ + include/ArRobotPacketSender.h include/ArRobotPacket.h \ + include/ArBasePacket.h include/ArRobotPacketReceiver.h \ + include/ArSyncTask.h include/ArTaskState.h include/ArSensorReading.h \ + include/ArTransform.h include/ArCondition.h include/ArSyncLoop.h \ + include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArRobotParams.h \ + include/ArConfig.h include/ArConfigArg.h include/ArFileParser.h \ + include/ArHasFileName.h include/ArResolver.h include/ArInterpolation.h \ + include/ArKeyHandler.h +obj/ArActionJoydrive.o: src/ArActionJoydrive.cpp include/ArExport.h \ + include/ariaOSDef.h include/ArActionJoydrive.h include/ariaTypedefs.h \ + include/ArAction.h include/ArArg.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ariaOSDef.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArActionDesired.h include/ArJoyHandler.h include/ArRobot.h \ + include/ArRobotPacketSender.h include/ArRobotPacket.h \ + include/ArBasePacket.h include/ArRobotPacketReceiver.h \ + include/ArSyncTask.h include/ArTaskState.h include/ArSensorReading.h \ + include/ArTransform.h include/ArCondition.h include/ArSyncLoop.h \ + include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArRobotParams.h \ + include/ArConfig.h include/ArConfigArg.h include/ArFileParser.h \ + include/ArHasFileName.h include/ArResolver.h include/ArInterpolation.h \ + include/ArKeyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h +obj/ArActionKeydrive.o: src/ArActionKeydrive.cpp include/ArExport.h \ + include/ariaOSDef.h include/ArActionKeydrive.h include/ariaTypedefs.h \ + include/ArAction.h include/ArArg.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ariaOSDef.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArActionDesired.h include/ArRobot.h \ + include/ArRobotPacketSender.h include/ArRobotPacket.h \ + include/ArBasePacket.h include/ArRobotPacketReceiver.h \ + include/ArSyncTask.h include/ArTaskState.h include/ArSensorReading.h \ + include/ArTransform.h include/ArCondition.h include/ArSyncLoop.h \ + include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArRobotParams.h \ + include/ArConfig.h include/ArConfigArg.h include/ArFileParser.h \ + include/ArHasFileName.h include/ArResolver.h include/ArInterpolation.h \ + include/ArKeyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArKeyHandler.h +obj/ArActionLimiterBackwards.o: src/ArActionLimiterBackwards.cpp \ + include/ArExport.h include/ariaOSDef.h \ + include/ArActionLimiterBackwards.h include/ariaTypedefs.h \ + include/ArAction.h include/ArArg.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ariaOSDef.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArActionDesired.h include/ArRobot.h \ + include/ArRobotPacketSender.h include/ArRobotPacket.h \ + include/ArBasePacket.h include/ArRobotPacketReceiver.h \ + include/ArSyncTask.h include/ArTaskState.h include/ArSensorReading.h \ + include/ArTransform.h include/ArCondition.h include/ArSyncLoop.h \ + include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArRobotParams.h \ + include/ArConfig.h include/ArConfigArg.h include/ArFileParser.h \ + include/ArHasFileName.h include/ArResolver.h include/ArInterpolation.h \ + include/ArKeyHandler.h +obj/ArActionLimiterForwards.o: src/ArActionLimiterForwards.cpp \ + include/ArExport.h include/ariaOSDef.h include/ArActionLimiterForwards.h \ + include/ariaTypedefs.h include/ArAction.h include/ArArg.h \ + include/ariaUtil.h include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ariaOSDef.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArActionDesired.h include/ArRobot.h \ + include/ArRobotPacketSender.h include/ArRobotPacket.h \ + include/ArBasePacket.h include/ArRobotPacketReceiver.h \ + include/ArSyncTask.h include/ArTaskState.h include/ArSensorReading.h \ + include/ArTransform.h include/ArCondition.h include/ArSyncLoop.h \ + include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArRobotParams.h \ + include/ArConfig.h include/ArConfigArg.h include/ArFileParser.h \ + include/ArHasFileName.h include/ArResolver.h include/ArInterpolation.h \ + include/ArKeyHandler.h +obj/ArActionLimiterRot.o: src/ArActionLimiterRot.cpp include/ArExport.h \ + include/ariaOSDef.h include/ArActionLimiterRot.h include/ariaTypedefs.h \ + include/ArAction.h include/ArArg.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ariaOSDef.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArActionDesired.h include/ArRobot.h \ + include/ArRobotPacketSender.h include/ArRobotPacket.h \ + include/ArBasePacket.h include/ArRobotPacketReceiver.h \ + include/ArSyncTask.h include/ArTaskState.h include/ArSensorReading.h \ + include/ArTransform.h include/ArCondition.h include/ArSyncLoop.h \ + include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArRobotParams.h \ + include/ArConfig.h include/ArConfigArg.h include/ArFileParser.h \ + include/ArHasFileName.h include/ArResolver.h include/ArInterpolation.h \ + include/ArKeyHandler.h include/ArCommands.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArRobotConfigPacketReader.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h +obj/ArActionLimiterTableSensor.o: src/ArActionLimiterTableSensor.cpp \ + include/ArExport.h include/ariaOSDef.h \ + include/ArActionLimiterTableSensor.h include/ariaTypedefs.h \ + include/ArAction.h include/ArArg.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ariaOSDef.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArActionDesired.h include/ArRobot.h \ + include/ArRobotPacketSender.h include/ArRobotPacket.h \ + include/ArBasePacket.h include/ArRobotPacketReceiver.h \ + include/ArSyncTask.h include/ArTaskState.h include/ArSensorReading.h \ + include/ArTransform.h include/ArCondition.h include/ArSyncLoop.h \ + include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArRobotParams.h \ + include/ArConfig.h include/ArConfigArg.h include/ArFileParser.h \ + include/ArHasFileName.h include/ArResolver.h include/ArInterpolation.h \ + include/ArKeyHandler.h +obj/ArActionMovementParameters.o: src/ArActionMovementParameters.cpp \ + include/ArExport.h include/ariaOSDef.h \ + include/ArActionMovementParameters.h include/ariaTypedefs.h \ + include/ArAction.h include/ArArg.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ariaOSDef.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArActionDesired.h include/ArMapObject.h include/ArConfig.h \ + include/ArConfigArg.h include/ArFileParser.h include/ArHasFileName.h \ + include/ArRobot.h include/ArRobotPacketSender.h include/ArRobotPacket.h \ + include/ArBasePacket.h include/ArRobotPacketReceiver.h \ + include/ArSyncTask.h include/ArTaskState.h include/ArSensorReading.h \ + include/ArTransform.h include/ArCondition.h include/ArSyncLoop.h \ + include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArRobotParams.h \ + include/ArConfig.h include/ArResolver.h include/ArInterpolation.h \ + include/ArKeyHandler.h +obj/ArActionMovementParametersDebugging.o: \ + src/ArActionMovementParametersDebugging.cpp include/ArExport.h \ + include/ariaOSDef.h include/ArActionMovementParametersDebugging.h \ + include/ariaTypedefs.h include/ArAction.h include/ArArg.h \ + include/ariaUtil.h include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ariaOSDef.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArActionDesired.h \ + include/ArMapObject.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArRobot.h \ + include/ArRobotPacketSender.h include/ArRobotPacket.h \ + include/ArBasePacket.h include/ArRobotPacketReceiver.h \ + include/ArSyncTask.h include/ArTaskState.h include/ArSensorReading.h \ + include/ArTransform.h include/ArCondition.h include/ArSyncLoop.h \ + include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArRobotParams.h \ + include/ArConfig.h include/ArResolver.h include/ArInterpolation.h \ + include/ArKeyHandler.h +obj/ArActionRatioInput.o: src/ArActionRatioInput.cpp include/ArExport.h \ + include/ariaOSDef.h include/ArActionRatioInput.h include/ariaTypedefs.h \ + include/ArAction.h include/ArArg.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ariaOSDef.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArActionDesired.h include/ArRobot.h \ + include/ArRobotPacketSender.h include/ArRobotPacket.h \ + include/ArBasePacket.h include/ArRobotPacketReceiver.h \ + include/ArSyncTask.h include/ArTaskState.h include/ArSensorReading.h \ + include/ArTransform.h include/ArCondition.h include/ArSyncLoop.h \ + include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArRobotParams.h \ + include/ArConfig.h include/ArConfigArg.h include/ArFileParser.h \ + include/ArHasFileName.h include/ArResolver.h include/ArInterpolation.h \ + include/ArKeyHandler.h +obj/ArActionRobotJoydrive.o: src/ArActionRobotJoydrive.cpp include/ArExport.h \ + include/ariaOSDef.h include/ArActionRobotJoydrive.h \ + include/ariaTypedefs.h include/ArAction.h include/ArArg.h \ + include/ariaUtil.h include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ariaOSDef.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArActionDesired.h include/ArRobot.h \ + include/ArRobotPacketSender.h include/ArRobotPacket.h \ + include/ArBasePacket.h include/ArRobotPacketReceiver.h \ + include/ArSyncTask.h include/ArTaskState.h include/ArSensorReading.h \ + include/ArTransform.h include/ArCondition.h include/ArSyncLoop.h \ + include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArRobotParams.h \ + include/ArConfig.h include/ArConfigArg.h include/ArFileParser.h \ + include/ArHasFileName.h include/ArResolver.h include/ArInterpolation.h \ + include/ArKeyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArCommands.h +obj/ArActionStallRecover.o: src/ArActionStallRecover.cpp include/ArExport.h \ + include/ariaOSDef.h include/ArRobot.h include/ariaTypedefs.h \ + include/ArRobotPacketSender.h include/ArRobotPacket.h \ + include/ArBasePacket.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ariaOSDef.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArRobotPacketReceiver.h include/ArSyncTask.h \ + include/ArTaskState.h include/ArSensorReading.h include/ArTransform.h \ + include/ArCondition.h include/ArSyncLoop.h include/ArASyncTask.h \ + include/ArThread.h include/ArRobotPacketReaderThread.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArResolver.h include/ArActionStallRecover.h include/ArAction.h \ + include/ArArg.h +obj/ArActionStop.o: src/ArActionStop.cpp include/ArExport.h \ + include/ariaOSDef.h include/ArActionStop.h include/ariaTypedefs.h \ + include/ArAction.h include/ArArg.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ariaOSDef.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArActionDesired.h include/ArRobot.h \ + include/ArRobotPacketSender.h include/ArRobotPacket.h \ + include/ArBasePacket.h include/ArRobotPacketReceiver.h \ + include/ArSyncTask.h include/ArTaskState.h include/ArSensorReading.h \ + include/ArTransform.h include/ArCondition.h include/ArSyncLoop.h \ + include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArRobotParams.h \ + include/ArConfig.h include/ArConfigArg.h include/ArFileParser.h \ + include/ArHasFileName.h include/ArResolver.h include/ArInterpolation.h \ + include/ArKeyHandler.h +obj/ArActionTriangleDriveTo.o: src/ArActionTriangleDriveTo.cpp \ + include/ArExport.h include/ariaOSDef.h include/ArActionTriangleDriveTo.h \ + include/ariaTypedefs.h include/ArAction.h include/ArArg.h \ + include/ariaUtil.h include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ariaOSDef.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArActionDesired.h \ + include/ArLineFinder.h include/ArRangeDevice.h include/ArRangeBuffer.h \ + include/ArTransform.h include/ArSensorReading.h include/ArDrawingData.h \ + include/ArRobot.h include/ArRobotPacketSender.h include/ArRobotPacket.h \ + include/ArBasePacket.h include/ArRobotPacketReceiver.h \ + include/ArSyncTask.h include/ArTaskState.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArRobotParams.h \ + include/ArConfig.h include/ArConfigArg.h include/ArFileParser.h \ + include/ArHasFileName.h include/ArResolver.h include/ArInterpolation.h \ + include/ArKeyHandler.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ariaInternal.h \ + include/ArStringInfoGroup.h +obj/ArActionTurn.o: src/ArActionTurn.cpp include/ArExport.h \ + include/ariaOSDef.h include/ArActionTurn.h include/ariaTypedefs.h \ + include/ArAction.h include/ArArg.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ariaOSDef.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArActionDesired.h include/ArRobot.h \ + include/ArRobotPacketSender.h include/ArRobotPacket.h \ + include/ArBasePacket.h include/ArRobotPacketReceiver.h \ + include/ArSyncTask.h include/ArTaskState.h include/ArSensorReading.h \ + include/ArTransform.h include/ArCondition.h include/ArSyncLoop.h \ + include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArRobotParams.h \ + include/ArConfig.h include/ArConfigArg.h include/ArFileParser.h \ + include/ArHasFileName.h include/ArResolver.h include/ArInterpolation.h \ + include/ArKeyHandler.h +obj/ArAnalogGyro.o: src/ArAnalogGyro.cpp include/ariaOSDef.h \ + include/ArCommands.h include/ArExport.h include/ArAnalogGyro.h \ + include/ariaTypedefs.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ariaOSDef.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h include/ArRobot.h \ + include/ArRobotPacketSender.h include/ArRobotPacket.h \ + include/ArBasePacket.h include/ArRobotPacketReceiver.h \ + include/ArSyncTask.h include/ArTaskState.h include/ArSensorReading.h \ + include/ArTransform.h include/ArCondition.h include/ArSyncLoop.h \ + include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArRobotParams.h \ + include/ArConfig.h include/ArConfigArg.h include/ArFileParser.h \ + include/ArHasFileName.h include/ArActionDesired.h include/ArResolver.h \ + include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArRobotConfigPacketReader.h +obj/ArArg.o: src/ArArg.cpp include/ArExport.h include/ariaOSDef.h \ + include/ArArg.h include/ariaTypedefs.h include/ariaUtil.h \ + include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ariaOSDef.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArLog.h include/ArArgumentBuilder.h +obj/ArArgumentBuilder.o: src/ArArgumentBuilder.cpp include/ArExport.h \ + include/ariaOSDef.h include/ArArgumentBuilder.h include/ariaTypedefs.h \ + include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ariaOSDef.h +obj/ArArgumentParser.o: src/ArArgumentParser.cpp include/ArExport.h \ + include/ariaOSDef.h include/ArArgumentBuilder.h include/ariaTypedefs.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ariaOSDef.h \ + include/ariaUtil.h include/ArLog.h include/ArArgumentParser.h +obj/ArBasePacket.o: src/ArBasePacket.cpp include/ArExport.h \ + include/ariaOSDef.h include/ArBasePacket.h include/ariaTypedefs.h \ + include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ariaOSDef.h +obj/ArBatteryConnector.o: src/ArBatteryConnector.cpp include/ArExport.h \ + include/ariaOSDef.h include/ArBatteryConnector.h include/ariaTypedefs.h \ + include/ArSerialConnection.h include/ArDeviceConnection.h \ + include/ariaUtil.h include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ariaOSDef.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArRobotConnector.h \ + include/ArRobot.h include/ArRobotPacketSender.h include/ArRobotPacket.h \ + include/ArRobotPacketReceiver.h include/ArSyncTask.h \ + include/ArTaskState.h include/ArSensorReading.h include/ArTransform.h \ + include/ArCondition.h include/ArSyncLoop.h include/ArASyncTask.h \ + include/ArThread.h include/ArRobotPacketReaderThread.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArBatteryMTX.h include/ArRangeDevice.h include/ArRangeBuffer.h \ + include/ArDrawingData.h include/ArRobot.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArCommands.h \ + include/ArRobotConfigPacketReader.h +obj/ArBatteryMTX.o: src/ArBatteryMTX.cpp include/ArExport.h \ + include/ariaOSDef.h include/ArBatteryMTX.h include/ariaTypedefs.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ariaUtil.h \ + include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ariaOSDef.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArTransform.h \ + include/ArSensorReading.h include/ArDrawingData.h include/ArRobot.h \ + include/ArRobotPacketSender.h include/ArRobotPacket.h \ + include/ArBasePacket.h include/ArRobotPacketReceiver.h \ + include/ArSyncTask.h include/ArTaskState.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArRobotParams.h \ + include/ArConfig.h include/ArConfigArg.h include/ArFileParser.h \ + include/ArHasFileName.h include/ArActionDesired.h include/ArResolver.h \ + include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArRobotConnector.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ArTcpConnection.h \ + include/ArSocket.h include/ArSensorReading.h \ + include/ArSerialConnection.h include/ariaInternal.h \ + include/ArStringInfoGroup.h +obj/ArBumpers.o: src/ArBumpers.cpp include/ArExport.h include/ariaOSDef.h \ + include/ArRobot.h include/ariaTypedefs.h include/ArRobotPacketSender.h \ + include/ArRobotPacket.h include/ArBasePacket.h include/ariaUtil.h \ + include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ariaOSDef.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArRobotPacketReceiver.h \ + include/ArSyncTask.h include/ArTaskState.h include/ArSensorReading.h \ + include/ArTransform.h include/ArCondition.h include/ArSyncLoop.h \ + include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArRobotParams.h \ + include/ArConfig.h include/ArConfigArg.h include/ArFileParser.h \ + include/ArHasFileName.h include/ArActionDesired.h include/ArResolver.h \ + include/ArInterpolation.h include/ArKeyHandler.h include/ArBumpers.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h +obj/ArCameraCollection.o: src/ArCameraCollection.cpp include/ArExport.h \ + include/ariaUtil.h include/ariaTypedefs.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ariaOSDef.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArCameraCollection.h include/ArConfigArg.h include/ariaUtil.h +obj/ArCameraCommands.o: src/ArCameraCommands.cpp include/ArExport.h \ + include/ariaUtil.h include/ariaTypedefs.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ariaOSDef.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArCameraCommands.h include/ariaUtil.h +obj/ArCondition_LIN.o: src/ArCondition_LIN.cpp include/ArExport.h \ + include/ariaOSDef.h include/ArCondition.h include/ArMutex.h \ + include/ariaTypedefs.h include/ArLog.h include/ArFunctor.h \ + include/ariaOSDef.h +obj/ArCondition_WIN.o: src/ArCondition_WIN.cpp include/ArExport.h \ + include/ariaOSDef.h include/ArCondition.h include/ArMutex.h \ + include/ariaTypedefs.h include/ArLog.h include/ArFunctor.h \ + include/ariaOSDef.h +obj/ArConfig.o: src/ArConfig.cpp include/ArExport.h include/ariaOSDef.h \ + include/ArConfig.h include/ArConfigArg.h include/ariaTypedefs.h \ + include/ariaUtil.h include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ariaOSDef.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArFileParser.h \ + include/ArHasFileName.h include/ArArgumentBuilder.h include/ArLog.h +obj/ArConfigArg.o: src/ArConfigArg.cpp include/ArExport.h include/ariaOSDef.h \ + include/ArConfigArg.h include/ariaTypedefs.h include/ariaUtil.h \ + include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ariaOSDef.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArLog.h include/ArArgumentBuilder.h \ + include/ArFileParser.h +obj/ArConfigGroup.o: src/ArConfigGroup.cpp include/ArExport.h \ + include/ariaOSDef.h include/ArConfigGroup.h include/ArConfig.h \ + include/ArConfigArg.h include/ariaTypedefs.h include/ariaUtil.h \ + include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ariaOSDef.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArFileParser.h \ + include/ArHasFileName.h include/ArArgumentBuilder.h include/ArLog.h +obj/ArDPPTU.o: src/ArDPPTU.cpp include/ArExport.h include/ariaOSDef.h \ + include/ArDPPTU.h include/ariaTypedefs.h include/ArRobot.h \ + include/ArRobotPacketSender.h include/ArRobotPacket.h \ + include/ArBasePacket.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ariaOSDef.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArRobotPacketReceiver.h include/ArSyncTask.h \ + include/ArTaskState.h include/ArSensorReading.h include/ArTransform.h \ + include/ArCondition.h include/ArSyncLoop.h include/ArASyncTask.h \ + include/ArThread.h include/ArRobotPacketReaderThread.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArPTZ.h include/ArCommands.h include/ArPTZConnector.h \ + include/ariaInternal.h include/ArStringInfoGroup.h include/ArCommands.h \ + include/ArBasePacket.h include/ariaInternal.h \ + include/ArDeviceConnection.h +obj/ArDataLogger.o: src/ArDataLogger.cpp include/ariaOSDef.h \ + include/ArExport.h include/ArRobot.h include/ariaTypedefs.h \ + include/ArRobotPacketSender.h include/ArRobotPacket.h \ + include/ArBasePacket.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ariaOSDef.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArRobotPacketReceiver.h include/ArSyncTask.h \ + include/ArTaskState.h include/ArSensorReading.h include/ArTransform.h \ + include/ArCondition.h include/ArSyncLoop.h include/ArASyncTask.h \ + include/ArThread.h include/ArRobotPacketReaderThread.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArConfig.h include/ArDataLogger.h \ + include/ArRobotBatteryPacketReader.h +obj/ArDeviceConnection.o: src/ArDeviceConnection.cpp include/ArExport.h \ + include/ariaOSDef.h include/ArDeviceConnection.h include/ariaTypedefs.h \ + include/ariaUtil.h include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ariaOSDef.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h +obj/ArFileParser.o: src/ArFileParser.cpp include/ArExport.h \ + include/ariaOSDef.h include/ArFileParser.h include/ariaTypedefs.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArFunctor.h include/ariaOSDef.h include/ariaUtil.h \ + include/ArLog.h include/ArMutex.h include/ArLog.h include/ariaUtil.h +obj/ArForbiddenRangeDevice.o: src/ArForbiddenRangeDevice.cpp \ + include/ArExport.h include/ariaOSDef.h include/ArRobot.h \ + include/ariaTypedefs.h include/ArRobotPacketSender.h \ + include/ArRobotPacket.h include/ArBasePacket.h include/ariaUtil.h \ + include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ariaOSDef.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArRobotPacketReceiver.h \ + include/ArSyncTask.h include/ArTaskState.h include/ArSensorReading.h \ + include/ArTransform.h include/ArCondition.h include/ArSyncLoop.h \ + include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArRobotParams.h \ + include/ArConfig.h include/ArConfigArg.h include/ArFileParser.h \ + include/ArHasFileName.h include/ArActionDesired.h include/ArResolver.h \ + include/ArInterpolation.h include/ArKeyHandler.h include/ariaUtil.h \ + include/ArForbiddenRangeDevice.h include/ArRangeDevice.h \ + include/ArRangeBuffer.h include/ArDrawingData.h include/ArMapInterface.h \ + include/ArMapObject.h include/ArMapUtils.h +obj/ArFunctorASyncTask.o: src/ArFunctorASyncTask.cpp include/ArExport.h \ + include/ariaOSDef.h include/ArFunctorASyncTask.h include/ariaTypedefs.h \ + include/ArASyncTask.h include/ArFunctor.h include/ariaOSDef.h \ + include/ArThread.h include/ArMutex.h include/ArLog.h +obj/ArGPS.o: src/ArGPS.cpp include/ArExport.h include/ariaOSDef.h \ + include/ArGPS.h include/ariaTypedefs.h include/ArFunctor.h \ + include/ariaOSDef.h include/ariaUtil.h include/ArLog.h include/ArMutex.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArNMEAParser.h include/ArDeviceConnection.h \ + include/ArBasePacket.h include/ArDeviceConnection.h \ + include/ArRobotPacket.h include/ArRobot.h include/ArRobotPacketSender.h \ + include/ArRobotPacket.h include/ArRobotPacketReceiver.h \ + include/ArSyncTask.h include/ArTaskState.h include/ArSensorReading.h \ + include/ArTransform.h include/ArCondition.h include/ArSyncLoop.h \ + include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArRobotParams.h \ + include/ArConfig.h include/ArConfigArg.h include/ArFileParser.h \ + include/ArHasFileName.h include/ArActionDesired.h include/ArResolver.h \ + include/ArInterpolation.h include/ArKeyHandler.h include/ArCommands.h \ + include/ariaInternal.h include/ArStringInfoGroup.h +obj/ArGPSConnector.o: src/ArGPSConnector.cpp include/ArExport.h \ + include/ariaOSDef.h include/ArGPSConnector.h include/ariaTypedefs.h \ + include/ariaUtil.h include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ariaOSDef.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArGPS.h include/ArNMEAParser.h \ + include/ArDeviceConnection.h include/ArBasePacket.h include/ArGPS.h \ + include/ArDeviceConnection.h include/ArSerialConnection.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArRobot.h \ + include/ArRobotPacketSender.h include/ArRobotPacket.h \ + include/ArRobotPacketReceiver.h include/ArSyncTask.h \ + include/ArTaskState.h include/ArSensorReading.h include/ArTransform.h \ + include/ArCondition.h include/ArSyncLoop.h include/ArASyncTask.h \ + include/ArThread.h include/ArRobotPacketReaderThread.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ariaInternal.h include/ArStringInfoGroup.h \ + include/ArNovatelGPS.h include/ArTrimbleGPS.h +obj/ArGPSCoords.o: src/ArGPSCoords.cpp include/ArExport.h include/ariaOSDef.h \ + include/ariaUtil.h include/ariaTypedefs.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ariaOSDef.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h include/ArLog.h \ + include/ArGPSCoords.h +obj/ArGripper.o: src/ArGripper.cpp include/ArExport.h include/ariaOSDef.h \ + include/ArGripper.h include/ariaTypedefs.h include/ArRobot.h \ + include/ArRobotPacketSender.h include/ArRobotPacket.h \ + include/ArBasePacket.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ariaOSDef.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArRobotPacketReceiver.h include/ArSyncTask.h \ + include/ArTaskState.h include/ArSensorReading.h include/ArTransform.h \ + include/ArCondition.h include/ArSyncLoop.h include/ArASyncTask.h \ + include/ArThread.h include/ArRobotPacketReaderThread.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h +obj/ArIRs.o: src/ArIRs.cpp include/ArExport.h include/ariaOSDef.h \ + include/ArRobot.h include/ariaTypedefs.h include/ArRobotPacketSender.h \ + include/ArRobotPacket.h include/ArBasePacket.h include/ariaUtil.h \ + include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ariaOSDef.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArRobotPacketReceiver.h \ + include/ArSyncTask.h include/ArTaskState.h include/ArSensorReading.h \ + include/ArTransform.h include/ArCondition.h include/ArSyncLoop.h \ + include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArRobotParams.h \ + include/ArConfig.h include/ArConfigArg.h include/ArFileParser.h \ + include/ArHasFileName.h include/ArActionDesired.h include/ArResolver.h \ + include/ArInterpolation.h include/ArKeyHandler.h include/ariaUtil.h \ + include/ArIRs.h include/ArRangeDevice.h include/ArRangeBuffer.h \ + include/ArDrawingData.h +obj/ArInterpolation.o: src/ArInterpolation.cpp include/ArExport.h \ + include/ariaOSDef.h include/ArInterpolation.h include/ariaTypedefs.h \ + include/ariaUtil.h include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ariaOSDef.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h +obj/ArIrrfDevice.o: src/ArIrrfDevice.cpp include/ArExport.h \ + include/ariaOSDef.h include/ArIrrfDevice.h include/ariaTypedefs.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ariaUtil.h \ + include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ariaOSDef.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArTransform.h \ + include/ArSensorReading.h include/ArDrawingData.h include/ArRobot.h \ + include/ArRobotPacketSender.h include/ArRobotPacket.h \ + include/ArBasePacket.h include/ArRobotPacketReceiver.h \ + include/ArSyncTask.h include/ArTaskState.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArRobotParams.h \ + include/ArConfig.h include/ArConfigArg.h include/ArFileParser.h \ + include/ArHasFileName.h include/ArActionDesired.h include/ArResolver.h \ + include/ArInterpolation.h include/ArKeyHandler.h include/ArCommands.h +obj/ArJoyHandler.o: src/ArJoyHandler.cpp include/ariaOSDef.h \ + include/ArExport.h include/ArJoyHandler.h include/ariaTypedefs.h \ + include/ariaUtil.h include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ariaOSDef.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ariaUtil.h +obj/ArJoyHandler_LIN.o: src/ArJoyHandler_LIN.cpp include/ArExport.h \ + include/ariaOSDef.h include/ArJoyHandler.h include/ariaTypedefs.h \ + include/ariaUtil.h include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ariaOSDef.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArLog.h include/ariaUtil.h +obj/ArJoyHandler_WIN.o: src/ArJoyHandler_WIN.cpp include/ArExport.h \ + include/ariaOSDef.h include/ArJoyHandler.h include/ariaTypedefs.h \ + include/ariaUtil.h include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ariaOSDef.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h +obj/ArKeyHandler.o: src/ArKeyHandler.cpp include/ArExport.h \ + include/ariaOSDef.h include/ArKeyHandler.h include/ariaTypedefs.h \ + include/ArFunctor.h include/ariaOSDef.h include/ArLog.h \ + include/ArMutex.h include/ariaInternal.h include/ArConfig.h \ + include/ArConfigArg.h include/ariaUtil.h include/ArLog.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArFileParser.h include/ArHasFileName.h \ + include/ArStringInfoGroup.h +obj/ArLCDConnector.o: src/ArLCDConnector.cpp include/ArExport.h \ + include/ariaOSDef.h include/ArLCDConnector.h include/ariaTypedefs.h \ + include/ArSerialConnection.h include/ArDeviceConnection.h \ + include/ariaUtil.h include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ariaOSDef.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArRobotConnector.h \ + include/ArRobot.h include/ArRobotPacketSender.h include/ArRobotPacket.h \ + include/ArRobotPacketReceiver.h include/ArSyncTask.h \ + include/ArTaskState.h include/ArSensorReading.h include/ArTransform.h \ + include/ArCondition.h include/ArSyncLoop.h include/ArASyncTask.h \ + include/ArThread.h include/ArRobotPacketReaderThread.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArLCDMTX.h include/ArRangeDevice.h include/ArRangeBuffer.h \ + include/ArDrawingData.h include/ArRobot.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArCommands.h \ + include/ArRobotConfigPacketReader.h +obj/ArLCDMTX.o: src/ArLCDMTX.cpp include/ArExport.h include/ariaOSDef.h \ + include/ArLCDMTX.h include/ariaTypedefs.h include/ArRangeDevice.h \ + include/ArRangeBuffer.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ariaOSDef.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArTransform.h include/ArSensorReading.h include/ArDrawingData.h \ + include/ArRobot.h include/ArRobotPacketSender.h include/ArRobotPacket.h \ + include/ArBasePacket.h include/ArRobotPacketReceiver.h \ + include/ArSyncTask.h include/ArTaskState.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArRobotParams.h \ + include/ArConfig.h include/ArConfigArg.h include/ArFileParser.h \ + include/ArHasFileName.h include/ArActionDesired.h include/ArResolver.h \ + include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArRobotConnector.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ArTcpConnection.h \ + include/ArSocket.h include/ArSensorReading.h \ + include/ArSerialConnection.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSystemStatus.h +obj/ArLMS1XX.o: src/ArLMS1XX.cpp include/ArExport.h include/ariaOSDef.h \ + include/ArLMS1XX.h include/ariaTypedefs.h include/ArRobotPacket.h \ + include/ArBasePacket.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ariaOSDef.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h include/ArLaser.h \ + include/ArRangeDeviceThreaded.h include/ArRangeDevice.h \ + include/ArRangeBuffer.h include/ArTransform.h include/ArSensorReading.h \ + include/ArDrawingData.h include/ArFunctorASyncTask.h \ + include/ArASyncTask.h include/ArThread.h include/ArRobot.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArSyncTask.h include/ArTaskState.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArRobotPacketReaderThread.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArSerialConnection.h include/ArDeviceConnection.h \ + include/ariaInternal.h include/ArStringInfoGroup.h +obj/ArLMS2xx.o: src/ArLMS2xx.cpp include/ArExport.h include/ariaOSDef.h \ + include/ArLMS2xx.h include/ariaTypedefs.h include/ArLMS2xxPacket.h \ + include/ArBasePacket.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ariaOSDef.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArLMS2xxPacketReceiver.h include/ArDeviceConnection.h \ + include/ArRobotPacket.h include/ArLaser.h \ + include/ArRangeDeviceThreaded.h include/ArRangeDevice.h \ + include/ArRangeBuffer.h include/ArTransform.h include/ArSensorReading.h \ + include/ArDrawingData.h include/ArFunctorASyncTask.h \ + include/ArASyncTask.h include/ArThread.h include/ArCondition.h \ + include/ArRobot.h include/ArRobotPacketSender.h \ + include/ArRobotPacketReceiver.h include/ArSyncTask.h \ + include/ArTaskState.h include/ArSyncLoop.h \ + include/ArRobotPacketReaderThread.h include/ArRobotParams.h \ + include/ArConfig.h include/ArConfigArg.h include/ArFileParser.h \ + include/ArHasFileName.h include/ArActionDesired.h include/ArResolver.h \ + include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArSerialConnection.h include/ariaInternal.h \ + include/ArStringInfoGroup.h +obj/ArLMS2xxPacket.o: src/ArLMS2xxPacket.cpp include/ArExport.h \ + include/ariaOSDef.h include/ArLMS2xxPacket.h include/ariaTypedefs.h \ + include/ArBasePacket.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ariaOSDef.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h +obj/ArLMS2xxPacketReceiver.o: src/ArLMS2xxPacketReceiver.cpp \ + include/ArExport.h include/ariaOSDef.h include/ArLMS2xxPacketReceiver.h \ + include/ariaTypedefs.h include/ArDeviceConnection.h include/ariaUtil.h \ + include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ariaOSDef.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArLMS2xxPacket.h include/ArLog.h include/ariaUtil.h +obj/ArLaser.o: src/ArLaser.cpp include/ArExport.h include/ariaOSDef.h \ + include/ArLaser.h include/ariaTypedefs.h include/ArRangeDeviceThreaded.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ariaUtil.h \ + include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ariaOSDef.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArTransform.h \ + include/ArSensorReading.h include/ArDrawingData.h \ + include/ArFunctorASyncTask.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobot.h include/ArRobotPacketSender.h include/ArRobotPacket.h \ + include/ArBasePacket.h include/ArRobotPacketReceiver.h \ + include/ArSyncTask.h include/ArTaskState.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArRobotPacketReaderThread.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArDeviceConnection.h +obj/ArLaserConnector.o: src/ArLaserConnector.cpp include/ArExport.h \ + include/ariaOSDef.h include/ArLaserConnector.h include/ariaTypedefs.h \ + include/ArSerialConnection.h include/ArDeviceConnection.h \ + include/ariaUtil.h include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ariaOSDef.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArRobotConnector.h \ + include/ArRobot.h include/ArRobotPacketSender.h include/ArRobotPacket.h \ + include/ArRobotPacketReceiver.h include/ArSyncTask.h \ + include/ArTaskState.h include/ArSensorReading.h include/ArTransform.h \ + include/ArCondition.h include/ArSyncLoop.h include/ArASyncTask.h \ + include/ArThread.h include/ArRobotPacketReaderThread.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArFunctorASyncTask.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSick.h include/ArLaser.h \ + include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArUrg.h \ + include/ArSimulatedLaser.h include/ArCommands.h \ + include/ArRobotConfigPacketReader.h +obj/ArLaserFilter.o: src/ArLaserFilter.cpp include/ArExport.h \ + include/ArLaserFilter.h include/ArLaser.h include/ariaTypedefs.h \ + include/ArRangeDeviceThreaded.h include/ArRangeDevice.h \ + include/ArRangeBuffer.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ariaOSDef.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArTransform.h include/ArSensorReading.h include/ArDrawingData.h \ + include/ArFunctorASyncTask.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobot.h include/ArRobotPacketSender.h include/ArRobotPacket.h \ + include/ArBasePacket.h include/ArRobotPacketReceiver.h \ + include/ArSyncTask.h include/ArTaskState.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArRobotPacketReaderThread.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArConfig.h +obj/ArLaserLogger.o: src/ArLaserLogger.cpp include/ArExport.h \ + include/ariaOSDef.h include/ArLaserLogger.h include/ariaUtil.h \ + include/ariaTypedefs.h include/ArLog.h include/ArMutex.h \ + include/ArFunctor.h include/ariaOSDef.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArRobot.h \ + include/ArRobotPacketSender.h include/ArRobotPacket.h \ + include/ArBasePacket.h include/ArRobotPacketReceiver.h \ + include/ArSyncTask.h include/ArTaskState.h include/ArSensorReading.h \ + include/ArTransform.h include/ArCondition.h include/ArSyncLoop.h \ + include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArRobotParams.h \ + include/ArConfig.h include/ArConfigArg.h include/ArFileParser.h \ + include/ArHasFileName.h include/ArActionDesired.h include/ArResolver.h \ + include/ArInterpolation.h include/ArKeyHandler.h include/ArLaser.h \ + include/ArRangeDeviceThreaded.h include/ArRangeDevice.h \ + include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArFunctorASyncTask.h include/ArJoyHandler.h \ + include/ArRobotJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h +obj/ArLaserReflectorDevice.o: src/ArLaserReflectorDevice.cpp \ + include/ArExport.h include/ariaOSDef.h include/ArSick.h \ + include/ariaTypedefs.h include/ArRobotPacket.h include/ArBasePacket.h \ + include/ariaUtil.h include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ariaOSDef.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArLaser.h \ + include/ArRangeDeviceThreaded.h include/ArRangeDevice.h \ + include/ArRangeBuffer.h include/ArTransform.h include/ArSensorReading.h \ + include/ArDrawingData.h include/ArFunctorASyncTask.h \ + include/ArASyncTask.h include/ArThread.h include/ArCondition.h \ + include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArDeviceConnection.h \ + include/ArLaserReflectorDevice.h include/ArRobot.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArSyncTask.h include/ArTaskState.h include/ArSyncLoop.h \ + include/ArRobotPacketReaderThread.h include/ArRobotParams.h \ + include/ArConfig.h include/ArConfigArg.h include/ArFileParser.h \ + include/ArHasFileName.h include/ArActionDesired.h include/ArResolver.h \ + include/ArInterpolation.h include/ArKeyHandler.h +obj/ArLineFinder.o: src/ArLineFinder.cpp include/ArExport.h \ + include/ariaOSDef.h include/ArLineFinder.h include/ariaTypedefs.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ariaUtil.h \ + include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ariaOSDef.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArTransform.h \ + include/ArSensorReading.h include/ArDrawingData.h include/ArConfig.h \ + include/ArConfigArg.h include/ArFileParser.h include/ArHasFileName.h +obj/ArLog.o: src/ArLog.cpp include/ArExport.h include/ariaOSDef.h \ + include/ArLog.h include/ariaTypedefs.h include/ArMutex.h \ + include/ArFunctor.h include/ariaOSDef.h include/ArConfig.h \ + include/ArConfigArg.h include/ariaUtil.h include/ArLog.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArFileParser.h include/ArHasFileName.h include/ariaInternal.h \ + include/ArConfig.h include/ArStringInfoGroup.h +obj/ArLogFileConnection.o: src/ArLogFileConnection.cpp include/ArExport.h \ + include/ariaOSDef.h include/ArLogFileConnection.h \ + include/ArDeviceConnection.h include/ariaTypedefs.h include/ariaUtil.h \ + include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ariaOSDef.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h include/ArLog.h \ + include/ariaUtil.h +obj/ArMD5Calculator.o: src/ArMD5Calculator.cpp include/ArExport.h \ + include/ArMD5Calculator.h include/ariaTypedefs.h include/ariaUtil.h \ + include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ariaOSDef.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/md5.h include/ariaOSDef.h \ + include/ariaInternal.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h \ + include/ArStringInfoGroup.h include/ArLog.h +obj/ArMTXIO.o: src/ArMTXIO.cpp include/ArExport.h include/ariaOSDef.h \ + include/ArMTXIO.h include/ariaTypedefs.h include/ArRobot.h \ + include/ArRobotPacketSender.h include/ArRobotPacket.h \ + include/ArBasePacket.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ariaOSDef.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArRobotPacketReceiver.h include/ArSyncTask.h \ + include/ArTaskState.h include/ArSensorReading.h include/ArTransform.h \ + include/ArCondition.h include/ArSyncLoop.h include/ArASyncTask.h \ + include/ArThread.h include/ArRobotPacketReaderThread.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ariaInternal.h include/ArStringInfoGroup.h +obj/ArMap.o: src/ArMap.cpp include/ArExport.h include/ariaOSDef.h \ + include/ariaInternal.h include/ArMutex.h include/ariaTypedefs.h \ + include/ArFunctor.h include/ariaOSDef.h include/ArConfig.h \ + include/ArConfigArg.h include/ariaUtil.h include/ArLog.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArFileParser.h include/ArHasFileName.h \ + include/ArStringInfoGroup.h include/ArMap.h include/ArMapComponents.h \ + include/ArMapInterface.h include/ArMapObject.h include/ArMapUtils.h \ + include/ArLog.h +obj/ArMapComponents.o: src/ArMapComponents.cpp include/ArExport.h \ + include/ArMapComponents.h include/ArMapInterface.h \ + include/ariaTypedefs.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ariaOSDef.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArMapObject.h include/ArMapUtils.h include/ArHasFileName.h \ + include/ArFileParser.h include/ArMapUtils.h include/ArMD5Calculator.h \ + include/md5.h +obj/ArMapInterface.o: src/ArMapInterface.cpp include/ArExport.h \ + include/ariaOSDef.h include/ariaInternal.h include/ArMutex.h \ + include/ariaTypedefs.h include/ArFunctor.h include/ariaOSDef.h \ + include/ArConfig.h include/ArConfigArg.h include/ariaUtil.h \ + include/ArLog.h include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArFileParser.h include/ArHasFileName.h \ + include/ArStringInfoGroup.h include/ArMapInterface.h \ + include/ArMapObject.h include/ArMapUtils.h +obj/ArMapObject.o: src/ArMapObject.cpp include/ArExport.h \ + include/ArMapObject.h include/ariaTypedefs.h include/ariaUtil.h \ + include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ariaOSDef.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h +obj/ArMapUtils.o: src/ArMapUtils.cpp include/ArExport.h include/ArMapUtils.h \ + include/ariaTypedefs.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ariaOSDef.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ariaUtil.h include/ArBasePacket.h include/ArMapComponents.h \ + include/ArMapInterface.h include/ArMapObject.h include/ArMapUtils.h \ + include/ArHasFileName.h include/ArMD5Calculator.h include/md5.h +obj/ArMode.o: src/ArMode.cpp include/ArExport.h include/ariaOSDef.h \ + include/ArMode.h include/ariaTypedefs.h include/ArFunctor.h \ + include/ariaOSDef.h include/ArRobot.h include/ArRobotPacketSender.h \ + include/ArRobotPacket.h include/ArBasePacket.h include/ariaUtil.h \ + include/ArLog.h include/ArMutex.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArRobotPacketReceiver.h \ + include/ArSyncTask.h include/ArTaskState.h include/ArSensorReading.h \ + include/ArTransform.h include/ArCondition.h include/ArSyncLoop.h \ + include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArRobotParams.h \ + include/ArConfig.h include/ArConfigArg.h include/ArFileParser.h \ + include/ArHasFileName.h include/ArActionDesired.h include/ArResolver.h \ + include/ArInterpolation.h include/ArKeyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h +obj/ArModes.o: src/ArModes.cpp include/ArExport.h include/ariaOSDef.h \ + include/ArMode.h include/ariaTypedefs.h include/ArFunctor.h \ + include/ariaOSDef.h include/ArModes.h include/ArMode.h \ + include/ArActionGroups.h include/ArActionGroup.h \ + include/ArActionColorFollow.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArAction.h include/ArArg.h include/ArActionDesired.h \ + include/ArACTS.h include/ArTcpConnection.h include/ArDeviceConnection.h \ + include/ArBasePacket.h include/ArSocket.h include/ArRobot.h \ + include/ArRobotPacketSender.h include/ArRobotPacket.h \ + include/ArRobotPacketReceiver.h include/ArSyncTask.h \ + include/ArTaskState.h include/ArSensorReading.h include/ArTransform.h \ + include/ArCondition.h include/ArSyncLoop.h include/ArASyncTask.h \ + include/ArThread.h include/ArRobotPacketReaderThread.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArResolver.h \ + include/ArInterpolation.h include/ArKeyHandler.h include/ArPTZ.h \ + include/ArCommands.h include/ArPTZConnector.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArGripper.h \ + include/ArSerialConnection.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArRobotConfigPacketReader.h \ + include/ArKeyHandler.h include/ArSonyPTZ.h include/ArVCC4.h \ + include/ArDPPTU.h include/ArAMPTU.h include/ArRVisionPTZ.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArAnalogGyro.h \ + include/ArRobotConfigPacketReader.h include/ariaInternal.h +obj/ArModule.o: src/ArModule.cpp include/ArExport.h include/ariaOSDef.h \ + include/ArModule.h include/ariaTypedefs.h include/ArRobot.h \ + include/ArRobotPacketSender.h include/ArRobotPacket.h \ + include/ArBasePacket.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ariaOSDef.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArRobotPacketReceiver.h include/ArSyncTask.h \ + include/ArTaskState.h include/ArSensorReading.h include/ArTransform.h \ + include/ArCondition.h include/ArSyncLoop.h include/ArASyncTask.h \ + include/ArThread.h include/ArRobotPacketReaderThread.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h +obj/ArModuleLoader.o: src/ArModuleLoader.cpp include/ArExport.h \ + include/ariaOSDef.h include/ArModuleLoader.h include/ariaTypedefs.h \ + include/ArRobot.h include/ArRobotPacketSender.h include/ArRobotPacket.h \ + include/ArBasePacket.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ariaOSDef.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArRobotPacketReceiver.h include/ArSyncTask.h \ + include/ArTaskState.h include/ArSensorReading.h include/ArTransform.h \ + include/ArCondition.h include/ArSyncLoop.h include/ArASyncTask.h \ + include/ArThread.h include/ArRobotPacketReaderThread.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArModule.h include/ArLog.h +obj/ArMutex.o: src/ArMutex.cpp include/ArExport.h include/ArMutex.h \ + include/ariaTypedefs.h include/ariaOSDef.h include/ariaUtil.h \ + include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ariaOSDef.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArThread.h +obj/ArMutex_LIN.o: src/ArMutex_LIN.cpp include/ArExport.h include/ariaOSDef.h \ + include/ArMutex.h include/ariaTypedefs.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ariaOSDef.h \ + include/ArThread.h include/ArLog.h include/ariaUtil.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ariaInternal.h include/ArConfig.h include/ArConfigArg.h \ + include/ariaUtil.h include/ArFileParser.h include/ArHasFileName.h \ + include/ArStringInfoGroup.h include/ArFunctor.h +obj/ArMutex_WIN.o: src/ArMutex_WIN.cpp include/ArExport.h include/ariaOSDef.h \ + include/ArMutex.h include/ariaTypedefs.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ariaOSDef.h \ + include/ArFunctor.h include/ArThread.h include/ArLog.h \ + include/ariaInternal.h include/ArConfig.h include/ArConfigArg.h \ + include/ariaUtil.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArFileParser.h \ + include/ArHasFileName.h include/ArStringInfoGroup.h +obj/ArNMEAParser.o: src/ArNMEAParser.cpp include/ArExport.h \ + include/ariaOSDef.h include/ArNMEAParser.h include/ariaTypedefs.h \ + include/ArFunctor.h include/ariaOSDef.h include/ariaUtil.h \ + include/ArLog.h include/ArMutex.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArDeviceConnection.h \ + include/ArBasePacket.h +obj/ArNetServer.o: src/ArNetServer.cpp include/ArExport.h include/ariaOSDef.h \ + include/ArNetServer.h include/ariaTypedefs.h include/ArSocket.h \ + include/ArMutex.h include/ariaUtil.h include/ArLog.h include/ArFunctor.h \ + include/ariaOSDef.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArRobot.h \ + include/ArRobotPacketSender.h include/ArRobotPacket.h \ + include/ArBasePacket.h include/ArRobotPacketReceiver.h \ + include/ArSyncTask.h include/ArTaskState.h include/ArSensorReading.h \ + include/ArTransform.h include/ArCondition.h include/ArSyncLoop.h \ + include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArRobotParams.h \ + include/ArConfig.h include/ArConfigArg.h include/ArFileParser.h \ + include/ArHasFileName.h include/ArActionDesired.h include/ArResolver.h \ + include/ArInterpolation.h include/ArKeyHandler.h include/ArLog.h \ + include/ariaUtil.h include/ArSyncTask.h include/ArArgumentBuilder.h \ + include/ariaInternal.h include/ArStringInfoGroup.h +obj/ArNovatelGPS.o: src/ArNovatelGPS.cpp include/ArExport.h \ + include/ariaOSDef.h include/ArNovatelGPS.h include/ariaTypedefs.h \ + include/ArFunctor.h include/ariaOSDef.h include/ariaUtil.h \ + include/ArLog.h include/ArMutex.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArGPS.h include/ArNMEAParser.h \ + include/ArDeviceConnection.h include/ArBasePacket.h \ + include/ArDeviceConnection.h +obj/ArP2Arm.o: src/ArP2Arm.cpp include/ArExport.h include/ariaOSDef.h \ + include/ArP2Arm.h include/ArRobot.h include/ariaTypedefs.h \ + include/ArRobotPacketSender.h include/ArRobotPacket.h \ + include/ArBasePacket.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ariaOSDef.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArRobotPacketReceiver.h include/ArSyncTask.h \ + include/ArTaskState.h include/ArSensorReading.h include/ArTransform.h \ + include/ArCondition.h include/ArSyncLoop.h include/ArASyncTask.h \ + include/ArThread.h include/ArRobotPacketReaderThread.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArSerialConnection.h include/ArDeviceConnection.h \ + include/ariaUtil.h include/ArLog.h include/ariaInternal.h \ + include/ArStringInfoGroup.h +obj/ArPTZ.o: src/ArPTZ.cpp include/ArExport.h include/ariaOSDef.h \ + include/ArPTZ.h include/ariaTypedefs.h include/ArFunctor.h \ + include/ariaOSDef.h include/ArCommands.h include/ArPTZConnector.h \ + include/ariaUtil.h include/ArLog.h include/ArMutex.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArRobot.h \ + include/ArRobotPacketSender.h include/ArRobotPacket.h \ + include/ArBasePacket.h include/ArRobotPacketReceiver.h \ + include/ArSyncTask.h include/ArTaskState.h include/ArSensorReading.h \ + include/ArTransform.h include/ArCondition.h include/ArSyncLoop.h \ + include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArRobotPacket.h include/ArCommands.h \ + include/ArDeviceConnection.h +obj/ArPTZConnector.o: src/ArPTZConnector.cpp include/ArExport.h \ + include/ariaUtil.h include/ariaTypedefs.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ariaOSDef.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ariaInternal.h include/ArConfig.h include/ArConfigArg.h \ + include/ariaUtil.h include/ArFileParser.h include/ArHasFileName.h \ + include/ArStringInfoGroup.h include/ArLog.h include/ArFunctor.h \ + include/ArPTZ.h include/ArCommands.h include/ArPTZConnector.h \ + include/ArRobotParams.h include/ariaInternal.h include/ArPTZConnector.h \ + include/ArConfig.h include/ArRobot.h include/ArRobotPacketSender.h \ + include/ArRobotPacket.h include/ArBasePacket.h \ + include/ArRobotPacketReceiver.h include/ArSyncTask.h \ + include/ArTaskState.h include/ArSensorReading.h include/ArTransform.h \ + include/ArCondition.h include/ArSyncLoop.h include/ArASyncTask.h \ + include/ArThread.h include/ArRobotPacketReaderThread.h \ + include/ArActionDesired.h include/ArResolver.h include/ArInterpolation.h \ + include/ArKeyHandler.h include/ArRobotParams.h +obj/ArPriorityResolver.o: src/ArPriorityResolver.cpp include/ArExport.h \ + include/ariaOSDef.h include/ArPriorityResolver.h include/ArResolver.h \ + include/ariaTypedefs.h include/ArActionDesired.h include/ariaUtil.h \ + include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ariaOSDef.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArAction.h include/ArArg.h \ + include/ArRobot.h include/ArRobotPacketSender.h include/ArRobotPacket.h \ + include/ArBasePacket.h include/ArRobotPacketReceiver.h \ + include/ArSyncTask.h include/ArTaskState.h include/ArSensorReading.h \ + include/ArTransform.h include/ArCondition.h include/ArSyncLoop.h \ + include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArRobotParams.h \ + include/ArConfig.h include/ArConfigArg.h include/ArFileParser.h \ + include/ArHasFileName.h include/ArInterpolation.h include/ArKeyHandler.h +obj/ArRVisionPTZ.o: src/ArRVisionPTZ.cpp include/ArExport.h \ + include/ariaOSDef.h include/ArRVisionPTZ.h include/ariaTypedefs.h \ + include/ArBasePacket.h include/ArPTZ.h include/ArFunctor.h \ + include/ariaOSDef.h include/ArCommands.h include/ArPTZConnector.h \ + include/ariaUtil.h include/ArLog.h include/ArMutex.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ArRobot.h \ + include/ArRobotPacketSender.h include/ArRobotPacket.h \ + include/ArRobotPacketReceiver.h include/ArSyncTask.h \ + include/ArTaskState.h include/ArSensorReading.h include/ArTransform.h \ + include/ArCondition.h include/ArSyncLoop.h include/ArASyncTask.h \ + include/ArThread.h include/ArRobotPacketReaderThread.h \ + include/ArActionDesired.h include/ArResolver.h include/ArInterpolation.h \ + include/ArKeyHandler.h include/ArCommands.h +obj/ArRangeBuffer.o: src/ArRangeBuffer.cpp include/ArExport.h \ + include/ariaOSDef.h include/ArRangeBuffer.h include/ariaUtil.h \ + include/ariaTypedefs.h include/ArLog.h include/ArMutex.h \ + include/ArFunctor.h include/ariaOSDef.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArTransform.h include/ArLog.h +obj/ArRangeDevice.o: src/ArRangeDevice.cpp include/ArExport.h \ + include/ariaOSDef.h include/ArRangeDevice.h include/ariaTypedefs.h \ + include/ArRangeBuffer.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ariaOSDef.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArTransform.h include/ArSensorReading.h include/ArDrawingData.h \ + include/ArRobot.h include/ArRobotPacketSender.h include/ArRobotPacket.h \ + include/ArBasePacket.h include/ArRobotPacketReceiver.h \ + include/ArSyncTask.h include/ArTaskState.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArRobotParams.h \ + include/ArConfig.h include/ArConfigArg.h include/ArFileParser.h \ + include/ArHasFileName.h include/ArActionDesired.h include/ArResolver.h \ + include/ArInterpolation.h include/ArKeyHandler.h +obj/ArRangeDeviceThreaded.o: src/ArRangeDeviceThreaded.cpp include/ArExport.h \ + include/ariaOSDef.h include/ArRangeDeviceThreaded.h \ + include/ariaTypedefs.h include/ArRangeDevice.h include/ArRangeBuffer.h \ + include/ariaUtil.h include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ariaOSDef.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArTransform.h \ + include/ArSensorReading.h include/ArDrawingData.h \ + include/ArFunctorASyncTask.h include/ArASyncTask.h include/ArThread.h +obj/ArRatioInputJoydrive.o: src/ArRatioInputJoydrive.cpp include/ArExport.h \ + include/ariaOSDef.h include/ArRatioInputJoydrive.h \ + include/ariaTypedefs.h include/ArAction.h include/ArArg.h \ + include/ariaUtil.h include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ariaOSDef.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArActionDesired.h \ + include/ArActionRatioInput.h include/ArJoyHandler.h include/ArRobot.h \ + include/ArRobotPacketSender.h include/ArRobotPacket.h \ + include/ArBasePacket.h include/ArRobotPacketReceiver.h \ + include/ArSyncTask.h include/ArTaskState.h include/ArSensorReading.h \ + include/ArTransform.h include/ArCondition.h include/ArSyncLoop.h \ + include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArRobotParams.h \ + include/ArConfig.h include/ArConfigArg.h include/ArFileParser.h \ + include/ArHasFileName.h include/ArResolver.h include/ArInterpolation.h \ + include/ArKeyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h +obj/ArRatioInputKeydrive.o: src/ArRatioInputKeydrive.cpp include/ArExport.h \ + include/ariaOSDef.h include/ArRatioInputKeydrive.h \ + include/ariaTypedefs.h include/ArAction.h include/ArArg.h \ + include/ariaUtil.h include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ariaOSDef.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArActionDesired.h \ + include/ArActionRatioInput.h include/ArRobot.h \ + include/ArRobotPacketSender.h include/ArRobotPacket.h \ + include/ArBasePacket.h include/ArRobotPacketReceiver.h \ + include/ArSyncTask.h include/ArTaskState.h include/ArSensorReading.h \ + include/ArTransform.h include/ArCondition.h include/ArSyncLoop.h \ + include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArRobotParams.h \ + include/ArConfig.h include/ArConfigArg.h include/ArFileParser.h \ + include/ArHasFileName.h include/ArResolver.h include/ArInterpolation.h \ + include/ArKeyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArKeyHandler.h +obj/ArRatioInputRobotJoydrive.o: src/ArRatioInputRobotJoydrive.cpp \ + include/ArExport.h include/ariaOSDef.h \ + include/ArRatioInputRobotJoydrive.h include/ariaTypedefs.h \ + include/ArActionRatioInput.h include/ArAction.h include/ArArg.h \ + include/ariaUtil.h include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ariaOSDef.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArActionDesired.h include/ArRobot.h \ + include/ArRobotPacketSender.h include/ArRobotPacket.h \ + include/ArBasePacket.h include/ArRobotPacketReceiver.h \ + include/ArSyncTask.h include/ArTaskState.h include/ArSensorReading.h \ + include/ArTransform.h include/ArCondition.h include/ArSyncLoop.h \ + include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArRobotParams.h \ + include/ArConfig.h include/ArConfigArg.h include/ArFileParser.h \ + include/ArHasFileName.h include/ArResolver.h include/ArInterpolation.h \ + include/ArKeyHandler.h include/ArRobotJoyHandler.h \ + include/ariaInternal.h include/ArStringInfoGroup.h include/ArCommands.h +obj/ArRecurrentTask.o: src/ArRecurrentTask.cpp include/ArExport.h \ + include/ariaOSDef.h include/ArASyncTask.h include/ariaTypedefs.h \ + include/ArFunctor.h include/ariaOSDef.h include/ArThread.h \ + include/ArMutex.h include/ArLog.h include/ArLog.h \ + include/ArRecurrentTask.h include/ArASyncTask.h +obj/ArRobot.o: src/ArRobot.cpp include/ArExport.h include/ariaOSDef.h \ + include/ArRobot.h include/ariaTypedefs.h include/ArRobotPacketSender.h \ + include/ArRobotPacket.h include/ArBasePacket.h include/ariaUtil.h \ + include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ariaOSDef.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArRobotPacketReceiver.h \ + include/ArSyncTask.h include/ArTaskState.h include/ArSensorReading.h \ + include/ArTransform.h include/ArCondition.h include/ArSyncLoop.h \ + include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArRobotParams.h \ + include/ArConfig.h include/ArConfigArg.h include/ArFileParser.h \ + include/ArHasFileName.h include/ArActionDesired.h include/ArResolver.h \ + include/ArInterpolation.h include/ArKeyHandler.h include/ArLog.h \ + include/ArDeviceConnection.h include/ArTcpConnection.h \ + include/ArDeviceConnection.h include/ArSocket.h \ + include/ArSerialConnection.h include/ArLogFileConnection.h \ + include/ariaUtil.h include/ArSocket.h include/ArCommands.h \ + include/ArRobotTypes.h include/ArSignalHandler.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArRobotConfigPacketReader.h include/ArRobotBatteryPacketReader.h \ + include/ariaInternal.h include/ArStringInfoGroup.h include/ArLaser.h \ + include/ArRangeDeviceThreaded.h include/ArRangeDevice.h \ + include/ArFunctorASyncTask.h include/ArBatteryMTX.h include/ArRobot.h \ + include/ArRobotConnector.h include/ArSerialConnection.h \ + include/ArTcpConnection.h include/ArSonarMTX.h include/ArLCDMTX.h +obj/ArRobotBatteryPacketReader.o: src/ArRobotBatteryPacketReader.cpp \ + include/ariaOSDef.h include/ArExport.h \ + include/ArRobotBatteryPacketReader.h include/ariaTypedefs.h \ + include/ariaUtil.h include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ariaOSDef.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArRobot.h \ + include/ArRobotPacketSender.h include/ArRobotPacket.h \ + include/ArBasePacket.h include/ArRobotPacketReceiver.h \ + include/ArSyncTask.h include/ArTaskState.h include/ArSensorReading.h \ + include/ArTransform.h include/ArCondition.h include/ArSyncLoop.h \ + include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArRobotParams.h \ + include/ArConfig.h include/ArConfigArg.h include/ArFileParser.h \ + include/ArHasFileName.h include/ArActionDesired.h include/ArResolver.h \ + include/ArInterpolation.h include/ArKeyHandler.h include/ArRobotPacket.h \ + include/ArCommands.h +obj/ArRobotConfig.o: src/ArRobotConfig.cpp include/ariaOSDef.h \ + include/ArExport.h include/ArConfig.h include/ArConfigArg.h \ + include/ariaTypedefs.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ariaOSDef.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArRobotConfig.h \ + include/ArRobot.h include/ArRobotPacketSender.h include/ArRobotPacket.h \ + include/ArBasePacket.h include/ArRobotPacketReceiver.h \ + include/ArSyncTask.h include/ArTaskState.h include/ArSensorReading.h \ + include/ArTransform.h include/ArCondition.h include/ArSyncLoop.h \ + include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArRobotParams.h \ + include/ArConfig.h include/ArActionDesired.h include/ArResolver.h \ + include/ArInterpolation.h include/ArKeyHandler.h include/ArAnalogGyro.h \ + include/ariaInternal.h include/ArStringInfoGroup.h +obj/ArRobotConfigPacketReader.o: src/ArRobotConfigPacketReader.cpp \ + include/ariaOSDef.h include/ArExport.h \ + include/ArRobotConfigPacketReader.h include/ariaTypedefs.h \ + include/ariaUtil.h include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ariaOSDef.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArRobotPacket.h \ + include/ArBasePacket.h include/ArRobot.h include/ArRobotPacketSender.h \ + include/ArRobotPacketReceiver.h include/ArSyncTask.h \ + include/ArTaskState.h include/ArSensorReading.h include/ArTransform.h \ + include/ArCondition.h include/ArSyncLoop.h include/ArASyncTask.h \ + include/ArThread.h include/ArRobotPacketReaderThread.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArRobotPacket.h include/ArCommands.h +obj/ArRobotConnector.o: src/ArRobotConnector.cpp include/ArExport.h \ + include/ariaOSDef.h include/ArRobotConnector.h include/ariaTypedefs.h \ + include/ArSerialConnection.h include/ArDeviceConnection.h \ + include/ariaUtil.h include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ariaOSDef.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArRobot.h \ + include/ArRobotPacketSender.h include/ArRobotPacket.h \ + include/ArRobotPacketReceiver.h include/ArSyncTask.h \ + include/ArTaskState.h include/ArSensorReading.h include/ArTransform.h \ + include/ArCondition.h include/ArSyncLoop.h include/ArASyncTask.h \ + include/ArThread.h include/ArRobotPacketReaderThread.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ariaInternal.h \ + include/ArStringInfoGroup.h +obj/ArRobotJoyHandler.o: src/ArRobotJoyHandler.cpp include/ArExport.h \ + include/ariaOSDef.h include/ArRobotJoyHandler.h include/ariaTypedefs.h \ + include/ariaUtil.h include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ariaOSDef.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArRobot.h \ + include/ArRobotPacketSender.h include/ArRobotPacket.h \ + include/ArBasePacket.h include/ArRobotPacketReceiver.h \ + include/ArSyncTask.h include/ArTaskState.h include/ArSensorReading.h \ + include/ArTransform.h include/ArCondition.h include/ArSyncLoop.h \ + include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArRobotParams.h \ + include/ArConfig.h include/ArConfigArg.h include/ArFileParser.h \ + include/ArHasFileName.h include/ArActionDesired.h include/ArResolver.h \ + include/ArInterpolation.h include/ArKeyHandler.h include/ArCommands.h +obj/ArRobotPacket.o: src/ArRobotPacket.cpp include/ArExport.h \ + include/ariaOSDef.h include/ArRobotPacket.h include/ariaTypedefs.h \ + include/ArBasePacket.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ariaOSDef.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h +obj/ArRobotPacketReaderThread.o: src/ArRobotPacketReaderThread.cpp \ + include/ArExport.h include/ariaOSDef.h \ + include/ArRobotPacketReaderThread.h include/ariaTypedefs.h \ + include/ArASyncTask.h include/ArFunctor.h include/ariaOSDef.h \ + include/ArThread.h include/ArMutex.h include/ArLog.h include/ArLog.h \ + include/ariaUtil.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArRobot.h \ + include/ArRobotPacketSender.h include/ArRobotPacket.h \ + include/ArBasePacket.h include/ariaUtil.h \ + include/ArRobotPacketReceiver.h include/ArSyncTask.h \ + include/ArTaskState.h include/ArSensorReading.h include/ArTransform.h \ + include/ArCondition.h include/ArSyncLoop.h \ + include/ArRobotPacketReaderThread.h include/ArRobotParams.h \ + include/ArConfig.h include/ArConfigArg.h include/ArFileParser.h \ + include/ArHasFileName.h include/ArActionDesired.h include/ArResolver.h \ + include/ArInterpolation.h include/ArKeyHandler.h +obj/ArRobotPacketReceiver.o: src/ArRobotPacketReceiver.cpp include/ArExport.h \ + include/ariaOSDef.h include/ArDeviceConnection.h include/ariaTypedefs.h \ + include/ariaUtil.h include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ariaOSDef.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArRobotPacketReceiver.h include/ArRobotPacket.h \ + include/ArLogFileConnection.h include/ArDeviceConnection.h \ + include/ArLog.h include/ariaUtil.h +obj/ArRobotPacketSender.o: src/ArRobotPacketSender.cpp include/ArExport.h \ + include/ariaOSDef.h include/ArDeviceConnection.h include/ariaTypedefs.h \ + include/ariaUtil.h include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ariaOSDef.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacket.h +obj/ArRobotParams.o: src/ArRobotParams.cpp include/ArExport.h \ + include/ariaOSDef.h include/ArRobotParams.h include/ariaTypedefs.h \ + include/ArConfig.h include/ArConfigArg.h include/ariaUtil.h \ + include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ariaOSDef.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArFileParser.h \ + include/ArHasFileName.h include/ariaInternal.h \ + include/ArStringInfoGroup.h +obj/ArRobotTypes.o: src/ArRobotTypes.cpp include/ArExport.h \ + include/ariaOSDef.h include/ArRobotTypes.h include/ariaUtil.h \ + include/ariaTypedefs.h include/ArLog.h include/ArMutex.h \ + include/ArFunctor.h include/ariaOSDef.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArRobotParams.h include/ArConfig.h \ + include/ArConfigArg.h include/ArFileParser.h include/ArHasFileName.h \ + include/ArLog.h +obj/ArS3Series.o: src/ArS3Series.cpp include/ArExport.h include/ariaOSDef.h \ + include/ArS3Series.h include/ariaTypedefs.h include/ariaOSDef.h \ + include/ArRobotPacket.h include/ArBasePacket.h include/ariaUtil.h \ + include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h include/ArLaser.h \ + include/ArRangeDeviceThreaded.h include/ArRangeDevice.h \ + include/ArRangeBuffer.h include/ArTransform.h include/ArSensorReading.h \ + include/ArDrawingData.h include/ArFunctorASyncTask.h \ + include/ArASyncTask.h include/ArThread.h include/ArRobot.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArSyncTask.h include/ArTaskState.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArRobotPacketReaderThread.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArSerialConnection.h include/ArDeviceConnection.h \ + include/ariaInternal.h include/ArStringInfoGroup.h +obj/ArSZSeries.o: src/ArSZSeries.cpp include/ArExport.h include/ariaOSDef.h \ + include/ArSZSeries.h include/ariaTypedefs.h include/ariaOSDef.h \ + include/ArRobotPacket.h include/ArBasePacket.h include/ariaUtil.h \ + include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h include/ArLaser.h \ + include/ArRangeDeviceThreaded.h include/ArRangeDevice.h \ + include/ArRangeBuffer.h include/ArTransform.h include/ArSensorReading.h \ + include/ArDrawingData.h include/ArFunctorASyncTask.h \ + include/ArASyncTask.h include/ArThread.h include/ArRobot.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArSyncTask.h include/ArTaskState.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArRobotPacketReaderThread.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArSerialConnection.h include/ArDeviceConnection.h \ + include/ariaInternal.h include/ArStringInfoGroup.h +obj/ArSensorReading.o: src/ArSensorReading.cpp include/ArExport.h \ + include/ariaOSDef.h include/ArSensorReading.h include/ariaTypedefs.h \ + include/ariaUtil.h include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ariaOSDef.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArTransform.h include/ariaUtil.h +obj/ArSerialConnection_LIN.o: src/ArSerialConnection_LIN.cpp \ + include/ArExport.h include/ariaOSDef.h include/ArSerialConnection.h \ + include/ariaTypedefs.h include/ArDeviceConnection.h include/ariaUtil.h \ + include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ariaOSDef.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h include/ArLog.h \ + include/ariaUtil.h +obj/ArSerialConnection_WIN.o: src/ArSerialConnection_WIN.cpp \ + include/ArExport.h include/ariaOSDef.h include/ArSerialConnection.h \ + include/ariaTypedefs.h include/ArDeviceConnection.h include/ariaUtil.h \ + include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ariaOSDef.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h include/ArLog.h \ + include/ariaUtil.h +obj/ArSick.o: src/ArSick.cpp include/ArExport.h include/ariaOSDef.h \ + include/ArSick.h include/ariaTypedefs.h include/ArRobotPacket.h \ + include/ArBasePacket.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ariaOSDef.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h include/ArLaser.h \ + include/ArRangeDeviceThreaded.h include/ArRangeDevice.h \ + include/ArRangeBuffer.h include/ArTransform.h include/ArSensorReading.h \ + include/ArDrawingData.h include/ArFunctorASyncTask.h \ + include/ArASyncTask.h include/ArThread.h include/ArCondition.h \ + include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArDeviceConnection.h \ + include/ArRobot.h include/ArRobotPacketSender.h \ + include/ArRobotPacketReceiver.h include/ArSyncTask.h \ + include/ArTaskState.h include/ArSyncLoop.h \ + include/ArRobotPacketReaderThread.h include/ArRobotParams.h \ + include/ArConfig.h include/ArConfigArg.h include/ArFileParser.h \ + include/ArHasFileName.h include/ArActionDesired.h include/ArResolver.h \ + include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArSerialConnection.h include/ariaInternal.h \ + include/ArStringInfoGroup.h +obj/ArSignalHandler_LIN.o: src/ArSignalHandler_LIN.cpp include/ArExport.h \ + include/ArSignalHandler.h include/ariaTypedefs.h include/ArASyncTask.h \ + include/ArFunctor.h include/ariaOSDef.h include/ArThread.h \ + include/ArMutex.h include/ArLog.h include/ArLog.h include/ariaInternal.h \ + include/ArConfig.h include/ArConfigArg.h include/ariaUtil.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArFileParser.h include/ArHasFileName.h \ + include/ArStringInfoGroup.h +obj/ArSignalHandler_WIN.o: src/ArSignalHandler_WIN.cpp include/ArExport.h \ + include/ariaOSDef.h include/ArSignalHandler.h include/ariaTypedefs.h \ + include/ArASyncTask.h include/ArFunctor.h include/ariaOSDef.h \ + include/ArThread.h include/ArMutex.h include/ArLog.h include/ArLog.h +obj/ArSimpleConnector.o: src/ArSimpleConnector.cpp include/ArExport.h \ + include/ariaOSDef.h include/ArSimpleConnector.h include/ariaTypedefs.h \ + include/ArSerialConnection.h include/ArDeviceConnection.h \ + include/ariaUtil.h include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ariaOSDef.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArRobotConnector.h \ + include/ArLaserConnector.h include/ArRobot.h \ + include/ArRobotPacketSender.h include/ArRobotPacket.h \ + include/ArRobotPacketReceiver.h include/ArSyncTask.h \ + include/ArTaskState.h include/ArSensorReading.h include/ArTransform.h \ + include/ArCondition.h include/ArSyncLoop.h include/ArASyncTask.h \ + include/ArThread.h include/ArRobotPacketReaderThread.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArFunctorASyncTask.h include/ArSick.h include/ArLaser.h \ + include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ariaInternal.h \ + include/ArStringInfoGroup.h +obj/ArSimulatedLaser.o: src/ArSimulatedLaser.cpp include/ArExport.h \ + include/ariaOSDef.h include/ArSimulatedLaser.h include/ariaTypedefs.h \ + include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ariaUtil.h \ + include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ariaOSDef.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArTransform.h \ + include/ArSensorReading.h include/ArDrawingData.h \ + include/ArFunctorASyncTask.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobot.h include/ArRobotPacketSender.h include/ArRobotPacket.h \ + include/ArBasePacket.h include/ArRobotPacketReceiver.h \ + include/ArSyncTask.h include/ArTaskState.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArRobotPacketReaderThread.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h +obj/ArSocket.o: src/ArSocket.cpp include/ArExport.h include/ariaOSDef.h \ + include/ArSocket.h include/ariaTypedefs.h include/ArMutex.h \ + include/ariaUtil.h include/ArLog.h include/ArFunctor.h \ + include/ariaOSDef.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArLog.h +obj/ArSocket_LIN.o: src/ArSocket_LIN.cpp include/ArExport.h \ + include/ariaOSDef.h include/ArSocket.h include/ariaTypedefs.h \ + include/ArMutex.h include/ariaUtil.h include/ArLog.h include/ArFunctor.h \ + include/ariaOSDef.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArLog.h include/ArFunctor.h +obj/ArSocket_WIN.o: src/ArSocket_WIN.cpp include/ArExport.h \ + include/ariaOSDef.h include/ArSocket.h include/ariaTypedefs.h \ + include/ArMutex.h include/ariaUtil.h include/ArLog.h include/ArFunctor.h \ + include/ariaOSDef.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArLog.h include/ArFunctor.h +obj/ArSonarAutoDisabler.o: src/ArSonarAutoDisabler.cpp include/ariaOSDef.h \ + include/ArCommands.h include/ArExport.h include/ArSonarAutoDisabler.h \ + include/ariaTypedefs.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ariaOSDef.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h include/ArRobot.h \ + include/ArRobotPacketSender.h include/ArRobotPacket.h \ + include/ArBasePacket.h include/ArRobotPacketReceiver.h \ + include/ArSyncTask.h include/ArTaskState.h include/ArSensorReading.h \ + include/ArTransform.h include/ArCondition.h include/ArSyncLoop.h \ + include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArRobotParams.h \ + include/ArConfig.h include/ArConfigArg.h include/ArFileParser.h \ + include/ArHasFileName.h include/ArActionDesired.h include/ArResolver.h \ + include/ArInterpolation.h include/ArKeyHandler.h +obj/ArSonarConnector.o: src/ArSonarConnector.cpp include/ArExport.h \ + include/ariaOSDef.h include/ArSonarConnector.h include/ariaTypedefs.h \ + include/ArSerialConnection.h include/ArDeviceConnection.h \ + include/ariaUtil.h include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ariaOSDef.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArRobotConnector.h \ + include/ArRobot.h include/ArRobotPacketSender.h include/ArRobotPacket.h \ + include/ArRobotPacketReceiver.h include/ArSyncTask.h \ + include/ArTaskState.h include/ArSensorReading.h include/ArTransform.h \ + include/ArCondition.h include/ArSyncLoop.h include/ArASyncTask.h \ + include/ArThread.h include/ArRobotPacketReaderThread.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArSonarMTX.h include/ArRangeDevice.h include/ArRangeBuffer.h \ + include/ArDrawingData.h include/ArRobot.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArCommands.h \ + include/ArRobotConfigPacketReader.h +obj/ArSonarDevice.o: src/ArSonarDevice.cpp include/ArExport.h \ + include/ariaOSDef.h include/ArSonarDevice.h include/ariaTypedefs.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ariaUtil.h \ + include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ariaOSDef.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArTransform.h \ + include/ArSensorReading.h include/ArDrawingData.h include/ArRobot.h \ + include/ArRobotPacketSender.h include/ArRobotPacket.h \ + include/ArBasePacket.h include/ArRobotPacketReceiver.h \ + include/ArSyncTask.h include/ArTaskState.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArRobotParams.h \ + include/ArConfig.h include/ArConfigArg.h include/ArFileParser.h \ + include/ArHasFileName.h include/ArActionDesired.h include/ArResolver.h \ + include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArSensorReading.h include/ArRobot.h +obj/ArSonarMTX.o: src/ArSonarMTX.cpp include/ArExport.h include/ariaOSDef.h \ + include/ArSonarMTX.h include/ariaTypedefs.h include/ArRangeDevice.h \ + include/ArRangeBuffer.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ariaOSDef.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArTransform.h include/ArSensorReading.h include/ArDrawingData.h \ + include/ArRobot.h include/ArRobotPacketSender.h include/ArRobotPacket.h \ + include/ArBasePacket.h include/ArRobotPacketReceiver.h \ + include/ArSyncTask.h include/ArTaskState.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArRobotParams.h \ + include/ArConfig.h include/ArConfigArg.h include/ArFileParser.h \ + include/ArHasFileName.h include/ArActionDesired.h include/ArResolver.h \ + include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArSensorReading.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaInternal.h \ + include/ArStringInfoGroup.h +obj/ArSonyPTZ.o: src/ArSonyPTZ.cpp include/ArExport.h include/ariaOSDef.h \ + include/ArSonyPTZ.h include/ariaTypedefs.h include/ArBasePacket.h \ + include/ArPTZ.h include/ArFunctor.h include/ariaOSDef.h \ + include/ArCommands.h include/ArPTZConnector.h include/ariaUtil.h \ + include/ArLog.h include/ArMutex.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArRobotParams.h include/ArConfig.h \ + include/ArConfigArg.h include/ArFileParser.h include/ArHasFileName.h \ + include/ariaInternal.h include/ArStringInfoGroup.h include/ArRobot.h \ + include/ArRobotPacketSender.h include/ArRobotPacket.h \ + include/ArRobotPacketReceiver.h include/ArSyncTask.h \ + include/ArTaskState.h include/ArSensorReading.h include/ArTransform.h \ + include/ArCondition.h include/ArSyncLoop.h include/ArASyncTask.h \ + include/ArThread.h include/ArRobotPacketReaderThread.h \ + include/ArActionDesired.h include/ArResolver.h include/ArInterpolation.h \ + include/ArKeyHandler.h include/ArCommands.h +obj/ArSoundPlayer.o: src/ArSoundPlayer.cpp include/ArExport.h \ + include/ArSoundPlayer.h include/ArFunctor.h include/ariaTypedefs.h \ + include/ariaOSDef.h include/ArLog.h include/ArMutex.h include/ariaUtil.h \ + include/ArLog.h include/ArArgumentParser.h include/ArArgumentBuilder.h +obj/ArSoundsQueue.o: src/ArSoundsQueue.cpp include/ArExport.h include/ArLog.h \ + include/ariaTypedefs.h include/ArMutex.h include/ArFunctor.h \ + include/ariaOSDef.h include/ariaUtil.h include/ArLog.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArSoundsQueue.h include/ArASyncTask.h include/ArThread.h \ + include/ArCondition.h include/ArSpeech.h include/ArConfig.h \ + include/ArConfigArg.h include/ariaUtil.h include/ArFileParser.h \ + include/ArHasFileName.h include/ArSoundPlayer.h +obj/ArSpeech.o: src/ArSpeech.cpp include/ArExport.h include/ArSpeech.h \ + include/ariaTypedefs.h include/ArFunctor.h include/ariaOSDef.h \ + include/ArConfig.h include/ArConfigArg.h include/ariaUtil.h \ + include/ArLog.h include/ArMutex.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArFileParser.h \ + include/ArHasFileName.h include/ArConfig.h include/ariaInternal.h \ + include/ArStringInfoGroup.h +obj/ArStringInfoGroup.o: src/ArStringInfoGroup.cpp include/ArExport.h \ + include/ariaOSDef.h include/ArStringInfoGroup.h include/ariaUtil.h \ + include/ariaTypedefs.h include/ArLog.h include/ArMutex.h \ + include/ArFunctor.h include/ariaOSDef.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h +obj/ArSyncLoop.o: src/ArSyncLoop.cpp include/ArExport.h include/ariaOSDef.h \ + include/ArSyncLoop.h include/ariaTypedefs.h include/ArASyncTask.h \ + include/ArFunctor.h include/ariaOSDef.h include/ArThread.h \ + include/ArMutex.h include/ArLog.h include/ArSyncTask.h \ + include/ArTaskState.h include/ArLog.h include/ariaUtil.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h include/ArRobot.h \ + include/ArRobotPacketSender.h include/ArRobotPacket.h \ + include/ArBasePacket.h include/ariaUtil.h \ + include/ArRobotPacketReceiver.h include/ArSensorReading.h \ + include/ArTransform.h include/ArCondition.h include/ArSyncLoop.h \ + include/ArRobotPacketReaderThread.h include/ArRobotParams.h \ + include/ArConfig.h include/ArConfigArg.h include/ArFileParser.h \ + include/ArHasFileName.h include/ArActionDesired.h include/ArResolver.h \ + include/ArInterpolation.h include/ArKeyHandler.h +obj/ArSyncTask.o: src/ArSyncTask.cpp include/ArExport.h include/ariaOSDef.h \ + include/ariaUtil.h include/ariaTypedefs.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ariaOSDef.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArSyncTask.h include/ArTaskState.h include/ArLog.h +obj/ArSystemStatus.o: src/ArSystemStatus.cpp include/ArExport.h \ + include/ariaInternal.h include/ArMutex.h include/ariaTypedefs.h \ + include/ArFunctor.h include/ariaOSDef.h include/ArConfig.h \ + include/ArConfigArg.h include/ariaUtil.h include/ArLog.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArFileParser.h include/ArHasFileName.h \ + include/ArStringInfoGroup.h include/ariaOSDef.h include/ariaUtil.h \ + include/ArSystemStatus.h include/ArASyncTask.h include/ArThread.h +obj/ArTCM2.o: src/ArTCM2.cpp include/ArExport.h include/ariaOSDef.h \ + include/ariaInternal.h include/ArMutex.h include/ariaTypedefs.h \ + include/ArFunctor.h include/ariaOSDef.h include/ArConfig.h \ + include/ArConfigArg.h include/ariaUtil.h include/ArLog.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArFileParser.h include/ArHasFileName.h \ + include/ArStringInfoGroup.h include/ariaUtil.h include/ArTCM2.h \ + include/ArRobot.h include/ArRobotPacketSender.h include/ArRobotPacket.h \ + include/ArBasePacket.h include/ArRobotPacketReceiver.h \ + include/ArSyncTask.h include/ArTaskState.h include/ArSensorReading.h \ + include/ArTransform.h include/ArCondition.h include/ArSyncLoop.h \ + include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArRobotParams.h \ + include/ArActionDesired.h include/ArResolver.h include/ArInterpolation.h \ + include/ArKeyHandler.h include/ArTCMCompassDirect.h \ + include/ArDeviceConnection.h include/ArTCM2.h include/ArNMEAParser.h \ + include/ArTCMCompassRobot.h include/ArCommands.h +obj/ArTCMCompassDirect.o: src/ArTCMCompassDirect.cpp include/ArExport.h \ + include/ariaOSDef.h include/ArTCMCompassDirect.h include/ariaTypedefs.h \ + include/ariaUtil.h include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ariaOSDef.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArDeviceConnection.h \ + include/ArBasePacket.h include/ArTCM2.h include/ArRobot.h \ + include/ArRobotPacketSender.h include/ArRobotPacket.h \ + include/ArRobotPacketReceiver.h include/ArSyncTask.h \ + include/ArTaskState.h include/ArSensorReading.h include/ArTransform.h \ + include/ArCondition.h include/ArSyncLoop.h include/ArASyncTask.h \ + include/ArThread.h include/ArRobotPacketReaderThread.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArNMEAParser.h include/ArDeviceConnection.h \ + include/ArSerialConnection.h include/ariaUtil.h +obj/ArTCMCompassRobot.o: src/ArTCMCompassRobot.cpp include/ariaOSDef.h \ + include/ArExport.h include/ArCommands.h include/ArRobot.h \ + include/ariaTypedefs.h include/ArRobotPacketSender.h \ + include/ArRobotPacket.h include/ArBasePacket.h include/ariaUtil.h \ + include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ariaOSDef.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArRobotPacketReceiver.h \ + include/ArSyncTask.h include/ArTaskState.h include/ArSensorReading.h \ + include/ArTransform.h include/ArCondition.h include/ArSyncLoop.h \ + include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArRobotParams.h \ + include/ArConfig.h include/ArConfigArg.h include/ArFileParser.h \ + include/ArHasFileName.h include/ArActionDesired.h include/ArResolver.h \ + include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArTCMCompassRobot.h include/ArCommands.h include/ArRobot.h \ + include/ArTCM2.h +obj/ArTcpConnection.o: src/ArTcpConnection.cpp include/ArExport.h \ + include/ariaOSDef.h include/ArTcpConnection.h \ + include/ArDeviceConnection.h include/ariaTypedefs.h include/ariaUtil.h \ + include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ariaOSDef.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h include/ArSocket.h \ + include/ArLog.h include/ariaUtil.h +obj/ArThread.o: src/ArThread.cpp include/ArExport.h include/ariaOSDef.h \ + include/ArThread.h include/ariaTypedefs.h include/ArMutex.h \ + include/ArFunctor.h include/ariaOSDef.h include/ArLog.h include/ArLog.h +obj/ArThread_LIN.o: src/ArThread_LIN.cpp include/ArExport.h \ + include/ariaOSDef.h include/ArThread.h include/ariaTypedefs.h \ + include/ArMutex.h include/ArFunctor.h include/ariaOSDef.h \ + include/ArLog.h include/ArLog.h include/ArSignalHandler.h \ + include/ArASyncTask.h include/ArThread.h +obj/ArThread_WIN.o: src/ArThread_WIN.cpp include/ArExport.h \ + include/ariaOSDef.h include/ArThread.h include/ariaTypedefs.h \ + include/ArMutex.h include/ArFunctor.h include/ariaOSDef.h \ + include/ArLog.h include/ArLog.h include/ArSignalHandler.h \ + include/ArASyncTask.h include/ArThread.h include/ariaUtil.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h +obj/ArTransform.o: src/ArTransform.cpp include/ArExport.h include/ariaOSDef.h \ + include/ArTransform.h include/ariaTypedefs.h include/ariaUtil.h \ + include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ariaOSDef.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h +obj/ArTrimbleGPS.o: src/ArTrimbleGPS.cpp include/ArExport.h \ + include/ariaOSDef.h include/ArTrimbleGPS.h include/ariaTypedefs.h \ + include/ArFunctor.h include/ariaOSDef.h include/ariaUtil.h \ + include/ArLog.h include/ArMutex.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArGPS.h include/ArNMEAParser.h \ + include/ArDeviceConnection.h include/ArBasePacket.h \ + include/ArDeviceConnection.h +obj/ArUrg.o: src/ArUrg.cpp include/ArExport.h include/ariaOSDef.h \ + include/ArUrg.h include/ariaTypedefs.h include/ArLaser.h \ + include/ArRangeDeviceThreaded.h include/ArRangeDevice.h \ + include/ArRangeBuffer.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ariaOSDef.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArTransform.h include/ArSensorReading.h include/ArDrawingData.h \ + include/ArFunctorASyncTask.h include/ArASyncTask.h include/ArThread.h \ + include/ArDeviceConnection.h include/ArBasePacket.h include/ArRobot.h \ + include/ArRobotPacketSender.h include/ArRobotPacket.h \ + include/ArRobotPacketReceiver.h include/ArSyncTask.h \ + include/ArTaskState.h include/ArCondition.h include/ArSyncLoop.h \ + include/ArRobotPacketReaderThread.h include/ArRobotParams.h \ + include/ArConfig.h include/ArConfigArg.h include/ArFileParser.h \ + include/ArHasFileName.h include/ArActionDesired.h include/ArResolver.h \ + include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArSerialConnection.h include/ariaInternal.h \ + include/ArStringInfoGroup.h +obj/ArUrg_2_0.o: src/ArUrg_2_0.cpp include/ArExport.h include/ariaOSDef.h \ + include/ArUrg_2_0.h include/ariaTypedefs.h include/ArLaser.h \ + include/ArRangeDeviceThreaded.h include/ArRangeDevice.h \ + include/ArRangeBuffer.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ariaOSDef.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArTransform.h include/ArSensorReading.h include/ArDrawingData.h \ + include/ArFunctorASyncTask.h include/ArASyncTask.h include/ArThread.h \ + include/ArDeviceConnection.h include/ArBasePacket.h include/ArRobot.h \ + include/ArRobotPacketSender.h include/ArRobotPacket.h \ + include/ArRobotPacketReceiver.h include/ArSyncTask.h \ + include/ArTaskState.h include/ArCondition.h include/ArSyncLoop.h \ + include/ArRobotPacketReaderThread.h include/ArRobotParams.h \ + include/ArConfig.h include/ArConfigArg.h include/ArFileParser.h \ + include/ArHasFileName.h include/ArActionDesired.h include/ArResolver.h \ + include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArSerialConnection.h include/ariaInternal.h \ + include/ArStringInfoGroup.h +obj/ArVCC4.o: src/ArVCC4.cpp include/ArExport.h include/ariaOSDef.h \ + include/ArVCC4.h include/ariaTypedefs.h include/ArBasePacket.h \ + include/ArPTZ.h include/ArFunctor.h include/ariaOSDef.h \ + include/ArCommands.h include/ArPTZConnector.h include/ariaUtil.h \ + include/ArLog.h include/ArMutex.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArRobotParams.h include/ArConfig.h \ + include/ArConfigArg.h include/ArFileParser.h include/ArHasFileName.h \ + include/ariaInternal.h include/ArStringInfoGroup.h \ + include/ArSerialConnection.h include/ArDeviceConnection.h \ + include/ArCommands.h include/ArRobot.h include/ArRobotPacketSender.h \ + include/ArRobotPacket.h include/ArRobotPacketReceiver.h \ + include/ArSyncTask.h include/ArTaskState.h include/ArSensorReading.h \ + include/ArTransform.h include/ArCondition.h include/ArSyncLoop.h \ + include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h +obj/ArVersalogicIO.o: src/ArVersalogicIO.cpp include/ArExport.h \ + include/ariaOSDef.h include/ArVersalogicIO.h include/ariaTypedefs.h \ + include/ArRobot.h include/ArRobotPacketSender.h include/ArRobotPacket.h \ + include/ArBasePacket.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ariaOSDef.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArRobotPacketReceiver.h include/ArSyncTask.h \ + include/ArTaskState.h include/ArSensorReading.h include/ArTransform.h \ + include/ArCondition.h include/ArSyncLoop.h include/ArASyncTask.h \ + include/ArThread.h include/ArRobotPacketReaderThread.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ariaInternal.h include/ArStringInfoGroup.h +obj/Aria.o: src/Aria.cpp include/ArExport.h include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h include/ArSocket.h \ + include/ArSignalHandler.h include/ArKeyHandler.h include/ArJoyHandler.h \ + include/ArModuleLoader.h include/ArRobotJoyHandler.h \ + include/ArSystemStatus.h include/ArPTZConnector.h include/ArRVisionPTZ.h \ + include/ArVCC4.h include/ArDPPTU.h include/ArSonyPTZ.h +obj/ariaUtil.o: src/ariaUtil.cpp include/ArExport.h include/ariaOSDef.h \ + include/ariaInternal.h include/ArMutex.h include/ariaTypedefs.h \ + include/ArFunctor.h include/ariaOSDef.h include/ArConfig.h \ + include/ArConfigArg.h include/ariaUtil.h include/ArLog.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArFileParser.h include/ArHasFileName.h \ + include/ArStringInfoGroup.h include/ariaTypedefs.h include/ariaUtil.h \ + include/ArSick.h include/ArRobotPacket.h include/ArBasePacket.h \ + include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArTransform.h \ + include/ArSensorReading.h include/ArDrawingData.h \ + include/ArFunctorASyncTask.h include/ArASyncTask.h include/ArThread.h \ + include/ArCondition.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArDeviceConnection.h \ + include/ArUrg.h include/ArLMS1XX.h include/ArS3Series.h \ + include/ArUrg_2_0.h include/ArSZSeries.h include/ArSonarMTX.h \ + include/ArRobot.h include/ArRobotPacketSender.h \ + include/ArRobotPacketReceiver.h include/ArSyncTask.h \ + include/ArTaskState.h include/ArSyncLoop.h \ + include/ArRobotPacketReaderThread.h include/ArRobotParams.h \ + include/ArActionDesired.h include/ArResolver.h include/ArInterpolation.h \ + include/ArKeyHandler.h include/ArBatteryMTX.h include/ArRobotConnector.h \ + include/ArSerialConnection.h include/ArTcpConnection.h \ + include/ArSocket.h include/ArLCDMTX.h include/ArSerialConnection.h \ + include/ArTcpConnection.h +obj/md5.o: src/md5.cpp include/ArExport.h include/md5.h +obj/proprietaryArGnuplot.o: src/proprietaryArGnuplot.cpp \ + include/proprietaryArGnuplot.h include/ariaUtil.h include/ariaTypedefs.h \ + include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ariaOSDef.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArExport.h include/ariaOSDef.h +examples/actionExample: examples/actionExample.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +examples/actionGroupExample: examples/actionGroupExample.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +examples/actsColorFollowingExample: examples/actsColorFollowingExample.cpp \ + include/Aria.h include/ariaOSDef.h include/ariaTypedefs.h \ + include/ArSerialConnection.h include/ArDeviceConnection.h \ + include/ariaUtil.h include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArBasePacket.h include/ArTcpConnection.h include/ArSocket.h \ + include/ArSimpleConnector.h include/ArRobotConnector.h \ + include/ArLaserConnector.h include/ArLogFileConnection.h \ + include/ArRobotPacket.h include/ArRobotPacketSender.h \ + include/ArRobotPacketReceiver.h include/ArRobotConfigPacketReader.h \ + include/ArRobotTypes.h include/ArRobotParams.h include/ArConfig.h \ + include/ArConfigArg.h include/ArFileParser.h include/ArHasFileName.h \ + include/ArConfigGroup.h include/ArRobot.h include/ArSyncTask.h \ + include/ArTaskState.h include/ArSensorReading.h include/ArTransform.h \ + include/ArCondition.h include/ArSyncLoop.h include/ArASyncTask.h \ + include/ArThread.h include/ArRobotPacketReaderThread.h \ + include/ArActionDesired.h include/ArResolver.h include/ArInterpolation.h \ + include/ArKeyHandler.h include/ArCommands.h include/ArJoyHandler.h \ + include/ariaInternal.h include/ArStringInfoGroup.h \ + include/ArSonarDevice.h include/ArRangeDevice.h include/ArRangeBuffer.h \ + include/ArDrawingData.h include/ArPriorityResolver.h include/ArAction.h \ + include/ArArg.h include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +examples/armExample: examples/armExample.cpp include/Aria.h include/ariaOSDef.h \ + include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +examples/auxSerialExample: examples/auxSerialExample.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +examples/cameraPTZExample: examples/cameraPTZExample.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +examples/configExample: examples/configExample.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +examples/demo: examples/demo.cpp include/Aria.h include/ariaOSDef.h \ + include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +examples/directMotionExample: examples/directMotionExample.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +examples/dpptuExample: examples/dpptuExample.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +examples/functorExample: examples/functorExample.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +examples/gotoActionExample: examples/gotoActionExample.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +examples/gpsExample: examples/gpsExample.cpp include/Aria.h include/ariaOSDef.h \ + include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h include/ArGPS.h \ + include/ArGPSConnector.h include/ArTrimbleGPS.h \ + include/ArTCMCompassDirect.h +examples/gpsRobotTaskExample: examples/gpsRobotTaskExample.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h include/ArGPS.h \ + include/ArGPSConnector.h +examples/gripperExample: examples/gripperExample.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +examples/gyroExample: examples/gyroExample.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h include/ArAnalogGyro.h +examples/imuExample: examples/imuExample.cpp include/Aria.h include/ariaOSDef.h \ + include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +examples/ipthru: examples/ipthru.cpp include/Aria.h include/ariaOSDef.h \ + include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +examples/joydriveActionExample: examples/joydriveActionExample.cpp \ + include/Aria.h include/ariaOSDef.h include/ariaTypedefs.h \ + include/ArSerialConnection.h include/ArDeviceConnection.h \ + include/ariaUtil.h include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArBasePacket.h include/ArTcpConnection.h include/ArSocket.h \ + include/ArSimpleConnector.h include/ArRobotConnector.h \ + include/ArLaserConnector.h include/ArLogFileConnection.h \ + include/ArRobotPacket.h include/ArRobotPacketSender.h \ + include/ArRobotPacketReceiver.h include/ArRobotConfigPacketReader.h \ + include/ArRobotTypes.h include/ArRobotParams.h include/ArConfig.h \ + include/ArConfigArg.h include/ArFileParser.h include/ArHasFileName.h \ + include/ArConfigGroup.h include/ArRobot.h include/ArSyncTask.h \ + include/ArTaskState.h include/ArSensorReading.h include/ArTransform.h \ + include/ArCondition.h include/ArSyncLoop.h include/ArASyncTask.h \ + include/ArThread.h include/ArRobotPacketReaderThread.h \ + include/ArActionDesired.h include/ArResolver.h include/ArInterpolation.h \ + include/ArKeyHandler.h include/ArCommands.h include/ArJoyHandler.h \ + include/ariaInternal.h include/ArStringInfoGroup.h \ + include/ArSonarDevice.h include/ArRangeDevice.h include/ArRangeBuffer.h \ + include/ArDrawingData.h include/ArPriorityResolver.h include/ArAction.h \ + include/ArArg.h include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +examples/joydriveThreaded: examples/joydriveThreaded.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +examples/joydriveUserTask: examples/joydriveUserTask.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +examples/laserConnect: examples/laserConnect.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +examples/lasers: examples/lasers.cpp include/Aria.h include/ariaOSDef.h \ + include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +examples/lineFinderExample: examples/lineFinderExample.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +examples/moduleExample: examples/moduleExample.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +examples/moduleExample_Mod: examples/moduleExample_Mod.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +examples/mtxWheelLights: examples/mtxWheelLights.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +examples/netServerExample: examples/netServerExample.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +examples/proprietaryCoreIOTest: examples/proprietaryCoreIOTest.cpp \ + include/Aria.h include/ariaOSDef.h include/ariaTypedefs.h \ + include/ArSerialConnection.h include/ArDeviceConnection.h \ + include/ariaUtil.h include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArBasePacket.h include/ArTcpConnection.h include/ArSocket.h \ + include/ArSimpleConnector.h include/ArRobotConnector.h \ + include/ArLaserConnector.h include/ArLogFileConnection.h \ + include/ArRobotPacket.h include/ArRobotPacketSender.h \ + include/ArRobotPacketReceiver.h include/ArRobotConfigPacketReader.h \ + include/ArRobotTypes.h include/ArRobotParams.h include/ArConfig.h \ + include/ArConfigArg.h include/ArFileParser.h include/ArHasFileName.h \ + include/ArConfigGroup.h include/ArRobot.h include/ArSyncTask.h \ + include/ArTaskState.h include/ArSensorReading.h include/ArTransform.h \ + include/ArCondition.h include/ArSyncLoop.h include/ArASyncTask.h \ + include/ArThread.h include/ArRobotPacketReaderThread.h \ + include/ArActionDesired.h include/ArResolver.h include/ArInterpolation.h \ + include/ArKeyHandler.h include/ArCommands.h include/ArJoyHandler.h \ + include/ariaInternal.h include/ArStringInfoGroup.h \ + include/ArSonarDevice.h include/ArRangeDevice.h include/ArRangeBuffer.h \ + include/ArDrawingData.h include/ArPriorityResolver.h include/ArAction.h \ + include/ArArg.h include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +examples/proprietaryCoreTempTesting: examples/proprietaryCoreTempTesting.cpp \ + include/Aria.h include/ariaOSDef.h include/ariaTypedefs.h \ + include/ArSerialConnection.h include/ArDeviceConnection.h \ + include/ariaUtil.h include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArBasePacket.h include/ArTcpConnection.h include/ArSocket.h \ + include/ArSimpleConnector.h include/ArRobotConnector.h \ + include/ArLaserConnector.h include/ArLogFileConnection.h \ + include/ArRobotPacket.h include/ArRobotPacketSender.h \ + include/ArRobotPacketReceiver.h include/ArRobotConfigPacketReader.h \ + include/ArRobotTypes.h include/ArRobotParams.h include/ArConfig.h \ + include/ArConfigArg.h include/ArFileParser.h include/ArHasFileName.h \ + include/ArConfigGroup.h include/ArRobot.h include/ArSyncTask.h \ + include/ArTaskState.h include/ArSensorReading.h include/ArTransform.h \ + include/ArCondition.h include/ArSyncLoop.h include/ArASyncTask.h \ + include/ArThread.h include/ArRobotPacketReaderThread.h \ + include/ArActionDesired.h include/ArResolver.h include/ArInterpolation.h \ + include/ArKeyHandler.h include/ArCommands.h include/ArJoyHandler.h \ + include/ariaInternal.h include/ArStringInfoGroup.h \ + include/ArSonarDevice.h include/ArRangeDevice.h include/ArRangeBuffer.h \ + include/ArDrawingData.h include/ArPriorityResolver.h include/ArAction.h \ + include/ArArg.h include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +examples/proprietaryDataLogger: examples/proprietaryDataLogger.cpp \ + include/Aria.h include/ariaOSDef.h include/ariaTypedefs.h \ + include/ArSerialConnection.h include/ArDeviceConnection.h \ + include/ariaUtil.h include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArBasePacket.h include/ArTcpConnection.h include/ArSocket.h \ + include/ArSimpleConnector.h include/ArRobotConnector.h \ + include/ArLaserConnector.h include/ArLogFileConnection.h \ + include/ArRobotPacket.h include/ArRobotPacketSender.h \ + include/ArRobotPacketReceiver.h include/ArRobotConfigPacketReader.h \ + include/ArRobotTypes.h include/ArRobotParams.h include/ArConfig.h \ + include/ArConfigArg.h include/ArFileParser.h include/ArHasFileName.h \ + include/ArConfigGroup.h include/ArRobot.h include/ArSyncTask.h \ + include/ArTaskState.h include/ArSensorReading.h include/ArTransform.h \ + include/ArCondition.h include/ArSyncLoop.h include/ArASyncTask.h \ + include/ArThread.h include/ArRobotPacketReaderThread.h \ + include/ArActionDesired.h include/ArResolver.h include/ArInterpolation.h \ + include/ArKeyHandler.h include/ArCommands.h include/ArJoyHandler.h \ + include/ariaInternal.h include/ArStringInfoGroup.h \ + include/ArSonarDevice.h include/ArRangeDevice.h include/ArRangeBuffer.h \ + include/ArDrawingData.h include/ArPriorityResolver.h include/ArAction.h \ + include/ArArg.h include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +examples/proprietaryDataLoggerWander: examples/proprietaryDataLoggerWander.cpp \ + include/Aria.h include/ariaOSDef.h include/ariaTypedefs.h \ + include/ArSerialConnection.h include/ArDeviceConnection.h \ + include/ariaUtil.h include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArBasePacket.h include/ArTcpConnection.h include/ArSocket.h \ + include/ArSimpleConnector.h include/ArRobotConnector.h \ + include/ArLaserConnector.h include/ArLogFileConnection.h \ + include/ArRobotPacket.h include/ArRobotPacketSender.h \ + include/ArRobotPacketReceiver.h include/ArRobotConfigPacketReader.h \ + include/ArRobotTypes.h include/ArRobotParams.h include/ArConfig.h \ + include/ArConfigArg.h include/ArFileParser.h include/ArHasFileName.h \ + include/ArConfigGroup.h include/ArRobot.h include/ArSyncTask.h \ + include/ArTaskState.h include/ArSensorReading.h include/ArTransform.h \ + include/ArCondition.h include/ArSyncLoop.h include/ArASyncTask.h \ + include/ArThread.h include/ArRobotPacketReaderThread.h \ + include/ArActionDesired.h include/ArResolver.h include/ArInterpolation.h \ + include/ArKeyHandler.h include/ArCommands.h include/ArJoyHandler.h \ + include/ariaInternal.h include/ArStringInfoGroup.h \ + include/ArSonarDevice.h include/ArRangeDevice.h include/ArRangeBuffer.h \ + include/ArDrawingData.h include/ArPriorityResolver.h include/ArAction.h \ + include/ArArg.h include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +examples/proprietaryForwarder: examples/proprietaryForwarder.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +examples/proprietaryFostTest: examples/proprietaryFostTest.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +examples/proprietaryLaserPlans: examples/proprietaryLaserPlans.cpp \ + examples/proprietaryLaserPlans.h include/Aria.h include/ariaOSDef.h \ + include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +examples/proprietaryMinkingB01Demo: examples/proprietaryMinkingB01Demo.cpp \ + include/Aria.h include/ariaOSDef.h include/ariaTypedefs.h \ + include/ArSerialConnection.h include/ArDeviceConnection.h \ + include/ariaUtil.h include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArBasePacket.h include/ArTcpConnection.h include/ArSocket.h \ + include/ArSimpleConnector.h include/ArRobotConnector.h \ + include/ArLaserConnector.h include/ArLogFileConnection.h \ + include/ArRobotPacket.h include/ArRobotPacketSender.h \ + include/ArRobotPacketReceiver.h include/ArRobotConfigPacketReader.h \ + include/ArRobotTypes.h include/ArRobotParams.h include/ArConfig.h \ + include/ArConfigArg.h include/ArFileParser.h include/ArHasFileName.h \ + include/ArConfigGroup.h include/ArRobot.h include/ArSyncTask.h \ + include/ArTaskState.h include/ArSensorReading.h include/ArTransform.h \ + include/ArCondition.h include/ArSyncLoop.h include/ArASyncTask.h \ + include/ArThread.h include/ArRobotPacketReaderThread.h \ + include/ArActionDesired.h include/ArResolver.h include/ArInterpolation.h \ + include/ArKeyHandler.h include/ArCommands.h include/ArJoyHandler.h \ + include/ariaInternal.h include/ArStringInfoGroup.h \ + include/ArSonarDevice.h include/ArRangeDevice.h include/ArRangeBuffer.h \ + include/ArDrawingData.h include/ArPriorityResolver.h include/ArAction.h \ + include/ArArg.h include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +examples/proprietaryPatrolBotButtonTest: \ + examples/proprietaryPatrolBotButtonTest.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +examples/proprietaryPatrolBotIOTest: examples/proprietaryPatrolBotIOTest.cpp \ + include/Aria.h include/ariaOSDef.h include/ariaTypedefs.h \ + include/ArSerialConnection.h include/ArDeviceConnection.h \ + include/ariaUtil.h include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArBasePacket.h include/ArTcpConnection.h include/ArSocket.h \ + include/ArSimpleConnector.h include/ArRobotConnector.h \ + include/ArLaserConnector.h include/ArLogFileConnection.h \ + include/ArRobotPacket.h include/ArRobotPacketSender.h \ + include/ArRobotPacketReceiver.h include/ArRobotConfigPacketReader.h \ + include/ArRobotTypes.h include/ArRobotParams.h include/ArConfig.h \ + include/ArConfigArg.h include/ArFileParser.h include/ArHasFileName.h \ + include/ArConfigGroup.h include/ArRobot.h include/ArSyncTask.h \ + include/ArTaskState.h include/ArSensorReading.h include/ArTransform.h \ + include/ArCondition.h include/ArSyncLoop.h include/ArASyncTask.h \ + include/ArThread.h include/ArRobotPacketReaderThread.h \ + include/ArActionDesired.h include/ArResolver.h include/ArInterpolation.h \ + include/ArKeyHandler.h include/ArCommands.h include/ArJoyHandler.h \ + include/ariaInternal.h include/ArStringInfoGroup.h \ + include/ArSonarDevice.h include/ArRangeDevice.h include/ArRangeBuffer.h \ + include/ArDrawingData.h include/ArPriorityResolver.h include/ArAction.h \ + include/ArArg.h include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +examples/proprietaryPlansTest: examples/proprietaryPlansTest.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +examples/proprietaryPolarZPAN200Test: examples/proprietaryPolarZPAN200Test.cpp \ + include/Aria.h include/ariaOSDef.h include/ariaTypedefs.h \ + include/ArSerialConnection.h include/ArDeviceConnection.h \ + include/ariaUtil.h include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArBasePacket.h include/ArTcpConnection.h include/ArSocket.h \ + include/ArSimpleConnector.h include/ArRobotConnector.h \ + include/ArLaserConnector.h include/ArLogFileConnection.h \ + include/ArRobotPacket.h include/ArRobotPacketSender.h \ + include/ArRobotPacketReceiver.h include/ArRobotConfigPacketReader.h \ + include/ArRobotTypes.h include/ArRobotParams.h include/ArConfig.h \ + include/ArConfigArg.h include/ArFileParser.h include/ArHasFileName.h \ + include/ArConfigGroup.h include/ArRobot.h include/ArSyncTask.h \ + include/ArTaskState.h include/ArSensorReading.h include/ArTransform.h \ + include/ArCondition.h include/ArSyncLoop.h include/ArASyncTask.h \ + include/ArThread.h include/ArRobotPacketReaderThread.h \ + include/ArActionDesired.h include/ArResolver.h include/ArInterpolation.h \ + include/ArKeyHandler.h include/ArCommands.h include/ArJoyHandler.h \ + include/ariaInternal.h include/ArStringInfoGroup.h \ + include/ArSonarDevice.h include/ArRangeDevice.h include/ArRangeBuffer.h \ + include/ArDrawingData.h include/ArPriorityResolver.h include/ArAction.h \ + include/ArArg.h include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +examples/proprietaryRMTServoTest: examples/proprietaryRMTServoTest.cpp \ + include/Aria.h include/ariaOSDef.h include/ariaTypedefs.h \ + include/ArSerialConnection.h include/ArDeviceConnection.h \ + include/ariaUtil.h include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArBasePacket.h include/ArTcpConnection.h include/ArSocket.h \ + include/ArSimpleConnector.h include/ArRobotConnector.h \ + include/ArLaserConnector.h include/ArLogFileConnection.h \ + include/ArRobotPacket.h include/ArRobotPacketSender.h \ + include/ArRobotPacketReceiver.h include/ArRobotConfigPacketReader.h \ + include/ArRobotTypes.h include/ArRobotParams.h include/ArConfig.h \ + include/ArConfigArg.h include/ArFileParser.h include/ArHasFileName.h \ + include/ArConfigGroup.h include/ArRobot.h include/ArSyncTask.h \ + include/ArTaskState.h include/ArSensorReading.h include/ArTransform.h \ + include/ArCondition.h include/ArSyncLoop.h include/ArASyncTask.h \ + include/ArThread.h include/ArRobotPacketReaderThread.h \ + include/ArActionDesired.h include/ArResolver.h include/ArInterpolation.h \ + include/ArKeyHandler.h include/ArCommands.h include/ArJoyHandler.h \ + include/ariaInternal.h include/ArStringInfoGroup.h \ + include/ArSonarDevice.h include/ArRangeDevice.h include/ArRangeBuffer.h \ + include/ArDrawingData.h include/ArPriorityResolver.h include/ArAction.h \ + include/ArArg.h include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +examples/proprietaryRobotLooker: examples/proprietaryRobotLooker.cpp \ + include/Aria.h include/ariaOSDef.h include/ariaTypedefs.h \ + include/ArSerialConnection.h include/ArDeviceConnection.h \ + include/ariaUtil.h include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArBasePacket.h include/ArTcpConnection.h include/ArSocket.h \ + include/ArSimpleConnector.h include/ArRobotConnector.h \ + include/ArLaserConnector.h include/ArLogFileConnection.h \ + include/ArRobotPacket.h include/ArRobotPacketSender.h \ + include/ArRobotPacketReceiver.h include/ArRobotConfigPacketReader.h \ + include/ArRobotTypes.h include/ArRobotParams.h include/ArConfig.h \ + include/ArConfigArg.h include/ArFileParser.h include/ArHasFileName.h \ + include/ArConfigGroup.h include/ArRobot.h include/ArSyncTask.h \ + include/ArTaskState.h include/ArSensorReading.h include/ArTransform.h \ + include/ArCondition.h include/ArSyncLoop.h include/ArASyncTask.h \ + include/ArThread.h include/ArRobotPacketReaderThread.h \ + include/ArActionDesired.h include/ArResolver.h include/ArInterpolation.h \ + include/ArKeyHandler.h include/ArCommands.h include/ArJoyHandler.h \ + include/ariaInternal.h include/ArStringInfoGroup.h \ + include/ArSonarDevice.h include/ArRangeDevice.h include/ArRangeBuffer.h \ + include/ArDrawingData.h include/ArPriorityResolver.h include/ArAction.h \ + include/ArArg.h include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +examples/proprietaryWheelDemo: examples/proprietaryWheelDemo.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +examples/robotConnectionCallbacks: examples/robotConnectionCallbacks.cpp \ + include/Aria.h include/ariaOSDef.h include/ariaTypedefs.h \ + include/ArSerialConnection.h include/ArDeviceConnection.h \ + include/ariaUtil.h include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArBasePacket.h include/ArTcpConnection.h include/ArSocket.h \ + include/ArSimpleConnector.h include/ArRobotConnector.h \ + include/ArLaserConnector.h include/ArLogFileConnection.h \ + include/ArRobotPacket.h include/ArRobotPacketSender.h \ + include/ArRobotPacketReceiver.h include/ArRobotConfigPacketReader.h \ + include/ArRobotTypes.h include/ArRobotParams.h include/ArConfig.h \ + include/ArConfigArg.h include/ArFileParser.h include/ArHasFileName.h \ + include/ArConfigGroup.h include/ArRobot.h include/ArSyncTask.h \ + include/ArTaskState.h include/ArSensorReading.h include/ArTransform.h \ + include/ArCondition.h include/ArSyncLoop.h include/ArASyncTask.h \ + include/ArThread.h include/ArRobotPacketReaderThread.h \ + include/ArActionDesired.h include/ArResolver.h include/ArInterpolation.h \ + include/ArKeyHandler.h include/ArCommands.h include/ArJoyHandler.h \ + include/ariaInternal.h include/ArStringInfoGroup.h \ + include/ArSonarDevice.h include/ArRangeDevice.h include/ArRangeBuffer.h \ + include/ArDrawingData.h include/ArPriorityResolver.h include/ArAction.h \ + include/ArArg.h include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +examples/robotSyncTaskExample: examples/robotSyncTaskExample.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +examples/seekurPower: examples/seekurPower.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +examples/sickLogger: examples/sickLogger.cpp include/Aria.h include/ariaOSDef.h \ + include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +examples/sickRobotExample: examples/sickRobotExample.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +examples/sickTeleop: examples/sickTeleop.cpp include/Aria.h include/ariaOSDef.h \ + include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +examples/simpleConnect: examples/simpleConnect.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +examples/simpleMotionCommands: examples/simpleMotionCommands.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +examples/socketClientExample: examples/socketClientExample.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +examples/socketServerExample: examples/socketServerExample.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +examples/soundsQueueExample: examples/soundsQueueExample.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h include/ariaTypedefs.h \ + include/ariaUtil.h include/ArSoundsQueue.h include/ArSoundPlayer.h +examples/teleopActionsExample: examples/teleopActionsExample.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +examples/threadExample: examples/threadExample.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +examples/triangleDriveToActionExample: examples/triangleDriveToActionExample.cpp \ + include/Aria.h include/ariaOSDef.h include/ariaTypedefs.h \ + include/ArSerialConnection.h include/ArDeviceConnection.h \ + include/ariaUtil.h include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArBasePacket.h include/ArTcpConnection.h include/ArSocket.h \ + include/ArSimpleConnector.h include/ArRobotConnector.h \ + include/ArLaserConnector.h include/ArLogFileConnection.h \ + include/ArRobotPacket.h include/ArRobotPacketSender.h \ + include/ArRobotPacketReceiver.h include/ArRobotConfigPacketReader.h \ + include/ArRobotTypes.h include/ArRobotParams.h include/ArConfig.h \ + include/ArConfigArg.h include/ArFileParser.h include/ArHasFileName.h \ + include/ArConfigGroup.h include/ArRobot.h include/ArSyncTask.h \ + include/ArTaskState.h include/ArSensorReading.h include/ArTransform.h \ + include/ArCondition.h include/ArSyncLoop.h include/ArASyncTask.h \ + include/ArThread.h include/ArRobotPacketReaderThread.h \ + include/ArActionDesired.h include/ArResolver.h include/ArInterpolation.h \ + include/ArKeyHandler.h include/ArCommands.h include/ArJoyHandler.h \ + include/ariaInternal.h include/ArStringInfoGroup.h \ + include/ArSonarDevice.h include/ArRangeDevice.h include/ArRangeBuffer.h \ + include/ArDrawingData.h include/ArPriorityResolver.h include/ArAction.h \ + include/ArArg.h include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +examples/twoRobotWander: examples/twoRobotWander.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +examples/wander: examples/wander.cpp include/Aria.h include/ariaOSDef.h \ + include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +examples/wanderAndLogData: examples/wanderAndLogData.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +utils/addSfWorldLinesToArMap: utils/addSfWorldLinesToArMap.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +utils/convertSfWorldToArMap: utils/convertSfWorldToArMap.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +utils/genCommandLineOptionDocs: utils/genCommandLineOptionDocs.cpp \ + include/Aria.h include/ariaOSDef.h include/ariaTypedefs.h \ + include/ArSerialConnection.h include/ArDeviceConnection.h \ + include/ariaUtil.h include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArBasePacket.h include/ArTcpConnection.h include/ArSocket.h \ + include/ArSimpleConnector.h include/ArRobotConnector.h \ + include/ArLaserConnector.h include/ArLogFileConnection.h \ + include/ArRobotPacket.h include/ArRobotPacketSender.h \ + include/ArRobotPacketReceiver.h include/ArRobotConfigPacketReader.h \ + include/ArRobotTypes.h include/ArRobotParams.h include/ArConfig.h \ + include/ArConfigArg.h include/ArFileParser.h include/ArHasFileName.h \ + include/ArConfigGroup.h include/ArRobot.h include/ArSyncTask.h \ + include/ArTaskState.h include/ArSensorReading.h include/ArTransform.h \ + include/ArCondition.h include/ArSyncLoop.h include/ArASyncTask.h \ + include/ArThread.h include/ArRobotPacketReaderThread.h \ + include/ArActionDesired.h include/ArResolver.h include/ArInterpolation.h \ + include/ArKeyHandler.h include/ArCommands.h include/ArJoyHandler.h \ + include/ariaInternal.h include/ArStringInfoGroup.h \ + include/ArSonarDevice.h include/ArRangeDevice.h include/ArRangeBuffer.h \ + include/ArDrawingData.h include/ArPriorityResolver.h include/ArAction.h \ + include/ArArg.h include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +utils/makeParams: utils/makeParams.cpp include/ariaOSDef.h include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h include/ArRobotTypes.h +tests/ArTestConfig: tests/ArTestConfig.cpp tests/ArTestConfig.h \ + include/ArConfig.h include/ArConfigArg.h include/ariaTypedefs.h \ + include/ariaUtil.h include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ariaOSDef.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArFileParser.h \ + include/ArHasFileName.h include/ArConfigArg.h +tests/absoluteHeadingActionTest: tests/absoluteHeadingActionTest.cpp \ + include/Aria.h include/ariaOSDef.h include/ariaTypedefs.h \ + include/ArSerialConnection.h include/ArDeviceConnection.h \ + include/ariaUtil.h include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArBasePacket.h include/ArTcpConnection.h include/ArSocket.h \ + include/ArSimpleConnector.h include/ArRobotConnector.h \ + include/ArLaserConnector.h include/ArLogFileConnection.h \ + include/ArRobotPacket.h include/ArRobotPacketSender.h \ + include/ArRobotPacketReceiver.h include/ArRobotConfigPacketReader.h \ + include/ArRobotTypes.h include/ArRobotParams.h include/ArConfig.h \ + include/ArConfigArg.h include/ArFileParser.h include/ArHasFileName.h \ + include/ArConfigGroup.h include/ArRobot.h include/ArSyncTask.h \ + include/ArTaskState.h include/ArSensorReading.h include/ArTransform.h \ + include/ArCondition.h include/ArSyncLoop.h include/ArASyncTask.h \ + include/ArThread.h include/ArRobotPacketReaderThread.h \ + include/ArActionDesired.h include/ArResolver.h include/ArInterpolation.h \ + include/ArKeyHandler.h include/ArCommands.h include/ArJoyHandler.h \ + include/ariaInternal.h include/ArStringInfoGroup.h \ + include/ArSonarDevice.h include/ArRangeDevice.h include/ArRangeBuffer.h \ + include/ArDrawingData.h include/ArPriorityResolver.h include/ArAction.h \ + include/ArArg.h include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/accDecelMaxTest: tests/accDecelMaxTest.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/actionArgumentTest: tests/actionArgumentTest.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/actionAverageTest: tests/actionAverageTest.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/actionManagementTest: tests/actionManagementTest.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/actsTest: tests/actsTest.cpp include/Aria.h include/ariaOSDef.h \ + include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/angleBetweenTest: tests/angleBetweenTest.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/angleFixTest: tests/angleFixTest.cpp include/Aria.h include/ariaOSDef.h \ + include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/angleTest: tests/angleTest.cpp include/Aria.h include/ariaOSDef.h \ + include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/asyncConnectTest: tests/asyncConnectTest.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/auxSerialTest: tests/auxSerialTest.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/batteryTest: tests/batteryTest.cpp include/Aria.h include/ariaOSDef.h \ + include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/callbackTest: tests/callbackTest.cpp include/Aria.h include/ariaOSDef.h \ + include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/chargeTest: tests/chargeTest.cpp include/Aria.h include/ariaOSDef.h \ + include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/compassDirect: tests/compassDirect.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h include/ArTCMCompassDirect.h +tests/compassDirectCalib: tests/compassDirectCalib.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h include/ArKeyHandler.h \ + include/ArTCMCompassDirect.h +tests/configSectionTest: tests/configSectionTest.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/configTest: tests/configTest.cpp include/Aria.h include/ariaOSDef.h \ + include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/connectTest: tests/connectTest.cpp include/Aria.h include/ariaOSDef.h \ + include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/connectionTest: tests/connectionTest.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/dcdTest: tests/dcdTest.cpp include/Aria.h include/ariaOSDef.h \ + include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/deleteArgs: tests/deleteArgs.cpp include/Aria.h include/ariaOSDef.h \ + include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/driveFast: tests/driveFast.cpp include/Aria.h include/ariaOSDef.h \ + include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/driveHardDirect: tests/driveHardDirect.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/encoderCorrectionTest: tests/encoderCorrectionTest.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/encoderTest: tests/encoderTest.cpp include/Aria.h include/ariaOSDef.h \ + include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/fileParserTest: tests/fileParserTest.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/functorTest: tests/functorTest.cpp include/Aria.h include/ariaOSDef.h \ + include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/gotoTest: tests/gotoTest.cpp include/Aria.h include/ariaOSDef.h \ + include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/gpsCoordsTest: tests/gpsCoordsTest.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h include/ArGPSCoords.h +tests/gpsInternals: tests/gpsInternals.cpp include/ArGPS.h \ + include/ariaTypedefs.h include/ArFunctor.h include/ariaOSDef.h \ + include/ariaUtil.h include/ArLog.h include/ArMutex.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArNMEAParser.h include/ArDeviceConnection.h \ + include/ArBasePacket.h +tests/gripperStateFlagsTest: tests/gripperStateFlagsTest.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/gyroDrive: tests/gyroDrive.cpp include/Aria.h include/ariaOSDef.h \ + include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/hardDriveWander: tests/hardDriveWander.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/interpolationTest: tests/interpolationTest.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/ioTest: tests/ioTest.cpp include/Aria.h include/ariaOSDef.h \ + include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/joytest: tests/joytest.cpp include/Aria.h include/ariaOSDef.h \ + include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/keyHandlerTest: tests/keyHandlerTest.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/keys: tests/keys.cpp include/Aria.h include/ariaOSDef.h \ + include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/lineTest: tests/lineTest.cpp include/Aria.h include/ariaOSDef.h \ + include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h include/ariaUtil.h +tests/lms2xxTest: tests/lms2xxTest.cpp include/Aria.h include/ariaOSDef.h \ + include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/logRobotJoystick: tests/logRobotJoystick.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/logSIPData: tests/logSIPData.cpp include/Aria.h include/ariaOSDef.h \ + include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/logSIPs: tests/logSIPs.cpp include/Aria.h include/ariaOSDef.h \ + include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/mapTest: tests/mapTest.cpp include/Aria.h include/ariaOSDef.h \ + include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/mathTests: tests/mathTests.cpp include/ariaUtil.h \ + include/ariaTypedefs.h include/ArLog.h include/ArMutex.h \ + include/ArFunctor.h include/ariaOSDef.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h +tests/moduleActionExample: tests/moduleActionExample.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/moduleActionExample2_Mod: tests/moduleActionExample2_Mod.cpp \ + include/Aria.h include/ariaOSDef.h include/ariaTypedefs.h \ + include/ArSerialConnection.h include/ArDeviceConnection.h \ + include/ariaUtil.h include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArBasePacket.h include/ArTcpConnection.h include/ArSocket.h \ + include/ArSimpleConnector.h include/ArRobotConnector.h \ + include/ArLaserConnector.h include/ArLogFileConnection.h \ + include/ArRobotPacket.h include/ArRobotPacketSender.h \ + include/ArRobotPacketReceiver.h include/ArRobotConfigPacketReader.h \ + include/ArRobotTypes.h include/ArRobotParams.h include/ArConfig.h \ + include/ArConfigArg.h include/ArFileParser.h include/ArHasFileName.h \ + include/ArConfigGroup.h include/ArRobot.h include/ArSyncTask.h \ + include/ArTaskState.h include/ArSensorReading.h include/ArTransform.h \ + include/ArCondition.h include/ArSyncLoop.h include/ArASyncTask.h \ + include/ArThread.h include/ArRobotPacketReaderThread.h \ + include/ArActionDesired.h include/ArResolver.h include/ArInterpolation.h \ + include/ArKeyHandler.h include/ArCommands.h include/ArJoyHandler.h \ + include/ariaInternal.h include/ArStringInfoGroup.h \ + include/ArSonarDevice.h include/ArRangeDevice.h include/ArRangeBuffer.h \ + include/ArDrawingData.h include/ArPriorityResolver.h include/ArAction.h \ + include/ArArg.h include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/moduleActionExample_Mod: tests/moduleActionExample_Mod.cpp \ + include/Aria.h include/ariaOSDef.h include/ariaTypedefs.h \ + include/ArSerialConnection.h include/ArDeviceConnection.h \ + include/ariaUtil.h include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArBasePacket.h include/ArTcpConnection.h include/ArSocket.h \ + include/ArSimpleConnector.h include/ArRobotConnector.h \ + include/ArLaserConnector.h include/ArLogFileConnection.h \ + include/ArRobotPacket.h include/ArRobotPacketSender.h \ + include/ArRobotPacketReceiver.h include/ArRobotConfigPacketReader.h \ + include/ArRobotTypes.h include/ArRobotParams.h include/ArConfig.h \ + include/ArConfigArg.h include/ArFileParser.h include/ArHasFileName.h \ + include/ArConfigGroup.h include/ArRobot.h include/ArSyncTask.h \ + include/ArTaskState.h include/ArSensorReading.h include/ArTransform.h \ + include/ArCondition.h include/ArSyncLoop.h include/ArASyncTask.h \ + include/ArThread.h include/ArRobotPacketReaderThread.h \ + include/ArActionDesired.h include/ArResolver.h include/ArInterpolation.h \ + include/ArKeyHandler.h include/ArCommands.h include/ArJoyHandler.h \ + include/ariaInternal.h include/ArStringInfoGroup.h \ + include/ArSonarDevice.h include/ArRangeDevice.h include/ArRangeBuffer.h \ + include/ArDrawingData.h include/ArPriorityResolver.h include/ArAction.h \ + include/ArArg.h include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/moveCommandTest: tests/moveCommandTest.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/moveRobotInSim: tests/moveRobotInSim.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/moveRobotTest: tests/moveRobotTest.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/mutexLockWarning: tests/mutexLockWarning.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/nmeaParser: tests/nmeaParser.cpp include/ArNMEAParser.h \ + include/ariaTypedefs.h include/ArFunctor.h include/ariaOSDef.h \ + include/ariaUtil.h include/ArLog.h include/ArMutex.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArDeviceConnection.h include/ArBasePacket.h +tests/optoIOtest: tests/optoIOtest.cpp include/Aria.h include/ariaOSDef.h \ + include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/p2osSlamTest: tests/p2osSlamTest.cpp include/Aria.h include/ariaOSDef.h \ + include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/poseTest: tests/poseTest.cpp include/Aria.h include/ariaOSDef.h \ + include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/proprietaryCommand: tests/proprietaryCommand.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/proprietaryConfigLeakTest: tests/proprietaryConfigLeakTest.cpp \ + include/Aria.h include/ariaOSDef.h include/ariaTypedefs.h \ + include/ArSerialConnection.h include/ArDeviceConnection.h \ + include/ariaUtil.h include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArBasePacket.h include/ArTcpConnection.h include/ArSocket.h \ + include/ArSimpleConnector.h include/ArRobotConnector.h \ + include/ArLaserConnector.h include/ArLogFileConnection.h \ + include/ArRobotPacket.h include/ArRobotPacketSender.h \ + include/ArRobotPacketReceiver.h include/ArRobotConfigPacketReader.h \ + include/ArRobotTypes.h include/ArRobotParams.h include/ArConfig.h \ + include/ArConfigArg.h include/ArFileParser.h include/ArHasFileName.h \ + include/ArConfigGroup.h include/ArRobot.h include/ArSyncTask.h \ + include/ArTaskState.h include/ArSensorReading.h include/ArTransform.h \ + include/ArCondition.h include/ArSyncLoop.h include/ArASyncTask.h \ + include/ArThread.h include/ArRobotPacketReaderThread.h \ + include/ArActionDesired.h include/ArResolver.h include/ArInterpolation.h \ + include/ArKeyHandler.h include/ArCommands.h include/ArJoyHandler.h \ + include/ariaInternal.h include/ArStringInfoGroup.h \ + include/ArSonarDevice.h include/ArRangeDevice.h include/ArRangeBuffer.h \ + include/ArDrawingData.h include/ArPriorityResolver.h include/ArAction.h \ + include/ArArg.h include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/proprietaryGenericIOpowerTest: tests/proprietaryGenericIOpowerTest.cpp \ + include/Aria.h include/ariaOSDef.h include/ariaTypedefs.h \ + include/ArSerialConnection.h include/ArDeviceConnection.h \ + include/ariaUtil.h include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArBasePacket.h include/ArTcpConnection.h include/ArSocket.h \ + include/ArSimpleConnector.h include/ArRobotConnector.h \ + include/ArLaserConnector.h include/ArLogFileConnection.h \ + include/ArRobotPacket.h include/ArRobotPacketSender.h \ + include/ArRobotPacketReceiver.h include/ArRobotConfigPacketReader.h \ + include/ArRobotTypes.h include/ArRobotParams.h include/ArConfig.h \ + include/ArConfigArg.h include/ArFileParser.h include/ArHasFileName.h \ + include/ArConfigGroup.h include/ArRobot.h include/ArSyncTask.h \ + include/ArTaskState.h include/ArSensorReading.h include/ArTransform.h \ + include/ArCondition.h include/ArSyncLoop.h include/ArASyncTask.h \ + include/ArThread.h include/ArRobotPacketReaderThread.h \ + include/ArActionDesired.h include/ArResolver.h include/ArInterpolation.h \ + include/ArKeyHandler.h include/ArCommands.h include/ArJoyHandler.h \ + include/ariaInternal.h include/ArStringInfoGroup.h \ + include/ArSonarDevice.h include/ArRangeDevice.h include/ArRangeBuffer.h \ + include/ArDrawingData.h include/ArPriorityResolver.h include/ArAction.h \ + include/ArArg.h include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/proprietaryGnuplotTest: tests/proprietaryGnuplotTest.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h include/proprietaryArGnuplot.h +tests/proprietaryH8Test: tests/proprietaryH8Test.cpp \ + tests/proprietaryH8Test.h include/Aria.h include/ariaOSDef.h \ + include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h include/ArFunctor.h +tests/proprietaryLCDWrite: tests/proprietaryLCDWrite.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/proprietaryLCDtest: tests/proprietaryLCDtest.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/proprietaryMappingTest: tests/proprietaryMappingTest.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/proprietaryPDBTest: tests/proprietaryPDBTest.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h include/proprietaryArGnuplot.h +tests/proprietaryPowerBoardTest: tests/proprietaryPowerBoardTest.cpp \ + include/Aria.h include/ariaOSDef.h include/ariaTypedefs.h \ + include/ArSerialConnection.h include/ArDeviceConnection.h \ + include/ariaUtil.h include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArBasePacket.h include/ArTcpConnection.h include/ArSocket.h \ + include/ArSimpleConnector.h include/ArRobotConnector.h \ + include/ArLaserConnector.h include/ArLogFileConnection.h \ + include/ArRobotPacket.h include/ArRobotPacketSender.h \ + include/ArRobotPacketReceiver.h include/ArRobotConfigPacketReader.h \ + include/ArRobotTypes.h include/ArRobotParams.h include/ArConfig.h \ + include/ArConfigArg.h include/ArFileParser.h include/ArHasFileName.h \ + include/ArConfigGroup.h include/ArRobot.h include/ArSyncTask.h \ + include/ArTaskState.h include/ArSensorReading.h include/ArTransform.h \ + include/ArCondition.h include/ArSyncLoop.h include/ArASyncTask.h \ + include/ArThread.h include/ArRobotPacketReaderThread.h \ + include/ArActionDesired.h include/ArResolver.h include/ArInterpolation.h \ + include/ArKeyHandler.h include/ArCommands.h include/ArJoyHandler.h \ + include/ariaInternal.h include/ArStringInfoGroup.h \ + include/ArSonarDevice.h include/ArRangeDevice.h include/ArRangeBuffer.h \ + include/ArDrawingData.h include/ArPriorityResolver.h include/ArAction.h \ + include/ArArg.h include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/proprietaryPowerDockMonitor: tests/proprietaryPowerDockMonitor.cpp \ + include/Aria.h include/ariaOSDef.h include/ariaTypedefs.h \ + include/ArSerialConnection.h include/ArDeviceConnection.h \ + include/ariaUtil.h include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArBasePacket.h include/ArTcpConnection.h include/ArSocket.h \ + include/ArSimpleConnector.h include/ArRobotConnector.h \ + include/ArLaserConnector.h include/ArLogFileConnection.h \ + include/ArRobotPacket.h include/ArRobotPacketSender.h \ + include/ArRobotPacketReceiver.h include/ArRobotConfigPacketReader.h \ + include/ArRobotTypes.h include/ArRobotParams.h include/ArConfig.h \ + include/ArConfigArg.h include/ArFileParser.h include/ArHasFileName.h \ + include/ArConfigGroup.h include/ArRobot.h include/ArSyncTask.h \ + include/ArTaskState.h include/ArSensorReading.h include/ArTransform.h \ + include/ArCondition.h include/ArSyncLoop.h include/ArASyncTask.h \ + include/ArThread.h include/ArRobotPacketReaderThread.h \ + include/ArActionDesired.h include/ArResolver.h include/ArInterpolation.h \ + include/ArKeyHandler.h include/ArCommands.h include/ArJoyHandler.h \ + include/ariaInternal.h include/ArStringInfoGroup.h \ + include/ArSonarDevice.h include/ArRangeDevice.h include/ArRangeBuffer.h \ + include/ArDrawingData.h include/ArPriorityResolver.h include/ArAction.h \ + include/ArArg.h include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/proprietarySaftTestAllCommands: \ + tests/proprietarySaftTestAllCommands.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/proprietarySeekurPDBPowerCycle: \ + tests/proprietarySeekurPDBPowerCycle.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/proprietaryShowLeftRight: tests/proprietaryShowLeftRight.cpp \ + include/Aria.h include/ariaOSDef.h include/ariaTypedefs.h \ + include/ArSerialConnection.h include/ArDeviceConnection.h \ + include/ariaUtil.h include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArBasePacket.h include/ArTcpConnection.h include/ArSocket.h \ + include/ArSimpleConnector.h include/ArRobotConnector.h \ + include/ArLaserConnector.h include/ArLogFileConnection.h \ + include/ArRobotPacket.h include/ArRobotPacketSender.h \ + include/ArRobotPacketReceiver.h include/ArRobotConfigPacketReader.h \ + include/ArRobotTypes.h include/ArRobotParams.h include/ArConfig.h \ + include/ArConfigArg.h include/ArFileParser.h include/ArHasFileName.h \ + include/ArConfigGroup.h include/ArRobot.h include/ArSyncTask.h \ + include/ArTaskState.h include/ArSensorReading.h include/ArTransform.h \ + include/ArCondition.h include/ArSyncLoop.h include/ArASyncTask.h \ + include/ArThread.h include/ArRobotPacketReaderThread.h \ + include/ArActionDesired.h include/ArResolver.h include/ArInterpolation.h \ + include/ArKeyHandler.h include/ArCommands.h include/ArJoyHandler.h \ + include/ariaInternal.h include/ArStringInfoGroup.h \ + include/ArSonarDevice.h include/ArRangeDevice.h include/ArRangeBuffer.h \ + include/ArDrawingData.h include/ArPriorityResolver.h include/ArAction.h \ + include/ArArg.h include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h include/ArSoundPlayer.h +tests/proprietarySoundPlayerWithMuchMalloc: \ + tests/proprietarySoundPlayerWithMuchMalloc.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h include/ArSoundPlayer.h +tests/proprietarySpARCSburnin: tests/proprietarySpARCSburnin.cpp \ + include/Aria.h include/ariaOSDef.h include/ariaTypedefs.h \ + include/ArSerialConnection.h include/ArDeviceConnection.h \ + include/ariaUtil.h include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArBasePacket.h include/ArTcpConnection.h include/ArSocket.h \ + include/ArSimpleConnector.h include/ArRobotConnector.h \ + include/ArLaserConnector.h include/ArLogFileConnection.h \ + include/ArRobotPacket.h include/ArRobotPacketSender.h \ + include/ArRobotPacketReceiver.h include/ArRobotConfigPacketReader.h \ + include/ArRobotTypes.h include/ArRobotParams.h include/ArConfig.h \ + include/ArConfigArg.h include/ArFileParser.h include/ArHasFileName.h \ + include/ArConfigGroup.h include/ArRobot.h include/ArSyncTask.h \ + include/ArTaskState.h include/ArSensorReading.h include/ArTransform.h \ + include/ArCondition.h include/ArSyncLoop.h include/ArASyncTask.h \ + include/ArThread.h include/ArRobotPacketReaderThread.h \ + include/ArActionDesired.h include/ArResolver.h include/ArInterpolation.h \ + include/ArKeyHandler.h include/ArCommands.h include/ArJoyHandler.h \ + include/ariaInternal.h include/ArStringInfoGroup.h \ + include/ArSonarDevice.h include/ArRangeDevice.h include/ArRangeBuffer.h \ + include/ArDrawingData.h include/ArPriorityResolver.h include/ArAction.h \ + include/ArArg.h include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/proprietarySpARCSburninViauARCS: \ + tests/proprietarySpARCSburninViauARCS.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/proprietarySpARCStest: tests/proprietarySpARCStest.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/proprietarySpARCSviauARCStest: tests/proprietarySpARCSviauARCStest.cpp \ + include/Aria.h include/ariaOSDef.h include/ariaTypedefs.h \ + include/ArSerialConnection.h include/ArDeviceConnection.h \ + include/ariaUtil.h include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArBasePacket.h include/ArTcpConnection.h include/ArSocket.h \ + include/ArSimpleConnector.h include/ArRobotConnector.h \ + include/ArLaserConnector.h include/ArLogFileConnection.h \ + include/ArRobotPacket.h include/ArRobotPacketSender.h \ + include/ArRobotPacketReceiver.h include/ArRobotConfigPacketReader.h \ + include/ArRobotTypes.h include/ArRobotParams.h include/ArConfig.h \ + include/ArConfigArg.h include/ArFileParser.h include/ArHasFileName.h \ + include/ArConfigGroup.h include/ArRobot.h include/ArSyncTask.h \ + include/ArTaskState.h include/ArSensorReading.h include/ArTransform.h \ + include/ArCondition.h include/ArSyncLoop.h include/ArASyncTask.h \ + include/ArThread.h include/ArRobotPacketReaderThread.h \ + include/ArActionDesired.h include/ArResolver.h include/ArInterpolation.h \ + include/ArKeyHandler.h include/ArCommands.h include/ArJoyHandler.h \ + include/ariaInternal.h include/ArStringInfoGroup.h \ + include/ArSonarDevice.h include/ArRangeDevice.h include/ArRangeBuffer.h \ + include/ArDrawingData.h include/ArPriorityResolver.h include/ArAction.h \ + include/ArArg.h include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/proprietaryTestGenerator: tests/proprietaryTestGenerator.cpp \ + include/Aria.h include/ariaOSDef.h include/ariaTypedefs.h \ + include/ArSerialConnection.h include/ArDeviceConnection.h \ + include/ariaUtil.h include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArBasePacket.h include/ArTcpConnection.h include/ArSocket.h \ + include/ArSimpleConnector.h include/ArRobotConnector.h \ + include/ArLaserConnector.h include/ArLogFileConnection.h \ + include/ArRobotPacket.h include/ArRobotPacketSender.h \ + include/ArRobotPacketReceiver.h include/ArRobotConfigPacketReader.h \ + include/ArRobotTypes.h include/ArRobotParams.h include/ArConfig.h \ + include/ArConfigArg.h include/ArFileParser.h include/ArHasFileName.h \ + include/ArConfigGroup.h include/ArRobot.h include/ArSyncTask.h \ + include/ArTaskState.h include/ArSensorReading.h include/ArTransform.h \ + include/ArCondition.h include/ArSyncLoop.h include/ArASyncTask.h \ + include/ArThread.h include/ArRobotPacketReaderThread.h \ + include/ArActionDesired.h include/ArResolver.h include/ArInterpolation.h \ + include/ArKeyHandler.h include/ArCommands.h include/ArJoyHandler.h \ + include/ariaInternal.h include/ArStringInfoGroup.h \ + include/ArSonarDevice.h include/ArRangeDevice.h include/ArRangeBuffer.h \ + include/ArDrawingData.h include/ArPriorityResolver.h include/ArAction.h \ + include/ArArg.h include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/proprietaryTonyBox: tests/proprietaryTonyBox.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/ptzTest: tests/ptzTest.cpp include/Aria.h include/ariaOSDef.h \ + include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/robotConfigPacketReaderTest: tests/robotConfigPacketReaderTest.cpp \ + include/Aria.h include/ariaOSDef.h include/ariaTypedefs.h \ + include/ArSerialConnection.h include/ArDeviceConnection.h \ + include/ariaUtil.h include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArBasePacket.h include/ArTcpConnection.h include/ArSocket.h \ + include/ArSimpleConnector.h include/ArRobotConnector.h \ + include/ArLaserConnector.h include/ArLogFileConnection.h \ + include/ArRobotPacket.h include/ArRobotPacketSender.h \ + include/ArRobotPacketReceiver.h include/ArRobotConfigPacketReader.h \ + include/ArRobotTypes.h include/ArRobotParams.h include/ArConfig.h \ + include/ArConfigArg.h include/ArFileParser.h include/ArHasFileName.h \ + include/ArConfigGroup.h include/ArRobot.h include/ArSyncTask.h \ + include/ArTaskState.h include/ArSensorReading.h include/ArTransform.h \ + include/ArCondition.h include/ArSyncLoop.h include/ArASyncTask.h \ + include/ArThread.h include/ArRobotPacketReaderThread.h \ + include/ArActionDesired.h include/ArResolver.h include/ArInterpolation.h \ + include/ArKeyHandler.h include/ArCommands.h include/ArJoyHandler.h \ + include/ariaInternal.h include/ArStringInfoGroup.h \ + include/ArSonarDevice.h include/ArRangeDevice.h include/ArRangeBuffer.h \ + include/ArDrawingData.h include/ArPriorityResolver.h include/ArAction.h \ + include/ArArg.h include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/robotListTest: tests/robotListTest.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/robotPacketHandlerTest: tests/robotPacketHandlerTest.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/rotVelActionExample: tests/rotVelActionExample.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/runtimeTest: tests/runtimeTest.cpp include/Aria.h include/ariaOSDef.h \ + include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/samePriorityActionTest: tests/samePriorityActionTest.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/serialDump: tests/serialDump.cpp include/Aria.h include/ariaOSDef.h \ + include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/serialTest: tests/serialTest.cpp include/Aria.h include/ariaOSDef.h \ + include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/serialTest2: tests/serialTest2.cpp include/Aria.h include/ariaOSDef.h \ + include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/showFirmwareParameters: tests/showFirmwareParameters.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/sickMiddleTest: tests/sickMiddleTest.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/sickQuadrantReadings: tests/sickQuadrantReadings.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/sickSafeAutoLogger: tests/sickSafeAutoLogger.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/sickSimpleTest: tests/sickSimpleTest.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/sickTest: tests/sickTest.cpp include/Aria.h include/ariaOSDef.h \ + include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/sickTestAll: tests/sickTestAll.cpp include/Aria.h include/ariaOSDef.h \ + include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/signalTest: tests/signalTest.cpp include/Aria.h include/ariaOSDef.h \ + include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/sonarAutoDisablerTest: tests/sonarAutoDisablerTest.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/sonarDeviceTest: tests/sonarDeviceTest.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/sonarMonitor: tests/sonarMonitor.cpp include/Aria.h include/ariaOSDef.h \ + include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/sonarQuadrantReadings: tests/sonarQuadrantReadings.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/sonarTest: tests/sonarTest.cpp include/Aria.h include/ariaOSDef.h \ + include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/soundPlayer: tests/soundPlayer.cpp include/ArSoundPlayer.h \ + include/ArFunctor.h include/ariaTypedefs.h include/ariaOSDef.h +tests/stallTest: tests/stallTest.cpp include/Aria.h include/ariaOSDef.h \ + include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/stressTest: tests/stressTest.cpp include/Aria.h include/ariaOSDef.h \ + include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/stripQuoteTest: tests/stripQuoteTest.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/systemCallTest: tests/systemCallTest.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/systemStatusBasic: tests/systemStatusBasic.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h include/ArSystemStatus.h +tests/systemStatusThread: tests/systemStatusThread.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h include/ArSystemStatus.h +tests/tcm2Test: tests/tcm2Test.cpp include/Aria.h include/ariaOSDef.h \ + include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/tcpConnectionTest: tests/tcpConnectionTest.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/testAbsoluteMaxesCommand: tests/testAbsoluteMaxesCommand.cpp \ + include/Aria.h include/ariaOSDef.h include/ariaTypedefs.h \ + include/ArSerialConnection.h include/ArDeviceConnection.h \ + include/ariaUtil.h include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArBasePacket.h include/ArTcpConnection.h include/ArSocket.h \ + include/ArSimpleConnector.h include/ArRobotConnector.h \ + include/ArLaserConnector.h include/ArLogFileConnection.h \ + include/ArRobotPacket.h include/ArRobotPacketSender.h \ + include/ArRobotPacketReceiver.h include/ArRobotConfigPacketReader.h \ + include/ArRobotTypes.h include/ArRobotParams.h include/ArConfig.h \ + include/ArConfigArg.h include/ArFileParser.h include/ArHasFileName.h \ + include/ArConfigGroup.h include/ArRobot.h include/ArSyncTask.h \ + include/ArTaskState.h include/ArSensorReading.h include/ArTransform.h \ + include/ArCondition.h include/ArSyncLoop.h include/ArASyncTask.h \ + include/ArThread.h include/ArRobotPacketReaderThread.h \ + include/ArActionDesired.h include/ArResolver.h include/ArInterpolation.h \ + include/ArKeyHandler.h include/ArCommands.h include/ArJoyHandler.h \ + include/ariaInternal.h include/ArStringInfoGroup.h \ + include/ArSonarDevice.h include/ArRangeDevice.h include/ArRangeBuffer.h \ + include/ArDrawingData.h include/ArPriorityResolver.h include/ArAction.h \ + include/ArArg.h include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/testCOM: tests/testCOM.cpp include/Aria.h include/ariaOSDef.h \ + include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/testMobileSim: tests/testMobileSim.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/threadTest: tests/threadTest.cpp include/Aria.h include/ariaOSDef.h \ + include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/timePrinter: tests/timePrinter.cpp include/Aria.h include/ariaOSDef.h \ + include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/timeTest: tests/timeTest.cpp include/Aria.h include/ariaOSDef.h \ + include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/timingTest: tests/timingTest.cpp include/Aria.h include/ariaOSDef.h \ + include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/transformTest: tests/transformTest.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/triangleAccuracyTest: tests/triangleAccuracyTest.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/usertasktest: tests/usertasktest.cpp include/Aria.h include/ariaOSDef.h \ + include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/vcc4Test: tests/vcc4Test.cpp include/Aria.h include/ariaOSDef.h \ + include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/velTest: tests/velTest.cpp include/Aria.h include/ariaOSDef.h \ + include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +tests/wanderAndLogBumps: tests/wanderAndLogBumps.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +advanced/actsDemo: advanced/actsDemo.cpp include/Aria.h include/ariaOSDef.h \ + include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +advanced/actsDemoSimple: advanced/actsDemoSimple.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +advanced/amptuDemo: advanced/amptuDemo.cpp include/Aria.h include/ariaOSDef.h \ + include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +advanced/condition: advanced/condition.cpp include/Aria.h include/ariaOSDef.h \ + include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +advanced/functorListsAndStdAlgorithms: advanced/functorListsAndStdAlgorithms.cpp \ + include/Aria.h include/ariaOSDef.h include/ariaTypedefs.h \ + include/ArSerialConnection.h include/ArDeviceConnection.h \ + include/ariaUtil.h include/ArLog.h include/ArMutex.h include/ArFunctor.h \ + include/ArArgumentParser.h include/ArArgumentBuilder.h \ + include/ArBasePacket.h include/ArTcpConnection.h include/ArSocket.h \ + include/ArSimpleConnector.h include/ArRobotConnector.h \ + include/ArLaserConnector.h include/ArLogFileConnection.h \ + include/ArRobotPacket.h include/ArRobotPacketSender.h \ + include/ArRobotPacketReceiver.h include/ArRobotConfigPacketReader.h \ + include/ArRobotTypes.h include/ArRobotParams.h include/ArConfig.h \ + include/ArConfigArg.h include/ArFileParser.h include/ArHasFileName.h \ + include/ArConfigGroup.h include/ArRobot.h include/ArSyncTask.h \ + include/ArTaskState.h include/ArSensorReading.h include/ArTransform.h \ + include/ArCondition.h include/ArSyncLoop.h include/ArASyncTask.h \ + include/ArThread.h include/ArRobotPacketReaderThread.h \ + include/ArActionDesired.h include/ArResolver.h include/ArInterpolation.h \ + include/ArKeyHandler.h include/ArCommands.h include/ArJoyHandler.h \ + include/ariaInternal.h include/ArStringInfoGroup.h \ + include/ArSonarDevice.h include/ArRangeDevice.h include/ArRangeBuffer.h \ + include/ArDrawingData.h include/ArPriorityResolver.h include/ArAction.h \ + include/ArArg.h include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +advanced/joydriveActionMod: advanced/joydriveActionMod.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +advanced/joydriveActionModule: advanced/joydriveActionModule.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +advanced/joydriveUserControl: advanced/joydriveUserControl.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +advanced/peoplebotDemo: advanced/peoplebotDemo.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +advanced/sickAutoLogger: advanced/sickAutoLogger.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +advanced/sickSpinLogger: advanced/sickSpinLogger.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h +advanced/sickSquareLogger: advanced/sickSquareLogger.cpp include/Aria.h \ + include/ariaOSDef.h include/ariaTypedefs.h include/ArSerialConnection.h \ + include/ArDeviceConnection.h include/ariaUtil.h include/ArLog.h \ + include/ArMutex.h include/ArFunctor.h include/ArArgumentParser.h \ + include/ArArgumentBuilder.h include/ArBasePacket.h \ + include/ArTcpConnection.h include/ArSocket.h include/ArSimpleConnector.h \ + include/ArRobotConnector.h include/ArLaserConnector.h \ + include/ArLogFileConnection.h include/ArRobotPacket.h \ + include/ArRobotPacketSender.h include/ArRobotPacketReceiver.h \ + include/ArRobotConfigPacketReader.h include/ArRobotTypes.h \ + include/ArRobotParams.h include/ArConfig.h include/ArConfigArg.h \ + include/ArFileParser.h include/ArHasFileName.h include/ArConfigGroup.h \ + include/ArRobot.h include/ArSyncTask.h include/ArTaskState.h \ + include/ArSensorReading.h include/ArTransform.h include/ArCondition.h \ + include/ArSyncLoop.h include/ArASyncTask.h include/ArThread.h \ + include/ArRobotPacketReaderThread.h include/ArActionDesired.h \ + include/ArResolver.h include/ArInterpolation.h include/ArKeyHandler.h \ + include/ArCommands.h include/ArJoyHandler.h include/ariaInternal.h \ + include/ArStringInfoGroup.h include/ArSonarDevice.h \ + include/ArRangeDevice.h include/ArRangeBuffer.h include/ArDrawingData.h \ + include/ArPriorityResolver.h include/ArAction.h include/ArArg.h \ + include/ArActionGroup.h include/ArActionGroups.h \ + include/ArActionColorFollow.h include/ArACTS.h include/ArPTZ.h \ + include/ArPTZConnector.h include/ArActionDeceleratingLimiter.h \ + include/ArActionLimiterForwards.h include/ArActionLimiterBackwards.h \ + include/ArActionLimiterTableSensor.h include/ArActionBumpers.h \ + include/ArActionIRs.h include/ArActionStallRecover.h \ + include/ArActionAvoidFront.h include/ArActionAvoidSide.h \ + include/ArActionConstantVelocity.h include/ArActionInput.h \ + include/ArActionRobotJoydrive.h include/ArActionJoydrive.h \ + include/ArActionKeydrive.h include/ArActionTriangleDriveTo.h \ + include/ArLineFinder.h include/ArActionTurn.h \ + include/ArActionRatioInput.h include/ArActionStop.h \ + include/ArActionGoto.h include/ArModule.h include/ArModuleLoader.h \ + include/ArRecurrentTask.h include/ArGripper.h include/ArSonyPTZ.h \ + include/ArRVisionPTZ.h include/ArAMPTU.h include/ArP2Arm.h \ + include/ArSick.h include/ArLaser.h include/ArRangeDeviceThreaded.h \ + include/ArFunctorASyncTask.h include/ArLMS2xx.h include/ArLMS2xxPacket.h \ + include/ArLMS2xxPacketReceiver.h include/ArLaserLogger.h \ + include/ArIrrfDevice.h include/ArDPPTU.h include/ArVCC4.h \ + include/ArMode.h include/ArModes.h include/ArTCMCompassRobot.h \ + include/ArTCM2.h include/ArNetServer.h include/ArSignalHandler.h \ + include/ArAnalogGyro.h include/ArMapInterface.h include/ArMapObject.h \ + include/ArMapUtils.h include/ArMap.h include/ArMapComponents.h \ + include/ArBumpers.h include/ArIRs.h include/ArForbiddenRangeDevice.h \ + include/ArVersalogicIO.h include/ArMTXIO.h \ + include/ArActionGotoStraight.h include/ArDataLogger.h \ + include/ArRobotJoyHandler.h include/ArRatioInputKeydrive.h \ + include/ArRatioInputJoydrive.h include/ArRatioInputRobotJoydrive.h \ + include/ArActionMovementParameters.h include/ArSoundPlayer.h \ + include/ArSoundsQueue.h include/ArSpeech.h include/ArCameraCollection.h \ + include/ArCameraCommands.h include/ArSonarAutoDisabler.h \ + include/ArActionDriveDistance.h include/ArLaserReflectorDevice.h \ + include/ArRobotConfig.h include/ArTCMCompassDirect.h \ + include/ArNMEAParser.h include/ArLaserFilter.h include/ArUrg.h \ + include/ArGPS.h include/ArTrimbleGPS.h include/ArNovatelGPS.h \ + include/ArGPSCoords.h include/ArSonarConnector.h \ + include/ArBatteryConnector.h include/ArLCDConnector.h \ + include/ArSonarMTX.h include/ArBatteryMTX.h include/ArLCDMTX.h \ + include/ArSimulatedLaser.h include/ArExitErrorSource.h \ + include/ArActionLimiterRot.h include/ArRobotBatteryPacketReader.h \ + include/ArLMS1XX.h include/ArUrg_2_0.h \ + include/ArActionMovementParametersDebugging.h include/ArZippable.h \ + include/ArS3Series.h include/ArSZSeries.h diff --git a/Legacy/Aria/README.txt b/Legacy/Aria/README.txt new file mode 100644 index 0000000..1ea395a --- /dev/null +++ b/Legacy/Aria/README.txt @@ -0,0 +1,546 @@ + +ARIA +==== + +Adept MobileRobots Advanced Robotics Interface for Applications +--------------------------------------------------------------- + +Version 2.8.0 + +Linux + +Copyright 2002, 2003, 2004, 2005 +ActivMedia Robotics, LLC. All rights reserved. + +Copyright 2006, 2007, 2008, 2009 +MobileRobots Inc. All rights reserved. + +Copyright 2010, 2011, 2012, 2013 +Adept Technology. All rights reserved. + +See LICENSE.txt for full license information about ARIA. + +Please read this document for important details about using ARIA. + +Contents +======== + +* Introduction +* Documentation +* Licenses and Sharing +* ARIA Package +* Files of Note +* Compiling programs that use ARIA + * Windows + * Linux + * Using ARIA's Makefiles + * Using your own Makefile or other build system + * Setting variables for ARIA Makefiles + * Learning more about using Linux + * Learning more about C++ +* Using ARIA from Python and Java +* Simulator + +Introduction +============ + +Welcome to the Adept MobileRobots Advanced Robotics Interface for Applications (ARIA). +ARIA is an object-oriented, application programming interface (API) for +Adept MobileRobots (and ActivMedia) line of intelligent mobile robots, including +Pioneer 2/3 DX and AT, PeopleBot, PowerBot, AmigoBot, PatrolBot/Guiabot, +Seekur and SeekurJr mobile robots. + +Written in the C++ language, ARIA is client-side software for easy, +high-performance access to and management of the robot server, as well +to the many accessory robot sensors and effectors, and useful utilities. + +ARIA can be run multi- or single-threaded, using its own wrapper +around Linux pthreads and WIN32 threads. Use ARIA in many different +ways, from simple command-control of the robot server for direct-drive +navigation, to development of higher-level intelligent actions (aka +behaviors). Add your own features and modifications to ARIA: It's +open-source! + +The ARIA package includes both source code and pre-build libraries +and example programs. These libraries and programs were build with +GCC 3.4 if on Linux, and MS Visual Studio .NET 2003 (7.1), Visual C++ +Express 2008 (9.0) or Visual C++ Express 2010 (10.0) if on Windows. +Using these compilers for development is recommended. + +NOTE: If you use a different compiler or compiler version, you must +rebuild the ARIA libraries to ensure link compatability. + +See below for more information about building programs with ARIA +on Windows and Linux and using the Windows and Linux development tools. + + +Documentation and Help +====================== + +Follow the INSTALL text instructions to install ARIA on your Linux or +Windows workstation or robot computer. System requirements are included +in the INSTALL.txt file. + +ARIA includes a full API Reference Manual in HTML format. This manual, +Aria-Reference.html (and in the docs/ directory), includes documentation +about each of the classes and methods in ARIA, as well as a comprehensive +overview describing how to get stated understanding and using ARIA. In +addition, ARIA includes several example programs in the examples/ +(start with simpleConnect.cpp, then explore the others) and +advanced/ directories, and the header files and source code are included +in include/ and src/ as well. + +The ArNetworking library has its own reference manual, +ArNetworking-Reference.html in the ArNetworking subdirectory, and examples +in ArNetworking/examples. + +If you plan on using the Java or Python wrapper libraries, see the +javaExamples, pythonExamples, ArNetworking/javaExamples and +ArNetworking/pythonExamples directories for important information in +README files, and example programs. You should also read the Aria Reference +manual for general information about Aria -- the API in the wrapper libraries +are almost identical to the C++ API. + +If you have any problems or questions using ARIA or your robot, the +MobileRobots support site provides: + + * A FAQ (Frequently Asked Questions) list, at + * A knowlege base of information on robot hardware and software, at + * All robot and device manuals + * The Aria-Users mailing list, where you can discuss Aria with other users and + MobileRobots software developers: + * Search the archives at + * Join the list at + * Information on contacting MobileRobots technical support. + +License and Sharing +=================== + +ARIA is released under the GNU Public License, which means that if you +distribute any work which uses ARIA, you must distribute the entire +source code to that work under the GPS as well. Read the included +LICENSE text for details. We open-sourced ARIA under GPL with full +source code not only for your convenience, but also so that you can +share your enhancements to the software. If you wish your enhancements +to make it into our future ARIA versions, you will need to assign the +copyright on those changes to Adept. Contact lafary@mobilerobots.com +with these changes or with questions about this. + +Accordingly, please do share your work, and please sign up for the +exclusive aria-users@mobilerobots.com newslist so that you can benefit +from others' work, too. + +ARIA may instead be relicensed for proprietary, closed source applications. +Contact sales@mobilerobots.com for details. + +For answers to frequently asked questions about what the GPL allows +and requires, see + + +The ARIA Package +================ + +Aria/: + docs The API Reference Manual: Extensive documentation of all of ARIA + examples ARIA examples -- a good place to start; see examples/README.txt + include ARIA header (*.h) files + src ARIA source code (*.cpp) files + lib Libraries (.lib files for Windows, .so files for Linux) + bin Contains Windows binaries and DLLs. + params Robot definition (parameter) files ("p3dx.p", for example) + tests Test files, somewhat esoteric but useful during ARIA development + utils Utility commands, not generally needed + advanced Advanced demos, not for the faint of heart (or ARIA novice) + python Python wrapper package + java Java wrapper package + +Aria/ArNetworking/: (A library used to facilitate network communication) + docs API Reference Manual for ArNetworking + examples ArNetworking examples + include ArNetworking header (*.h) files, of course + src ArNetworking source (*.cpp) files + python Python wrapper package + java Java wrapper package + + +Other ARIA Files of Note +======================== + +LICENSE.txt GPL license; agree to this to use ARIA +Aria-vc2003.sln MSVC++ 2003 solution for building ARIA and 'demo'. +Aria-vc2008.sln MSVC++ 2008 solution file for building ARIA and demo. +Aria-VC2010.sln MSVC++ 2010 solution file forbuilding Aria and demo. +examples/All_examples-vc2003.sln + MSVC++ 2003 solution for building all of the examples +examples/All_examples-vc2008.sln + MSVC++ 2008 solution for building all of the examples +examples/All_examples-vc2010.sln + MSVC++ 2010 solution for building all of the examples +Makefile Linux makefile (GNU Make) for building ARIA and examples +Makefile.dep Linux dependency file +INSTALL.txt More information about installing ARIA +README.txt This file; also see READMEs in advanced/, examples/, and tests/ +Changes.txt Summary of changes in each version of ARIA + + +Building programs that use ARIA +=============================== + +Windows +------- + +On Windows, use Microsoft Visual Studio .NET 2003 (MS Visual C++ 7.1), +Visual C++ 2008 (VC9), or Visual C++ 2010 (VC10). + +Note: If you use a different version of Visual C++, you must rebuild +the ARIA libraries. We recommand and support only these versions; other +versions may or may not work. + +You can add your new project the Visual Studio solution files provided with ARIA if you +wish, or create a new solution and add your new project as well as projects +for the ARIA libraries you use. + +Now you must configure your project to find ARIA. These instructions +assume a default installation; if you installed ARIA elsewhere you +must use different paths. If you keep your Visual Studo project within +Aria's directory, you can also use relative paths (e.g. "..\lib" for the +library path). + +Aria libraries are provided in two variants, "Debug" libraries that use +the "Multithreaded Debug DLL" runtime library, and non-Debug (or "Release") libraries +that use the plain "Multithreaded DLL" runtime library. The ARIA solutions +use a "Debug" and a "Release" configuration to select these variants; you +can also use these configuration names as well if you wish. + +1. Create new configuration in the solution: Release and Debug. + +2. From the Project Menu, choose to edit your projects Properties. Or + right-click on the project in the Solution Explorer and choose Properties. + +To edit your new project's configuration properties, right click on the +project in the solution explorer pane and choose Properties. + +3. Change the "Configuration" (upper left of the dialog) menu to "All + Configurations". + +4. Click on the "General" section + + * Set "Output Files" to "C:\Program Files\MobileRobots\Aria\bin" + (Aria's bin directory, where Aria.dll etc. are). Or, if you want your + program saved in a different directory, you must put Aria's bin directory + in your system PATH environment variable, or copy the DLLs to your own + output directory. + + * You may want to change Intermediate Files. A useful value is + "obj\$(ConfigurationName)". + + * (Visual Studio 2003) Set "Use Managed Extensions" to "no". + + * (Visual C++ 2008) Set "Common Language Runtime Support" to "No Common + Language Runtime Support" + +5. Click on the "Link" or "Linker" section. + + * Click on the "Input" subsection. + + * To "Additional Library Path" add "C:\Program Files\MobileRobots\Aria\lib". + + * Change the "Configuration" menu (upper left of the window) to "Debug" + + * (Visual Studio 2003) To "Additional Dependencies", add: + AriaDebug.lib winmm.lib advapi32.lib + If you are using the ArNetworking library, also add: + ArNetworkingDebug.lib ws2_32.lib + + * (Visual C++ 2008) To "Additional Dependencies", add: + AriaDebugVC9.lib winmm.lib advapi32.lib + If you are using the ArNetworking library, also add: + ArNetworkingDebugVC9.lib ws2_32.lib + + * Change the "Configuration" menu to "Release" + + * (Visual Studio 2003) To "Additional Dependencies", add: + Aria.lib winmm.lib advapi32.lib + If you are using the ArNetworking library, also add: + ArNetworking.lib ws2_32.lib + + * (Visual C++ 2008) To "Additional Dependencies", add: + AriaVC9.lib winmm.lib advapi32.lib + If you are using the ArNetworking library, also add: + ArNetworkingVC9.lib ws2_32.lib + + * Change the "Configuration" menu (upper left of the window) to "Debug" + + * If using Visual Studio 2003, To "Additional Dependencies", add: + AriaDebug.lib winmm.lib advapi32.lib + If you are using the ArNetworking library, also add: + ArNetworkingDebug.lib ws2_32.lib + + * Or, if using Visual Studio 2008, To "Additional Dependencies", add: + AriaDebugVC9.lib winmm.lib advapi32.lib + If you are using the ArNetworking library, also add: + ArNetworkingDebugVC9.lib ws2_32.lib + + * Change the "Configuration" menu to "Release" + + * If using Visual Studio 2003, To "Additional Dependencies", add: + Aria.lib winmm.lib advapi32.lib + If you are using the ArNetworking library, also add: + ArNetworking.lib ws2_32.lib + + * Or, if using Visual Studio 2008, To "Additional Dependencies", add: + AriaVC9.lib winmm.lib advapi32.lib + If you are using the ArNetworking library, also add: + ArNetworkingVC9.lib ws2_32.lib + + * Change the "Configuration" menu back to "All Configurations" + +6. Click on the "C++" section. + + * Click on the "General" subsection + + * To "Additional Include Directories" add + "C:\Program Files\MobileRobots\Aria\include". + + * Click on the "Code Generation" subsection + + * Change the "Configuration" menu (upper left of the window) to "Debug". + + * Under the "Use run-time library" pulldown select "Debug + Multithreaded DLL". + + * Change the "Configuration" menu (upper left of the screen) to "Release". + + * Under the "Use run-time library" pulldown select "Multithreaded DLL". + + * Change the "Configuration" menu back to "All Configurations" + +Linux +----- + +On GNU/Linux two tools are used: the compiler (GCC), which compiles +and/or links a single file, and Make, which is used to manage +building multiple files and their dependencies. If you need to +deal with multiple files, you can copy a Makefile and modify it, +or create a new one. + +Note: In packages for Debian and Ubuntu, the shared libraries were built with the +standard G++ version provided with the system. You must use +the same version of G++ or a compatible version to build programs that +link against it, or rebuild ARIA using your preferrend G++ version. (On +Debian and Ubuntu systems, the default g++ and gcc compiler versions may be changed +using the 'galternatives' program or the 'update-alternatives' command). + +When compiling ARIA or its examples, you may also temporarily override the +C++ compiler command ('g++' by default) by setting the CXX environment +variable before or while running make. E.g.: "make CXX=g++-3.4" or +"export CXX=g++-3.4; make". + +More information and documentation about GCC is available at +, and in the gcc 'man' page. More information +about Make is at . Several graphical +IDE applications are available for use with GCC, though none are +currently supported by MobileRobots. + + + +### Using ARIA's Makefiles on Linux: ### + +The ARIA Makefile is able to build any program consisting +of one source code file in the 'examples', 'tests', or 'advanced' +directory. For example, if your source code file is +'examples/newProgram.cpp', then you can run 'make examples/newProgram' +from the top-level Aria directory, or 'make newProgram' from within +the 'examples' directory, to build it. This makes it easy to copy +one of the example programs to a new name and modify it -- a good way +to learn how to use ARIA. + + + +### Using ARIA from your own Makefile or other build system: ### + +If you want to keep your program in a different place than the Aria +examples directory, and use your own Makefile or other build tool, +you need to use the following g++ options to compile the program: + + -fPIC -I/usr/local/Aria/include + +If you wish, you may also use -g and -Wall for debugging information +and useful warnings. Aria does not use exceptions, so you may also +use -fno-exceptions if you wish; this will cause any use of exceptions +in your program to trigger a compile error. + +For linking with libAria use these options: + + -L/usr/local/Aria/lib -lAria -lpthread -ldl -lrt + +If you are also using ArNetworking, use the following compile option +in addition to the Aria options above: + + -I/usr/local/Aria/ArNetworking/include + +And for linking to libArNetworking: + + -lArNetworking + + +A Makefile for a program called "program" with source file "program.cpp" +might look something like this: + + + all: program + + CFLAGS=-fPIC -g -Wall + ARIA_INCLUDE=-I/usr/local/Aria/include + ARIA_LINK=-L/usr/local/Aria/lib -lAria -lpthread -ldl + + %: %.cpp + $(CXX) $(CFLAGS) $(ARIA_INCLUDE) $< -o $@ $(ARIA_LINK) + + +Refer to the GNU Make manual or +other books or documentation about Make to learn more. + + +### Setting variables for ARIA Makefiles ### + +You can add compile options to the following variables used in the ARIA +Makefiles, or replace default values. These can be set on the command +line when running `make`, for example: + + make CXX="g++-4.6" + +CXXFLAGS Additional compile flags passed to the C++ compiler. You + can add GCC options to enable profiling, optimizations, etc. + For example, to rebuild ARIA optimized for the Atom CPU + found in the LX/MTX embedded computer, add -mtune=atom and -O2: + make clean; make CXXFLAGS="-mtune=atom -O2" + These compiler flags will be used in addition to ARIA's + default flags. + +CXX Specify the C++ compiler command to use. The default is g++ or c++. + You can use this to use a different version of g++, or to give the + full path to g++, or to try a different compiler other than G++. + +JAVAC If rebuilding the Java wrapper library, this specifies the Java + compiler command to use. Default is "javac". + +JAR If rebuilding the Java wrapper library, this specifies the JAR + archiver command to use. Default is "jar". + +JAVA_BIN If rebuilding the Java wrapper library, this specifies a directory + containing JDK commands such as javac and jar. + +SWIG If rebuilding the Java and/or Python wrapper libraries, this + specifies the swig command used. Default is swig. + +PYTHON_INCLUDE + If rebuilding the Python wrapper library, this specifies the Python + include directory. Default is /usr/include/python2.5. You usually + need to specify this if building on a Linux other than Debian 5. + +INSTALL_DIR +SYSTEM_ETC_DIR + Directories used when installing ARIA from source with the + `make install` command. + +INSTALL How to run the `install` tool. Default is "install --preserve-timestamps" + + + +Learning more about using Linux: +-------------------------------- + +If you are new to using GNU/Linux, some guides on getting started can be +found at the following sites: + + * If your robot is using RedHat (it displays "RedHat Linux" on the console), + start with + . + More at . + + * If your robot is using Debian, start with + . More is at + . + + * If your robot is using Ubuntu 12.04, refer to + for documentation + and help. + + * is a repository of many different guides, FAQ and + HOWTO documents about Linux in general, including various programming + and system administration tasks. Note however that many details can + differ between Linux distributions and not all HOWTO documents will + be relevant to your distribution. + +For more depth, there are many books about using Linux, consult your +local computer bookseller. The ideal way to learn about Linux is to work +with an experienced colleague who can demonstrate things and answer +questions as they arise. + + + +Learning C++ +------------ + +If you are new to C++ programming, the definitive guide is Bjarne +Stroustrup's book "The C++ Programming Language". The book +"C++ In a Nutshell", published by O'Reilly & Associates, is a +good quick guide and reference. There are also several websites +and many other books about C++. + + +Using ARIA from Java or Python +============================== + +Even though ARIA was written in C++, it is possible to use ARIA from +the Java and Python programming languages as well. The directories +'python' and 'java' contain Python and Java packages automatically generated +by the 'swig' tool (http://www.swig.org) which mirror the ARIA API +closely, and are "wrappers" around the native ARIA library: When you call +an ARIA function in a Python or Java program, the wrapper re-marshalls the +function arguments and makes the equivalent call into the C++ ARIA library. +See the 'pythonExamples' and 'javaExamples' directories for more information +and example programs. See the ARIA API Reference Manual in 'docs' for +some more information. + +More about the Python programming language is at . +More about the Java programming language is at . + + +Using ARIA from Matlab or Simulink +================================== + +As of ARIA 2.8, it is possible to use a small but essential subset of ARIA features +from Matlab and Simulink. This is done via MEX functions and a +pure-C wrapper library called ariac. Matlab functions and Simulink +blocks are provided for essential robot operation such as velocity control, +receiving position estimate and other basic information. New functions +can be added to this interface using the already-implemented functions +as examples. + +See matlab/README.txt for details. + + + +MobileSim Simulator +=================== + +SRIsim is no longer included with Aria. There is now a seperately +downloadable MobileSim simulator at our support webpage +. MobileSim is compatible with SRISim, +but adds many new features. + + + + +------------------------- +Adept MobileRobots +10 Columbia Drive +Amherst, NH, 03031. USA + +support@mobilerobots.com +http://robots.mobilerobots.com +http://www.mobilerobots.com + + diff --git a/Legacy/Aria/advanced/Makefile b/Legacy/Aria/advanced/Makefile new file mode 100644 index 0000000..f6f02b0 --- /dev/null +++ b/Legacy/Aria/advanced/Makefile @@ -0,0 +1,32 @@ +# A simple $(MAKE)file to cause make to go look in the top directory. A simple +# convenience. + +%.so: %.cpp + $(MAKE) -C .. advanced/$@ + +%: %.cpp + $(MAKE) -C .. advanced/$@ + +all: + $(MAKE) -C .. advanced + +clean: + $(MAKE) -C .. cleanAdvanced + +# netAudioAndSpeech needs extra libraries: + +ifndef CXX +CXX=g++ +endif + +netAudioAndSpeech: netAudioAndSpeech.cpp ../lib/libArNetAudio.so ../lib/libArNetworking.so ../lib/libArSpeechSynth_Cepstral.so ../lib/libAria.so + $(CXX) $(CFLAGS) -o $@ -I../include -I../ArNetworking/include -I../ArNetAudio/include -I../ArSpeechSynth_Cepstral/include $< -L../lib -lArNetAudio -lArNetworking -lArSpeechSynth_Cepstral -lAria -lswift -lspeex -lportaudio -lportmixer + + +# Make dependent libraries. Assumes that lib is in sibling directory with +# matching name. +../lib/lib%.so: ../%/src/*.cpp ../%/include/*.h + $(MAKE) -C ../$* $@ + +../lib/libAria.so: + $(MAKE) -C .. lib/libAria.so diff --git a/Legacy/Aria/advanced/README.txt b/Legacy/Aria/advanced/README.txt new file mode 100644 index 0000000..2526ec3 --- /dev/null +++ b/Legacy/Aria/advanced/README.txt @@ -0,0 +1,30 @@ +This directory has various advanced demo applications, they are largely +undocumented, but do some cool things. It also contains some examples +using more obscure or less-used features or devices. +------------------------------------------------------------------------------- + +actsDemo - This one picks up a block (channel 2) and carrys it back and forth +between two placards (channels 1 and 3) + +actsDemoSimple - Like the above but it picks up a block (channel 2) and simply +takes it to a placard (channel 1) then stops + +condition - Example of how to use a condition variable (threading) + +joydriveUserControl - A normal joydrive program, but where control remains in +the users hands instead of ARIAs + +peoplebotDemo - Picks up a block (channel 2) from a table and takes it back +and forth between two placards also sitting on tables (channels 1 and 3) + +amptuDemo - Demo of the old AMPTU device. + +sickSpinLogger, sickSquareLogger, sickAutoLogger - Variations of the sickLogger +example that drive the robot automatically rather than using user joystick +operation. + +joydriveActionMod, joydriveActionModule - More examples of using ArModule to +load plugins at runtime. + +functorListsAndStdAlgorithms - using the STL functions with lists +of ArFunctor objects. diff --git a/Legacy/Aria/advanced/actsDemo.cpp b/Legacy/Aria/advanced/actsDemo.cpp new file mode 100644 index 0000000..976eaaf --- /dev/null +++ b/Legacy/Aria/advanced/actsDemo.cpp @@ -0,0 +1,1015 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#include "Aria.h" +class DriveTo : public ArAction +{ +public: + enum State { + STATE_START_LOOKING, + STATE_LOOKING, + STATE_FAILED, + STATE_SUCCEEDED + }; + DriveTo(ArACTS_1_2 *acts, ArGripper *gripper, ArSonyPTZ *sony); + ~DriveTo(void); + ArActionDesired *fire(ArActionDesired currentDesired); + bool setChannel(int channel); + State getState(void) { return myState; } + enum { + WIDTH = 160, + HEIGHT = 120 + }; +protected: + ArActionDesired myDesired; + ArACTS_1_2 *myActs; + ArGripper *myGripper; + ArSonyPTZ *mySony; + int myChannel; + bool myPickup; + State myState; + ArTime myLastSeen; +}; + +DriveTo::DriveTo(ArACTS_1_2 *acts, ArGripper *gripper, ArSonyPTZ *sony) : + ArAction("DriveTo", "Drives to something.") +{ + myActs = acts; + myGripper = gripper; + mySony = sony; + myChannel = 0; + myState = STATE_FAILED; + setChannel(1); +} + +DriveTo::~DriveTo(void) +{ + +} + +ArActionDesired *DriveTo::fire(ArActionDesired currentDesired) +{ + ArACTSBlob blob; + double xRel, yRel; + + if (myState == STATE_SUCCEEDED || myState == STATE_FAILED) + { + myDesired.setVel(0); + myDesired.setDeltaHeading(0); + return &myDesired; + } + + if (myState == STATE_START_LOOKING) + { + myState = STATE_LOOKING; + myLastSeen.setToNow(); + } + + if (myActs->getNumBlobs(myChannel) == 0 || + !myActs->getBlob(myChannel, 1, &blob)) + { + if (myLastSeen.mSecSince() > 1000) + { + printf("DriveTo: Lost the blob, failed.\n"); + myState = STATE_FAILED; + myDesired.setVel(0); + myDesired.setDeltaHeading(0); + return &myDesired; + } + } + else + { + myLastSeen.setToNow(); + } + + xRel = (double)(blob.getXCG() - WIDTH/2.0) / (double)WIDTH; + yRel = (double)(blob.getYCG() - HEIGHT/2.0) / (double)HEIGHT; + + //printf("xRel %.3f yRel %.3f\n", xRel, yRel); + + myDesired.reset(); + // this if the stuff we want to do if we're not going to just drive forward + // and home in on the color, ie the pickup-specific stuff + if (currentDesired.getMaxVelStrength() > 0 && + currentDesired.getMaxVel() < 125) + { + printf("DriveTo: Close to a wall of some sort, succeeded.\n"); + myState = STATE_SUCCEEDED; + myDesired.setVel(0); + myDesired.setDeltaHeading(0); + return &myDesired; + } + + if (ArMath::fabs(xRel) < .10) + { + //printf("Going straight ahead\n"); + myDesired.setDeltaHeading(0); + } + else + { + //printf("Turning %.2f\n", -xRel * 10); + myDesired.setDeltaHeading(-xRel * 10); + } + myDesired.setVel(300); + return &myDesired; +} + +bool DriveTo::setChannel(int channel) +{ + if (channel >= 1 && channel <= ArACTS_1_2::NUM_CHANNELS) + { + myChannel = channel; + myState = STATE_START_LOOKING; + return true; + } + else + return false; +} + + +class PickUp : public ArAction +{ +public: + enum State { + STATE_START_LOOKING, + STATE_LOOKING, + STATE_FAILED, + STATE_SUCCEEDED + }; + PickUp(ArACTS_1_2 *acts, ArGripper *gripper, ArSonyPTZ *sony); + ~PickUp(void); + ArActionDesired *fire(ArActionDesired currentDesired); + bool setChannel(int channel); + State getState(void) { return myState; } + enum { + WIDTH = 160, + HEIGHT = 120 + }; +protected: + ArActionDesired myDesired; + ArACTS_1_2 *myActs; + ArGripper *myGripper; + ArSonyPTZ *mySony; + int myChannel; + bool myPickup; + bool myTried; + bool myPointedDown; + State myState; + ArPose myLastPose; + ArTime myLastMoved; + ArTime myLastSeen; + ArTime mySentLiftDown; + ArTime myTriedStart; + bool myWaitingOnGripper; +}; + +PickUp::PickUp(ArACTS_1_2 *acts, ArGripper *gripper, ArSonyPTZ *sony) : + ArAction("PickUp", "Picks up something.") +{ + myActs = acts; + myGripper = gripper; + mySony = sony; + myChannel = 0; + myState = STATE_FAILED; +} + +PickUp::~PickUp(void) +{ + +} + +ArActionDesired *PickUp::fire(ArActionDesired currentDesired) +{ + ArPose pose; + ArACTSBlob blob; + bool blobSeen = false; + double xRel, yRel; + double dist; + + myDesired.reset(); + if (myState == STATE_SUCCEEDED) + { + //printf("PickUp: Succeeded\n"); + myDesired.setVel(0); + myDesired.setDeltaHeading(0); + return &myDesired; + } + else if (myState == STATE_FAILED) + { + //printf("PickUp: Failed\n"); + myDesired.setVel(0); + myDesired.setDeltaHeading(0); + return &myDesired; + } + + // this if the stuff we want to do if we're not going to just drive forward + // and home in on the color, ie the pickup-specific stuff + if (myState == STATE_START_LOOKING) + { + myGripper->gripOpen(); + ArUtil::sleep(3); + myGripper->liftDown(); + mySentLiftDown.setToNow(); + myPointedDown = false; + myState = STATE_LOOKING; + myLastSeen.setToNow(); + myTried = false; + myLastMoved.setToNow(); + myLastPose = myRobot->getPose(); + myWaitingOnGripper = true; + printf("@@@@@ Pickup: Lowering lift\n"); + } + + // we want to sit still until the lift is down or for a second and a half + if (myWaitingOnGripper) + { + if (mySentLiftDown.mSecSince() < 500 || + ((!myGripper->isLiftMaxed() || myGripper->getGripState() != 2) + && mySentLiftDown.mSecSince() < 5000)) + { + myGripper->liftDown(); + myGripper->gripOpen(); + myDesired.setVel(0); + myDesired.setDeltaHeading(0); + myLastMoved.setToNow(); + myLastPose = myRobot->getPose(); + return &myDesired; + } + else + { + myWaitingOnGripper = false; + } + myLastMoved.setToNow(); + myLastPose = myRobot->getPose(); + } + + if (myGripper->getBreakBeamState() != 0) + { + if (myGripper->getGripState() == 2) + { + printf("PickUp: Succeeded, have block.\n"); + myGripper->liftUp(); + myState = STATE_SUCCEEDED; + } + else if (!myTried) + { + myGripper->gripClose(); + printf("PickUp: Trying to pick up.\n"); + myTried = true; + myTriedStart.setToNow(); + } + myDesired.setVel(0); + myDesired.setDeltaHeading(0); + return &myDesired; + } + // this means that the grippers are closed, but we don't have anything in + // them, ie that we failed to get the block + else if (myTried && (myGripper->getGripState() == 2 || + myTriedStart.mSecSince() > 5000)) + { + myState = STATE_FAILED; + myGripper->gripOpen(); + ArUtil::sleep(3); + myGripper->liftUp(); + printf("PickUp: Grippers closed, didn't get a block, failed.\n"); + myDesired.setVel(0); + myDesired.setDeltaHeading(0); + return &myDesired; + } + + pose = myRobot->getPose(); + dist = myLastPose.findDistanceTo(pose); + if (dist < 5 && myLastMoved.mSecSince() > 1500) + { + printf("PickUp: Failed, no movement in the last 1500 msec.\n"); + myState = STATE_FAILED; + myGripper->gripOpen(); + myGripper->liftUp(); + myDesired.setVel(0); + myDesired.setDeltaHeading(0); + return &myDesired; + } + else if (dist > 5) + { + myLastMoved.setToNow(); + myLastPose = myRobot->getPose(); + } + + if (myActs->getNumBlobs(myChannel) == 0 || + !(blobSeen = myActs->getBlob(myChannel, 1, &blob))) + { + if (((!myPointedDown && myLastSeen.mSecSince() > 1500) || + (myPointedDown && myLastSeen.mSecSince() > 4000)) && + myGripper->getBreakBeamState() == 0) + { + printf("PickUp: Lost the blob, failed, last saw it %ld msec ago.\n", + myLastSeen.mSecSince()); + myState = STATE_FAILED; + myGripper->gripOpen(); + ArUtil::sleep(3); + myGripper->liftUp(); + myDesired.setVel(0); + myDesired.setDeltaHeading(0); + return &myDesired; + } + } + else + myLastSeen.setToNow(); + + + if (blobSeen) + { + xRel = (double)(blob.getXCG() - WIDTH/2.0) / (double)WIDTH; + yRel = (double)(blob.getYCG() - HEIGHT/2.0) / (double)HEIGHT; + //printf("xRel %.3f yRel %.3f:\n", xRel, yRel); + } + else + { + //printf("No blob: "); + } + + if (blobSeen && yRel < 0.2 && !myPointedDown) + { + printf("PickUp: Pointing the camera down!!!\n"); + mySony->panTilt(0, -ArSonyPTZ::MAX_TILT); + myPointedDown = true; + } + + + if (!blobSeen || ArMath::fabs(xRel) < .10) + { + //printf("Going straight ahead\n"); + myDesired.setDeltaHeading(0); + } + else + { + //printf("Turning %.2f\n", -xRel * 10); + if (ArMath::fabs(-xRel * 10) <= 10) + myDesired.setDeltaHeading(-xRel * 10); + else if (-xRel > 0) + myDesired.setDeltaHeading(10); + else + myDesired.setDeltaHeading(-10); + } + myDesired.setVel(150); + return &myDesired; +} + +bool PickUp::setChannel(int channel) +{ + if (channel >= 1 && channel <= ArACTS_1_2::NUM_CHANNELS) + { + myChannel = channel; + myState = STATE_START_LOOKING; + return true; + } + else + return false; +} + +class Acquire : public ArAction +{ +public: + enum State { + STATE_START_LOOKING, + STATE_LOOKING, + STATE_FAILED, + STATE_SUCCEEDED + }; + Acquire(ArACTS_1_2 *acts, ArGripper *gripper); + virtual ~Acquire(void); + ArActionDesired *fire(ArActionDesired currentDesired); + bool setChannel(int channel); + State getState(void) { return myState; } +protected: + State myState; + int myChannel; + ArSectors myFirstTurn; + ArSectors mySecondTurn; + ArActionDesired myDesired; + ArACTS_1_2 *myActs; + ArGripper *myGripper; + ArTime myStartUp; + bool myTryingGripper; +}; + +Acquire::Acquire(ArACTS_1_2 *acts, ArGripper *gripper) : + ArAction("Acquire", "Turns until it can find the given channel, gives up after 1 revolution") +{ + myActs = acts; + myGripper = gripper; + myState = STATE_FAILED; +} + +Acquire::~Acquire(void) +{ +} + +ArActionDesired *Acquire::fire(ArActionDesired currentDesired) +{ + myDesired.reset(); + myDesired.setVel(0); + switch (myState) { + case STATE_START_LOOKING: + myFirstTurn.clear(); + mySecondTurn.clear(); + myState = STATE_LOOKING; + myGripper->liftUp(); + myGripper->gripClose(); + printf("Acquire: Raising lift\n"); + myStartUp.setToNow(); + myTryingGripper = true; + case STATE_LOOKING: + if (myTryingGripper && (myStartUp.mSecSince() < 600 || + ((!myGripper->isLiftMaxed() || + myGripper->getGripState() != 2) && + myStartUp.mSecSince() < 5000))) + { + myGripper->liftUp(); + myGripper->gripClose(); + myDesired.setVel(0); + myDesired.setDeltaHeading(0); + return &myDesired; + } + else if (myTryingGripper) + { + printf("Acquire: Done raising lift %ld after started.\n", + myStartUp.mSecSince()); + myTryingGripper = false; + } + if (myActs->getNumBlobs(myChannel) > 0) + { + myDesired.setDeltaHeading(0); + myState = STATE_SUCCEEDED; + printf("Acquire: Succeeded!\n"); + } + else if (myFirstTurn.didAll() && mySecondTurn.didAll()) + { + myDesired.setDeltaHeading(0); + myState = STATE_FAILED; + printf("Acquire: Did two revolutions, didn't see the blob, Failed!\n"); + } + else + { + myFirstTurn.update(myRobot->getTh()); + if (myFirstTurn.didAll()) + mySecondTurn.update(myRobot->getTh()); + myDesired.setDeltaHeading(8); + } + return &myDesired; + default: + myDesired.setVel(0); + myDesired.setDeltaHeading(0); + return &myDesired; + } +} + +bool Acquire::setChannel(int channel) +{ + if (channel >= 1 && channel <= ArACTS_1_2::NUM_CHANNELS) + { + myChannel = channel; + myState = STATE_START_LOOKING; + return true; + } + else + return false; +} + +class TakeBlockToWall +{ +public: + enum State { + STATE_START, + STATE_ACQUIRE_BLOCK, + STATE_PICKUP_BLOCK, + STATE_BACKUP, + STATE_ACQUIRE_BLOCK2, + STATE_PICKUP_BLOCK2, + STATE_ACQUIRE_DROP_WALL, + STATE_DRIVETO_DROP_WALL, + STATE_DROP, + STATE_DROP_BACKUP, + STATE_ACQUIRE_LAP_WALL, + STATE_DRIVETO_LAP_WALL, + STATE_SWITCH, + STATE_FAILED + }; + TakeBlockToWall(ArRobot *robot, ArGripper *gripper, ArSonyPTZ *sony, + Acquire *acquire, DriveTo *driveTo, PickUp *pickup, + ArActionConstantVelocity *backup); + ~TakeBlockToWall(void); + void handler(void); + void setState(State state) + { myState = state; myNewState = true; myStateStart.setToNow(); } + enum Color { + COLOR_FIRST_WALL = 1, + COLOR_SECOND_WALL = 3, + COLOR_BLOCK = 2 + }; + +protected: + ArTime myStateStart; + ArRobot *myRobot; + ArFunctorC myHandlerCB; + ArGripper *myGripper; + ArSonyPTZ *mySony; + Acquire *myAcquire; + DriveTo *myDriveTo; + PickUp *myPickUp; + ArActionConstantVelocity *myBackup; + State myState; + Color myDropWall; + Color myLapWall; + bool myNewState; + bool myGripOpenSent; +}; + +TakeBlockToWall::TakeBlockToWall(ArRobot *robot, ArGripper *gripper, + ArSonyPTZ *sony, Acquire *acquire, + DriveTo *driveTo, PickUp *pickUp, + ArActionConstantVelocity *backup) : + myHandlerCB(this, &TakeBlockToWall::handler) +{ + myRobot = robot; + myRobot->addUserTask("TakeBlockToWall", 75, &myHandlerCB); + myGripper = gripper; + myAcquire = acquire; + myDriveTo = driveTo; + myPickUp = pickUp; + mySony = sony; + myBackup = backup; + myState = STATE_START; + myNewState = true; +} + +TakeBlockToWall::~TakeBlockToWall(void) +{ +} + +void TakeBlockToWall::handler(void) +{ + Color tempColor; + + switch (myState) + { + case STATE_START: + setState(STATE_ACQUIRE_BLOCK); + myDropWall = COLOR_FIRST_WALL; + myLapWall = COLOR_SECOND_WALL; + printf("!! Started state handling!\n"); + //handler(); + return; + break; + case STATE_ACQUIRE_BLOCK: + if (myNewState) + { + printf("!! Acquire block\n"); + myNewState = false; + mySony->panTilt(0, -10); + myAcquire->activate(); + myAcquire->setChannel(COLOR_BLOCK); + myPickUp->deactivate(); + myDriveTo->deactivate(); + myBackup->deactivate(); + } + if (myGripper->getGripState() == 2 && + myGripper->getBreakBeamState() != 0) + { + printf("###### AcquireBlock: Successful (have cube?)\n"); + setState(STATE_ACQUIRE_DROP_WALL); + //handler(); + return; + } + else if (myGripper->getBreakBeamState() != 0) + { + printf("###### AcquireBlock: Successful (cube in gripper?)\n"); + setState(STATE_PICKUP_BLOCK); + //handler(); + return; + } + if (myAcquire->getState() == Acquire::STATE_FAILED || + myStateStart.mSecSince() > 35000) + { + printf("###### AcqiureBlock: failed\n"); + setState(STATE_BACKUP); + //handler(); + return; + } + else if (myAcquire->getState() == Acquire::STATE_SUCCEEDED) + { + printf("###### AcquireBlock: successful\n"); + setState(STATE_PICKUP_BLOCK); + //handler(); + return; + } + break; + case STATE_PICKUP_BLOCK: + if (myNewState) + { + printf("!! Pickup block\n"); + myNewState = false; + mySony->panTilt(0, -15); + myAcquire->deactivate(); + myPickUp->activate(); + myPickUp->setChannel(COLOR_BLOCK); + myDriveTo->deactivate(); + myBackup->deactivate(); + } + if (myPickUp->getState() == PickUp::STATE_FAILED) + { + printf("###### PickUpBlock: failed\n"); + setState(STATE_BACKUP); + //handler(); + return; + } + else if (myPickUp->getState() == PickUp::STATE_SUCCEEDED) + { + printf("###### PickUpBlock: successful\n"); + setState(STATE_ACQUIRE_DROP_WALL); + //handler(); + return; + } + break; + case STATE_BACKUP: + if (myNewState) + { + printf("!! Backup\n"); + myAcquire->deactivate(); + myPickUp->deactivate(); + myDriveTo->deactivate(); + myBackup->activate(); + myNewState = false; + } + if (myStateStart.mSecSince() > 2000) + { + printf("###### Backup: done\n"); + setState(STATE_ACQUIRE_BLOCK2); + //handler(); + return; + } + break; + case STATE_ACQUIRE_BLOCK2: + if (myNewState) + { + printf("!! Acquire block 2\n"); + myNewState = false; + mySony->panTilt(0, -25); + myAcquire->activate(); + myAcquire->setChannel(COLOR_BLOCK); + myPickUp->deactivate(); + myDriveTo->deactivate(); + myBackup->deactivate(); + } + if (myGripper->getGripState() == 2 && + myGripper->getBreakBeamState() != 0) + { + printf("###### AcquireBlock2: Successful (have cube?)\n"); + setState(STATE_ACQUIRE_DROP_WALL); + //handler(); + return; + } + else if (myGripper->getBreakBeamState() != 0) + { + printf("###### AcquireBlock2: Successful (cube in gripper?)\n"); + setState(STATE_PICKUP_BLOCK2); + //handler(); + return; + } + if (myAcquire->getState() == Acquire::STATE_FAILED || + myStateStart.mSecSince() > 35000) + { + printf("###### AcqiureBlock2: failed\n"); + setState(STATE_FAILED); + //handler(); + return; + } + else if (myAcquire->getState() == Acquire::STATE_SUCCEEDED) + { + printf("###### AcquireBlock2: successful\n"); + setState(STATE_PICKUP_BLOCK2); + //handler(); + return; + } + break; + case STATE_PICKUP_BLOCK2: + if (myNewState) + { + printf("!! Pickup block 2\n"); + myNewState = false; + myAcquire->deactivate(); + myPickUp->activate(); + mySony->panTilt(0, -25); + myPickUp->setChannel(COLOR_BLOCK); + myDriveTo->deactivate(); + myBackup->deactivate(); + } + if (myPickUp->getState() == PickUp::STATE_FAILED) + { + printf("###### PickUpBlock2: failed\n"); + setState(STATE_FAILED); + //handler(); + return; + } + else if (myPickUp->getState() == PickUp::STATE_SUCCEEDED) + { + printf("###### PickUpBlock2: successful\n"); + setState(STATE_ACQUIRE_DROP_WALL); + //handler(); + return; + } + break; + case STATE_ACQUIRE_DROP_WALL: + if (myNewState) + { + printf("!! Acquire Drop wall, channel %d\n", myDropWall); + myNewState = false; + mySony->panTilt(0, -5); + myAcquire->activate(); + myAcquire->setChannel(myDropWall); + myPickUp->deactivate(); + myDriveTo->deactivate(); + myBackup->deactivate(); + } + if (myGripper->getGripState() != 2 || + myGripper->getBreakBeamState() == 0) + { + printf("###### AcquireDropWall:: failed (lost cube)\n"); + setState(STATE_BACKUP); + //handler(); + return; + } + if (myAcquire->getState() == Acquire::STATE_FAILED || + myStateStart.mSecSince() > 35000) + { + printf("###### AcquireDropWall:: failed\n"); + setState(STATE_FAILED); + //handler(); + return; + } + else if (myAcquire->getState() == Acquire::STATE_SUCCEEDED) + { + printf("###### AcquireDropWall: successful\n"); + setState(STATE_DRIVETO_DROP_WALL); + //handler(); + return; + } + break; + case STATE_DRIVETO_DROP_WALL: + if (myNewState) + { + printf("!! Driveto Drop wall, channel %d\n", myDropWall); + myNewState = false; + myAcquire->deactivate(); + myPickUp->deactivate(); + myDriveTo->activate(); + myDriveTo->setChannel(myDropWall); + myBackup->deactivate(); + } + if (myGripper->getGripState() != 2 || + myGripper->getBreakBeamState() == 0) + { + printf("###### DriveToDropWall:: failed (lost cube)\n"); + setState(STATE_BACKUP); + //handler(); + return; + } + if (myDriveTo->getState() == DriveTo::STATE_FAILED) + { + printf("###### DriveToDropWall: failed\n"); + setState(STATE_FAILED); + //handler(); + return; + } + else if (myDriveTo->getState() == DriveTo::STATE_SUCCEEDED) + { + printf("###### DriveToDropWall: succesful\n"); + setState(STATE_DROP); + //handler(); + return; + } + break; + case STATE_DROP: + if (myNewState) + { + printf("!! Drop\n"); + printf("@@@@@ Drop lowering lift\n"); + myGripper->liftDown(); + myNewState = false; + myAcquire->deactivate(); + myPickUp->deactivate(); + myDriveTo->deactivate(); + myBackup->deactivate(); + myGripOpenSent = false; + } + + myGripper->liftDown(); + if ((myStateStart.mSecSince() > 500 && + myGripper->isLiftMaxed() && myStateStart.mSecSince() < 5000) || + myStateStart.mSecSince() > 5000) + { + myGripper->gripOpen(); + /*if (!myGripOpenSent) + { + ArUtil::sleep(3); + myGripper->gripOpen(); + } + myGripOpenSent = true; + */ + } + if (myGripper->getGripState() == 1 || myStateStart.mSecSince() > 6000) + { + printf("###### Drop: success\n"); + setState(STATE_DROP_BACKUP); + //handler(); + return; + } + break; + case STATE_DROP_BACKUP: + if (myNewState) + { + printf("!! Drop backup\n"); + myAcquire->deactivate(); + myPickUp->deactivate(); + myDriveTo->deactivate(); + myBackup->activate(); + myNewState = false; + } + if (myStateStart.mSecSince() > 2000) + { + printf("###### Drop_Backup: done\n"); + setState(STATE_ACQUIRE_LAP_WALL); + //handler(); + return; + } + break; + case STATE_ACQUIRE_LAP_WALL: + if (myNewState) + { + printf("!! Acquire Lap wall, channel %d\n", myLapWall); + myNewState = false; + mySony->panTilt(0, -5); + myAcquire->activate(); + myAcquire->setChannel(myLapWall); + myPickUp->deactivate(); + myDriveTo->deactivate(); + myBackup->deactivate(); + } + if (myAcquire->getState() == Acquire::STATE_FAILED || + myStateStart.mSecSince() > 35000) + { + printf("###### AcquireLapWall:: failed\n"); + setState(STATE_SWITCH); + //handler(); + return; + } + else if (myAcquire->getState() == Acquire::STATE_SUCCEEDED) + { + printf("###### AcquireLapWall: successful\n"); + setState(STATE_DRIVETO_LAP_WALL); + //handler(); + return; + } + break; + case STATE_DRIVETO_LAP_WALL: + if (myNewState) + { + printf("!! Driveto Lap wall, channel %d\n", myLapWall); + myNewState = false; + myAcquire->deactivate(); + myPickUp->deactivate(); + myDriveTo->activate(); + myDriveTo->setChannel(myLapWall); + myBackup->deactivate(); + } + if (myDriveTo->getState() == DriveTo::STATE_FAILED) + { + printf("###### DriveToLapWall: failed\n"); + setState(STATE_SWITCH); + //handler(); + return; + } + else if (myDriveTo->getState() == DriveTo::STATE_SUCCEEDED) + { + printf("###### DriveToLapWall: succesful\n"); + setState(STATE_SWITCH); + //handler(); + return; + } + break; + case STATE_SWITCH: + printf("!! Switching walls around.\n"); + tempColor = myDropWall; + myDropWall = myLapWall; + myLapWall = tempColor; + setState(STATE_ACQUIRE_BLOCK); + //handler(); + return; + case STATE_FAILED: + printf("@@@@@ Failed to complete the task!\n"); + myRobot->comInt(ArCommands::SONAR, 0); + ArUtil::sleep(50); + myRobot->comStr(ArCommands::SAY, "\52\77\37\62\42\70"); + ArUtil::sleep(500); + Aria::shutdown(); + myRobot->disconnect(); + myRobot->stopRunning(); + return; + } + +} + +int main(void) +{ + ArSerialConnection con; + ArRobot robot; + int ret; + std::string str; + ArActionLimiterForwards limiter("speed limiter near", 300, 600, 250); + ArActionLimiterForwards limiterFar("speed limiter far", 300, 1100, 400); + ArActionLimiterBackwards backwardsLimiter; + ArActionConstantVelocity stop("stop", 0); + ArActionConstantVelocity backup("backup", -200); + ArSonarDevice sonar; + ArACTS_1_2 acts; + ArSonyPTZ sony(&robot); + ArGripper gripper(&robot, ArGripper::GENIO); + + Acquire acq(&acts, &gripper); + DriveTo driveTo(&acts, &gripper, &sony); + PickUp pickUp(&acts, &gripper, &sony); + + TakeBlockToWall takeBlock(&robot, &gripper, &sony, &acq, &driveTo, &pickUp, + &backup); + + Aria::init(); + + if (!acts.openPort(&robot)) + { + printf("Could not connect to acts\n"); + exit(1); + } + + robot.addRangeDevice(&sonar); + //con.setBaud(38400); + if ((ret = con.open()) != 0) + { + str = con.getOpenMessage(ret); + printf("Open failed: %s\n", str.c_str()); + Aria::shutdown(); + return 1; + } + + robot.setDeviceConnection(&con); + if (!robot.blockingConnect()) + { + printf("Could not connect to robot... exiting\n"); + Aria::shutdown(); + return 1; + } + + sony.init(); + ArUtil::sleep(1000); + //robot.setAbsoluteMaxTransVel(400); + + robot.setStateReflectionRefreshTime(250); + robot.comInt(ArCommands::ENABLE, 1); + robot.comInt(ArCommands::SOUNDTOG, 0); + + ArUtil::sleep(200); + robot.addAction(&limiter, 100); + robot.addAction(&limiterFar, 99); + robot.addAction(&backwardsLimiter, 98); + robot.addAction(&acq, 77); + robot.addAction(&driveTo, 76); + robot.addAction(&pickUp, 75); + robot.addAction(&backup, 50); + robot.addAction(&stop, 30); + + robot.run(true); + + Aria::shutdown(); + return 0; +} diff --git a/Legacy/Aria/advanced/actsDemoSimple.cpp b/Legacy/Aria/advanced/actsDemoSimple.cpp new file mode 100644 index 0000000..5b8d160 --- /dev/null +++ b/Legacy/Aria/advanced/actsDemoSimple.cpp @@ -0,0 +1,751 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#include "Aria.h" + +class DriveTo : public ArAction +{ +public: + enum State { + STATE_START_LOOKING, + STATE_LOOKING, + STATE_FAILED, + STATE_SUCCEEDED + }; + DriveTo(ArACTS_1_2 *acts, ArGripper *gripper, ArSonyPTZ *sony); + ~DriveTo(void); + ArActionDesired *fire(ArActionDesired currentDesired); + bool setChannel(int channel); + State getState(void) { return myState; } + enum { + WIDTH = 160, + HEIGHT = 120 + }; +protected: + ArActionDesired myDesired; + ArACTS_1_2 *myActs; + ArGripper *myGripper; + ArSonyPTZ *mySony; + int myChannel; + bool myPickup; + State myState; + ArTime myLastSeen; +}; + +DriveTo::DriveTo(ArACTS_1_2 *acts, ArGripper *gripper, ArSonyPTZ *sony) : + ArAction("DriveTo", "Drives to something.") +{ + myActs = acts; + myGripper = gripper; + mySony = sony; + myChannel = 0; + myState = STATE_FAILED; + setChannel(1); +} + +DriveTo::~DriveTo(void) +{ + +} + +ArActionDesired *DriveTo::fire(ArActionDesired currentDesired) +{ + ArACTSBlob blob; + double xRel, yRel; + + if (myState == STATE_START_LOOKING) + { + myGripper->gripClose(); + myGripper->liftUp(); + mySony->panTilt(0, -5); + myState = STATE_LOOKING; + myLastSeen.setToNow(); + } + + if (myActs->getNumBlobs(myChannel) == 0 || + !myActs->getBlob(myChannel, 1, &blob)) + { + if (myLastSeen.mSecSince() > 1000) + { + printf("DriveTo: Lost the blob, failed.\n"); + myState = STATE_FAILED; + return NULL; + } + } + else + { + myLastSeen.setToNow(); + } + + if (myState == STATE_SUCCEEDED || myState == STATE_FAILED) + { + return NULL; + } + + xRel = (double)(blob.getXCG() - WIDTH/2.0) / (double)WIDTH; + yRel = (double)(blob.getYCG() - HEIGHT/2.0) / (double)HEIGHT; + + //printf("xRel %.3f yRel %.3f\n", xRel, yRel); + + myDesired.reset(); + // this if the stuff we want to do if we're not going to just drive forward + // and home in on the color, ie the pickup-specific stuff + if (currentDesired.getMaxVelStrength() > 0 && + currentDesired.getMaxVel() < 50) + { + printf("DriveTo: Close to a wall of some sort, succeeded.\n"); + myState = STATE_SUCCEEDED; + myDesired.setVel(0); + myDesired.setDeltaHeading(0); + return &myDesired; + } + + if (ArMath::fabs(xRel) < .10) + { + //printf("Going straight ahead\n"); + myDesired.setDeltaHeading(0); + } + else + { + //printf("Turning %.2f\n", -xRel * 10); + myDesired.setDeltaHeading(-xRel * 10); + } + myDesired.setVel(300); + return &myDesired; +} + +bool DriveTo::setChannel(int channel) +{ + if (channel >= 1 && channel <= ArACTS_1_2::NUM_CHANNELS) + { + myChannel = channel; + myState = STATE_START_LOOKING; + return true; + } + else + return false; +} + + +class PickUp : public ArAction +{ +public: + enum State { + STATE_START_LOOKING, + STATE_LOOKING, + STATE_FAILED, + STATE_SUCCEEDED + }; + PickUp(ArACTS_1_2 *acts, ArGripper *gripper, ArSonyPTZ *sony); + ~PickUp(void); + ArActionDesired *fire(ArActionDesired currentDesired); + bool setChannel(int channel); + State getState(void) { return myState; } + enum { + WIDTH = 160, + HEIGHT = 120 + }; +protected: + ArActionDesired myDesired; + ArACTS_1_2 *myActs; + ArGripper *myGripper; + ArSonyPTZ *mySony; + int myChannel; + bool myPickup; + bool myTried; + bool myPointedDown; + State myState; + ArPose myLastPose; + ArTime myLastMoved; + ArTime myLastSeen; + ArTime mySentLiftDown; +}; + +PickUp::PickUp(ArACTS_1_2 *acts, ArGripper *gripper, ArSonyPTZ *sony) : + ArAction("PickUp", "Picks up something.") +{ + myActs = acts; + myGripper = gripper; + mySony = sony; + myChannel = 0; + myState = STATE_FAILED; +} + +PickUp::~PickUp(void) +{ + +} + +ArActionDesired *PickUp::fire(ArActionDesired currentDesired) +{ + ArPose pose; + ArACTSBlob blob; + bool blobSeen = false; + double xRel, yRel; + double dist; + + // this if the stuff we want to do if we're not going to just drive forward + // and home in on the color, ie the pickup-specific stuff + if (myState == STATE_START_LOOKING) + { + myGripper->gripOpen(); + myGripper->liftDown(); + mySentLiftDown.setToNow(); + mySony->panTilt(0, -15); + myPointedDown = false; + myState = STATE_LOOKING; + myLastSeen.setToNow(); + myTried = false; + myLastMoved.setToNow(); + myLastPose = myRobot->getPose(); + } + + // we want to sit still until the lift is down or for a second and a half + if (!((mySentLiftDown.mSecSince() > 200 && myGripper->isLiftMaxed()) || + mySentLiftDown.mSecSince() > 1500)) + { + myDesired.setVel(0); + myDesired.setDeltaHeading(0); + myLastMoved.setToNow(); + return &myDesired; + } + + + if (myState == STATE_SUCCEEDED) + { + //printf("PickUp: Succeeded\n"); + return NULL; + } + else if (myState == STATE_FAILED) + { + //printf("PickUp: Failed\n"); + return NULL; + } + + pose = myRobot->getPose(); + dist = myLastPose.findDistanceTo(pose); + if (dist < 10 && myLastMoved.mSecSince() > 1500) + { + printf("PickUp: Failed, no movement in the last 1500 msec.\n"); + myState = STATE_FAILED; + return NULL; + } + else if (dist > 10) + { + myLastMoved.setToNow(); + } + + if (myActs->getNumBlobs(myChannel) == 0 || + !(blobSeen = myActs->getBlob(myChannel, 1, &blob))) + { + if (((!myPointedDown && myLastSeen.mSecSince() > 1500) || + (myPointedDown && myLastSeen.mSecSince() > 4000)) && + myGripper->getBreakBeamState() == 0) + { + printf("PickUp: Lost the blob, failed, last saw it %ld msec ago.\n", + myLastSeen.mSecSince()); + myState = STATE_FAILED; + return NULL; + } + } + else + myLastSeen.setToNow(); + + + if (blobSeen) + { + xRel = (double)(blob.getXCG() - WIDTH/2.0) / (double)WIDTH; + yRel = (double)(blob.getYCG() - HEIGHT/2.0) / (double)HEIGHT; + //printf("xRel %.3f yRel %.3f:\n", xRel, yRel); + } + else + { + //printf("No blob: "); + } + + myDesired.reset(); + if (myGripper->getBreakBeamState() != 0) + { + if (myGripper->getGripState() == 2) + { + printf("PickUp: Succeeded, have block.\n"); + myState = STATE_SUCCEEDED; + } + else if (!myTried) + { + myGripper->gripClose(); + printf("PickUp: Trying to pick up.\n"); + myTried = true; + } + myDesired.setVel(0); + myDesired.setDeltaHeading(0); + return &myDesired; + } + // this means that the grippers are closed, but we don't have anything in + // them, ie that we failed to get the block + else if (myTried && myGripper->getGripState() == 2) + { + myState = STATE_FAILED; + printf("PickUp: Grippers closed, didn't get a block, failed.\n"); + return NULL; + } + + if (blobSeen && yRel < 0.2 && !myPointedDown) + { + printf("PickUp: Pointing the camera down!!!\n"); + mySony->panTilt(0, -ArSonyPTZ::MAX_TILT); + myPointedDown = true; + } + + + if (!blobSeen || ArMath::fabs(xRel) < .10) + { + //printf("Going straight ahead\n"); + myDesired.setDeltaHeading(0); + } + else + { + //printf("Turning %.2f\n", -xRel * 10); + myDesired.setDeltaHeading(-xRel * 10); + } + myDesired.setVel(150); + return &myDesired; +} + +bool PickUp::setChannel(int channel) +{ + if (channel >= 1 && channel <= ArACTS_1_2::NUM_CHANNELS) + { + myChannel = channel; + myState = STATE_START_LOOKING; + return true; + } + else + return false; +} + +class Acquire : public ArAction +{ +public: + enum State { + STATE_START_LOOKING, + STATE_LOOKING, + STATE_FAILED, + STATE_SUCCEEDED + }; + Acquire(ArACTS_1_2 *acts); + virtual ~Acquire(void); + ArActionDesired *fire(ArActionDesired currentDesired); + bool setChannel(int channel); + State getState(void) { return myState; } +protected: + State myState; + int myChannel; + int myStartAngle; + ArSectors myFirstTurn; + ArSectors mySecondTurn; + ArActionDesired myDesired; + ArACTS_1_2 *myActs; +}; + +Acquire::Acquire(ArACTS_1_2 *acts) : + ArAction("Acquire", "Turns until it can find the given channel, gives up after 1 revolution") +{ + myActs = acts; + myState = STATE_FAILED; +} + +Acquire::~Acquire(void) +{ +} + +ArActionDesired *Acquire::fire(ArActionDesired currentDesired) +{ + myDesired.reset(); + switch (myState) { + case STATE_START_LOOKING: + myFirstTurn.clear(); + mySecondTurn.clear(); + myState = STATE_LOOKING; + case STATE_LOOKING: + if (myActs->getNumBlobs(myChannel) > 0) + { + myDesired.setDeltaHeading(0); + myState = STATE_SUCCEEDED; + printf("Acquire: Succeeded!\n"); + } + else if (myFirstTurn.didAll() && mySecondTurn.didAll()) + { + myDesired.setDeltaHeading(0); + myState = STATE_FAILED; + printf("Acquire: Did two revolutions, didn't see the blob, Failed!\n"); + } + else + { + myFirstTurn.update(myRobot->getTh()); + if (myFirstTurn.didAll()) + mySecondTurn.update(myRobot->getTh()); + myDesired.setDeltaHeading(8); + } + return &myDesired; + default: + return NULL; + } +} + +bool Acquire::setChannel(int channel) +{ + if (channel >= 1 && channel <= ArACTS_1_2::NUM_CHANNELS) + { + myChannel = channel; + myState = STATE_START_LOOKING; + return true; + } + else + return false; +} + +class TakeBlockToWall +{ +public: + enum State { + STATE_START, + STATE_ACQUIRE_BLOCK, + STATE_PICKUP_BLOCK, + STATE_BACKUP, + STATE_PICKUP_BLOCK2, + STATE_ACQUIRE_WALL, + STATE_DRIVETO_WALL, + STATE_DROP, + STATE_SUCCEEDED, + STATE_FAILED + }; + TakeBlockToWall(ArRobot *robot, ArGripper *gripper, ArSonyPTZ *sony, + Acquire *acquire, DriveTo *driveTo, PickUp *pickup, + ArActionConstantVelocity *backup); + ~TakeBlockToWall(void); + void handler(void); + void setState(State state) + { myState = state; myNewState = true; myStateStart.setToNow(); } + enum { + COLOR_FIRST_WALL = 1, + COLOR_SECOND_WALL = 3, + COLOR_BLOCK = 2 + }; + +protected: + ArTime myStateStart; + ArRobot *myRobot; + ArFunctorC myHandlerCB; + ArGripper *myGripper; + ArSonyPTZ *mySony; + Acquire *myAcquire; + DriveTo *myDriveTo; + PickUp *myPickUp; + ArActionConstantVelocity *myBackup; + State myState; + bool myNewState; +}; + +TakeBlockToWall::TakeBlockToWall(ArRobot *robot, ArGripper *gripper, + ArSonyPTZ *sony, Acquire *acquire, + DriveTo *driveTo, PickUp *pickUp, + ArActionConstantVelocity *backup) : + myHandlerCB(this, &TakeBlockToWall::handler) +{ + myRobot = robot; + myRobot->addUserTask("TakeBlockToWall", 75, &myHandlerCB); + myGripper = gripper; + myAcquire = acquire; + myDriveTo = driveTo; + myPickUp = pickUp; + mySony = sony; + myBackup = backup; + myState = STATE_START; + myNewState = true; +} + +TakeBlockToWall::~TakeBlockToWall(void) +{ +} + +void TakeBlockToWall::handler(void) +{ + switch (myState) + { + case STATE_START: + setState(STATE_ACQUIRE_BLOCK); + printf("Started state handling!\n"); + handler(); + return; + break; + case STATE_ACQUIRE_BLOCK: + if (myNewState) + { + myNewState = false; + mySony->panTilt(0, -10); + myAcquire->activate(); + myAcquire->setChannel(COLOR_BLOCK); + myPickUp->deactivate(); + myDriveTo->deactivate(); + myBackup->deactivate(); + } + if (myAcquire->getState() == Acquire::STATE_FAILED) + { + printf("## AcqiureBlock: failed\n"); + setState(STATE_FAILED); + handler(); + return; + } + else if (myAcquire->getState() == Acquire::STATE_SUCCEEDED) + { + printf("## AcquireBlock: successful\n"); + setState(STATE_PICKUP_BLOCK); + handler(); + return; + } + break; + case STATE_PICKUP_BLOCK: + if (myNewState) + { + myNewState = false; + myAcquire->deactivate(); + myPickUp->activate(); + myPickUp->setChannel(COLOR_BLOCK); + myDriveTo->deactivate(); + myBackup->deactivate(); + } + if (myPickUp->getState() == PickUp::STATE_FAILED) + { + printf("## PickUpBlock: failed\n"); + setState(STATE_BACKUP); + handler(); + return; + } + else if (myPickUp->getState() == PickUp::STATE_SUCCEEDED) + { + printf("## PickUpBlock: successful\n"); + setState(STATE_ACQUIRE_WALL); + myGripper->liftUp(); + handler(); + return; + } + break; + case STATE_BACKUP: + if (myNewState) + { + myAcquire->deactivate(); + myPickUp->deactivate(); + myDriveTo->deactivate(); + myBackup->activate(); + } + if (myStateStart.mSecSince() > 2000) + { + printf("## Backup: done\n"); + setState(STATE_PICKUP_BLOCK2); + handler(); + return; + } + break; + case STATE_PICKUP_BLOCK2: + if (myNewState) + { + myNewState = false; + myAcquire->deactivate(); + myPickUp->activate(); + myPickUp->setChannel(COLOR_BLOCK); + myDriveTo->deactivate(); + myBackup->deactivate(); + } + if (myPickUp->getState() == PickUp::STATE_FAILED) + { + printf("## PickUpBlock2: failed\n"); + setState(STATE_FAILED); + handler(); + return; + } + else if (myPickUp->getState() == PickUp::STATE_SUCCEEDED) + { + printf("## PickUpBlock2: successful\n"); + setState(STATE_ACQUIRE_WALL); + myGripper->liftUp(); + handler(); + return; + } + break; + case STATE_ACQUIRE_WALL: + if (myNewState) + { + myNewState = false; + mySony->panTilt(0, -5); + myAcquire->activate(); + myAcquire->setChannel(COLOR_FIRST_WALL); + myPickUp->deactivate(); + myDriveTo->deactivate(); + myBackup->deactivate(); + } + if (myAcquire->getState() == Acquire::STATE_FAILED) + { + printf("## AcquireWall:: failed\n"); + setState(STATE_FAILED); + handler(); + return; + } + else if (myAcquire->getState() == Acquire::STATE_SUCCEEDED) + { + printf("## AcquireWall: successful\n"); + setState(STATE_DRIVETO_WALL); + handler(); + return; + } + break; + case STATE_DRIVETO_WALL: + if (myNewState) + { + myNewState = false; + myAcquire->deactivate(); + myPickUp->deactivate(); + myDriveTo->activate(); + myDriveTo->setChannel(COLOR_FIRST_WALL); + myBackup->deactivate(); + } + if (myDriveTo->getState() == DriveTo::STATE_FAILED) + { + printf("## DriveToWall: failed\n"); + setState(STATE_FAILED); + handler(); + return; + } + else if (myDriveTo->getState() == DriveTo::STATE_SUCCEEDED) + { + printf("## DriveToWall: succesful\n"); + setState(STATE_DROP); + handler(); + return; + } + break; + case STATE_DROP: + if (myNewState) + { + myGripper->liftDown(); + myNewState = false; + } + + if (myStateStart.mSecSince() > 3500) + { + myGripper->gripOpen(); + } + if (myStateStart.mSecSince() > 5500) + { + printf("## Drop: success\n"); + setState(STATE_SUCCEEDED); + handler(); + return; + } + break; + case STATE_SUCCEEDED: + printf("Succeeded at the task!\n"); + Aria::shutdown(); + myRobot->disconnect(); + myRobot->stopRunning(); + return; + case STATE_FAILED: + printf("Failed to complete the task!\n"); + Aria::shutdown(); + myRobot->disconnect(); + myRobot->stopRunning(); + return; + default: + printf("TakeBlockToWall::handler: Unknown state!\n"); + + } + +} + +int main(void) +{ + ArSerialConnection con; + ArRobot robot; + int ret; + std::string str; + ArActionLimiterForwards limiter("speed limiter near", 300, 600, 250); + ArActionLimiterForwards limiterFar("speed limiter far", 300, 1100, 400); + ArActionLimiterBackwards backwardsLimiter; + ArActionConstantVelocity stop("stop", 0); + ArActionConstantVelocity backup("backup", -200); + ArSonarDevice sonar; + ArACTS_1_2 acts; + ArGripper gripper(&robot); + ArSonyPTZ sony(&robot); + + Acquire acq(&acts); + DriveTo driveTo(&acts, &gripper, &sony); + PickUp pickUp(&acts, &gripper, &sony); + + TakeBlockToWall takeBlock(&robot, &gripper, &sony, &acq, &driveTo, &pickUp, + &backup); + + Aria::init(); + + acts.openPort(&robot); + + robot.addRangeDevice(&sonar); + if ((ret = con.open()) != 0) + { + str = con.getOpenMessage(ret); + printf("Open failed: %s\n", str.c_str()); + Aria::shutdown(); + return 1; + } + + robot.setDeviceConnection(&con); + if (!robot.blockingConnect()) + { + printf("Could not connect to robot... exiting\n"); + Aria::shutdown(); + return 1; + } + + sony.init(); + ArUtil::sleep(1000); + robot.setAbsoluteMaxTransVel(400); + + robot.comInt(ArCommands::ENABLE, 1); + robot.comInt(ArCommands::SOUNDTOG, 0); + ArUtil::sleep(200); + robot.addAction(&limiter, 100); + robot.addAction(&limiterFar, 99); + robot.addAction(&backwardsLimiter, 98); + robot.addAction(&acq, 77); + robot.addAction(&driveTo, 76); + robot.addAction(&pickUp, 75); + robot.addAction(&backup, 50); + robot.addAction(&stop, 30); + + robot.run(true); + + Aria::shutdown(); + return 0; +} diff --git a/Legacy/Aria/advanced/amptuDemo.cpp b/Legacy/Aria/advanced/amptuDemo.cpp new file mode 100644 index 0000000..bb848e6 --- /dev/null +++ b/Legacy/Aria/advanced/amptuDemo.cpp @@ -0,0 +1,198 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#include "Aria.h" + +/* + This is basically just a demo of how to use the AMPTU, but made fancy so + you can drive around the robot and look at stuff with the camera. Press + button 1 to drive the robot and button two to move the camera. +*/ + +/* + This class is the core of this demo, it adds itself to the robot given + as a user task, then drives the robot and camera from the joystick +*/ +class Joydrive +{ +public: + // constructor + Joydrive(ArRobot *robot); + // destructor, its just empty + ~Joydrive(void) {} + + // the callback function + void drive(void); + +protected: + // the rotational max for the robot + int myRotValRobot; + // translational max for the robot + int myTransValRobot; + // pan max for the camera + int myPanValCamera; + // tilt max for the camera + int myTiltValCamera; + // the joystick handler + ArJoyHandler myJoyHandler; + // the camera + ArAMPTU myCam; + // whether the camera has been inited or not + bool myCamInited; + // pointer to the robot + ArRobot *myRobot; + // callback for the drive function + ArFunctorC myDriveCB; +}; + +/* + Constructor, sets the robot pointer, and some initial values, also note the + use of constructor chaining on myCam and myDriveCB. +*/ +Joydrive::Joydrive(ArRobot *robot) : + myCam(robot), + myDriveCB(this, &Joydrive::drive) +{ + // set the robot pointer and add the joydrive as a user task + myRobot = robot; + myRobot->addUserTask("joydrive", 50, &myDriveCB); + + // initialize some variables + myRotValRobot = 100; + myTransValRobot = 700; + myPanValCamera = 8; + myTiltValCamera = 6; + myCamInited = false; + + // initialize the joystick + myJoyHandler.init(); + // see if we have a joystick, and let user know the results + if (myJoyHandler.haveJoystick()) + { + printf("Have a joystick\n\n"); + } + // we don't have a joystick, so get out + else + { + printf("Do not have a joystick, set up the joystick then rerun the program\n\n"); + Aria::shutdown(); + exit(0); + } +} + +// the important function +void Joydrive::drive(void) +{ + int trans, rot; + int pan, tilt; + + // if the camera isn't initialized, initialize it here... it has to be + // done here instead of above because it needs to be done when the + // robot is connected + if (!myCamInited && myRobot->isConnected()) + { + myCam.init(); + myCamInited = true; + } + + // if joystick button one is pushed, then drive the robot + if (myJoyHandler.haveJoystick() && myJoyHandler.getButton(1)) + { + // set the speeds on the joyhandler so we get the values out we want + myJoyHandler.setSpeeds(myRotValRobot, myTransValRobot); + // get the values from the joyhandler + myJoyHandler.getAdjusted(&rot, &trans); + // set the velocities + myRobot->setVel(trans); + myRobot->setRotVel(-rot); + } + // if the joystick button one isn't pushed, stop the robot + else + { + myRobot->setVel(0); + myRobot->setRotVel(0); + } + + // if button two is pressed then move the camera + if (myJoyHandler.haveJoystick() && myJoyHandler.getButton(2)) + { + // set the speeds so we get out the values we want + myJoyHandler.setSpeeds(myPanValCamera, myTiltValCamera); + // get the values + myJoyHandler.getAdjusted(&pan, &tilt); + // move the camera + myCam.panTilt(myCam.getPan() + pan, myCam.getTilt() + tilt); + } + +} + +int main(int argc, char **argv) +{ + // just some stuff for returns + std::string str; + int ret; + + // robots connection + ArSerialConnection con; + // the robot, this turns state reflection off + ArRobot robot(NULL, false); + // the joydrive as defined above, this also adds itself as a user task + Joydrive joyd(&robot); + + // mandatory init + Aria::init(); + + // open the connection, if it fails, exit + if ((ret = con.open()) != 0) + { + str = con.getOpenMessage(ret); + printf("Open failed: %s\n", str.c_str()); + Aria::shutdown(); + return 1; + } + + // set the connection o nthe robot + robot.setDeviceConnection(&con); + // connect, if we fail, exit + if (!robot.blockingConnect()) + { + printf("Could not connect to robot... exiting\n"); + Aria::shutdown(); + return 1; + } + + // turn off the sonar, enable the motors, turn off amigobot sounds + robot.comInt(ArCommands::SONAR, 0); + robot.comInt(ArCommands::ENABLE, 1); + robot.comInt(ArCommands::SOUNDTOG, 0); + + // run, if we lose connection to the robot, exit + robot.run(true); + + // shutdown and go away + Aria::shutdown(); + return 0; +} + diff --git a/Legacy/Aria/advanced/amptuDemo.vcproj b/Legacy/Aria/advanced/amptuDemo.vcproj new file mode 100644 index 0000000..f4ddf97 --- /dev/null +++ b/Legacy/Aria/advanced/amptuDemo.vcproj @@ -0,0 +1,177 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/advanced/condition.cpp b/Legacy/Aria/advanced/condition.cpp new file mode 100644 index 0000000..b967f9c --- /dev/null +++ b/Legacy/Aria/advanced/condition.cpp @@ -0,0 +1,143 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#include +#include +#include "Aria.h" + + +/* + This example is to show how to use a condition variable. Conditions + are usefull for delaying the execution of a thread until some time later + when some other part of the program wants to wake it up. + + This program has 5 threads. The main thread and 4 worker threads. The + worker threads all wait on the condition variable to be woken up. When + they are woken up they print that fact and then go right back to sleep + waiting on the condition variable. + + The main thread randomly sleeps between 100ms and 500ms and then wakes + up a single thread. It does this 10 times then tells all the threads + to exit and waits for them to do so. The main thread then exits, which + ends the program. + + This is simply an example of how to make threads wait for something to + happen without doing a busy loop, which takes up CPU time. +*/ + + +// The thread class +class Task : public ArASyncTask +{ +public: + + Task(int num, ArCondition *cond); + virtual ~Task() {} + + // The run loop of the thread. + void * runThread(void *arg); + +protected: + + int myNum; + ArCondition *myCond; +}; + + +// Constructor +Task::Task(int num, ArCondition *cond) : + myNum(num), + myCond(cond) +{ + setThreadName("Task"); +} + +// The main loop for the threads. It checks to see if its still running. +// If not, it exits. The running variable is managed by ArThread. While its +// running, it waits on the condition variable. +void * Task::runThread(void *arg) +{ + threadStarted(); + while (getRunning()) + { + printf("Task %d waiting\n", myNum); + myCond->wait(); + printf("Task %d woke up\n", myNum); + } + + return(NULL); +} + + +int main() +{ + int i, sleepTime; + // The condition the threads will be using + ArCondition cond; + // The threads + Task task1(1, &cond); + Task task2(2, &cond); + Task task3(3, &cond); + Task task4(4, &cond); + + // Initialize Aria, which in turn initializes the thread layer + Aria::init(); + + // Initialize the rand() function + srand((unsigned)time(NULL)); + + // Lets start all correct threads. + task1.create(); + task2.create(); + task3.create(); + task4.create(); + + // Lets wake up the threads at different random times + for (i=0; i<10; ++i) + { + sleepTime=rand()%400+100; + printf("Main: Sleeping %dms\n", sleepTime); + ArUtil::sleep(sleepTime); + printf("Main: Waking up a thread\n"); + cond.signal(); + } + + printf("Exiting\n"); + + // Stop all the threads, which sets their running variable to false + ArThread::stopAll(); + + // Now that all the threads are marked as not running, wake them up + // so that we can exit the program gracefully. + cond.broadcast(); + + // Wait for all the threads to exit + ArThread::joinAll(); + + // Uninit Aria + Aria::uninit(); + + return(0); +} diff --git a/Legacy/Aria/advanced/functorListsAndStdAlgorithms.cpp b/Legacy/Aria/advanced/functorListsAndStdAlgorithms.cpp new file mode 100644 index 0000000..dd24eba --- /dev/null +++ b/Legacy/Aria/advanced/functorListsAndStdAlgorithms.cpp @@ -0,0 +1,127 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +/* + * This example shows how to use adapters to use STL algorithms + * with ARIA functors. + * An adapter is an STL function object that calls a method pointer + * (like &ArFunctor::invoke) on whatever object it's applied to when + * invoked with the STL convention (which uses operator().) + * + * This lets you use ARIA functors in STL algorithms (which normally + * only work on STL function objects): + * + * STL Algorithm -> STL Function Pointer Adapter -> ARIA Functor -> + * ARIA Functor Target Method + * + * + * Things end up looking kind of redundant + * +*/ + + +#include +#include +#include +#include +#include + +#include "Aria.h" + + +/* + This is the class that contains some methods to use as callbacks targets. +*/ +class CallbackClass +{ +public: + + void callback1(); + void callback2(int i); + bool callback3(const char *str); +}; + +void CallbackClass::callback1() +{ + printf("Invoked callback1\n"); +} + +void CallbackClass::callback2(int i) +{ + printf("Invoked callback2 with argument of '%d'\n", i); +} + +bool CallbackClass::callback3(const char *str) +{ + printf("Invoked callback3 with argument of '%s'\n", str); + return(true); +} + + +// But not all functor targets need to be in a class: +void globalFunction() +{ + std::cout << "Invoked globalFunction." << std::endl; +} + +int main() +{ + CallbackClass cb; + + + // For functors with no arguments: + std::list functors; + ArFunctorC functor1(cb, &CallbackClass::callback1); + functors.push_back(&functor1); + functors.push_back(&functor1); + functors.push_back(&functor1); + std::for_each(functors.begin(), functors.end(), + std::mem_fun(&ArFunctor::invoke)); + + // For functors with arguments, give mem_fun template parameters. + std::list*> functorsWithArg; + ArFunctor1C functor2(cb, &CallbackClass::callback2); + std::mem_fun1_t, int> f(&ArFunctor1::invoke); + functorsWithArg.push_back(&functor2); + functorsWithArg.push_back(&functor2); + functorsWithArg.push_back(&functor2); + std::for_each(functorsWithArg.begin(), functorsWithArg.end(), std::bind2nd(f, 42)); + + // You can use other STL algorithms if your functor returns something. + // count_if will invoke each functor, and return the number of functor + // invocations that returned true (in this case, 3, since they will + // always return true) + std::list*> functorsWithRet; + ArRetFunctor1C + functor3(cb, &CallbackClass::callback3); + std::mem_fun1_t, const char*> rf(&ArRetFunctor1::invokeR); + functorsWithRet.push_back(&functor3); + functorsWithRet.push_back(&functor3); + functorsWithRet.push_back(&functor3); + int c = std::count_if(functorsWithRet.begin(), functorsWithRet.end(), std::bind2nd(rf, "testing")); + std::cout << "Count=" << c << std::endl; + + return(0); +} diff --git a/Legacy/Aria/advanced/joydriveActionMod.cpp b/Legacy/Aria/advanced/joydriveActionMod.cpp new file mode 100644 index 0000000..1a2a716 --- /dev/null +++ b/Legacy/Aria/advanced/joydriveActionMod.cpp @@ -0,0 +1,136 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#include "Aria.h" + + +// the action which'll drive the robot +class JoydriveAction : public ArAction +{ +public: + // constructor + JoydriveAction(void); + // empty destructor + virtual ~JoydriveAction(void); + //the fire which will actually tell the resolver what to do + virtual ArActionDesired *fire(ArActionDesired currentDesired); + // whether the joystick is initalized or not + bool joystickInited(void); +protected: + // action desired + ArActionDesired myDesired; + // joystick handler + ArJoyHandler myJoyHandler; +}; + +class JoydriveMod : public ArModule +{ +public: + + bool init(ArRobot *robot, void *argument = NULL); + bool exit(); +}; + +JoydriveMod aModule; +ARDEF_MODULE(aModule); +JoydriveAction aJDAct; + +bool JoydriveMod::init(ArRobot *robot, void *argument) +{ + if (!aJDAct.joystickInited()) + { + printf("Do not have a joystick, set up the joystick then rerun the program\n\n"); + return(false); + } + + robot->addAction(&aJDAct, 100); + + return(true); +} + +bool JoydriveMod::exit() +{ + return(true); +} + + +/* + Note the use of constructor chaining with ArAction. +*/ +JoydriveAction::JoydriveAction(void) : + ArAction("Joydrive Action", "This action reads the joystick and sets the translational and rotational velocity based on this.") +{ + // initialize the joystick + myJoyHandler.init(); + // set up the speed parameters on the joystick + myJoyHandler.setSpeeds(50, 700); +} + +JoydriveAction::~JoydriveAction(void) +{ + // it just removes itself from the robots action list + if (myRobot != NULL) + myRobot->remAction(this); +} + +// whether the joystick is there or not +bool JoydriveAction::joystickInited(void) +{ + return myJoyHandler.haveJoystick(); +} + +// the guts of the thing +ArActionDesired *JoydriveAction::fire(ArActionDesired currentDesired) +{ + int rot, trans; + + // print out some info about hte robot + printf("\rx %6.1f y %6.1f tth %6.1f vel %7.1f mpacs %3d", myRobot->getX(), + myRobot->getY(), myRobot->getTh(), myRobot->getVel(), + myRobot->getMotorPacCount()); + fflush(stdout); + + // see if one of the buttons is pushed, if so drive + if (myJoyHandler.haveJoystick() && (myJoyHandler.getButton(1) || + myJoyHandler.getButton(2))) + { + // get the readings from the joystick + myJoyHandler.getAdjusted(&rot, &trans); + // set what we want to do + myDesired.setVel(trans); + myDesired.setDeltaHeading(-rot); + // return the actionDesired + return &myDesired; + } + else + { + // set what we want to do + myDesired.setVel(0); + myDesired.setDeltaHeading(0); + // return the actionDesired + return &myDesired; + } +} + diff --git a/Legacy/Aria/advanced/joydriveActionMod.vcproj b/Legacy/Aria/advanced/joydriveActionMod.vcproj new file mode 100644 index 0000000..e31922b --- /dev/null +++ b/Legacy/Aria/advanced/joydriveActionMod.vcproj @@ -0,0 +1,187 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/advanced/joydriveActionModule.cpp b/Legacy/Aria/advanced/joydriveActionModule.cpp new file mode 100644 index 0000000..aa85633 --- /dev/null +++ b/Legacy/Aria/advanced/joydriveActionModule.cpp @@ -0,0 +1,88 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#include "Aria.h" + + +void printStatus(ArModuleLoader::Status status) +{ + if (status == ArModuleLoader::STATUS_ALREADY_LOADED) + printf("Module already loaded\n"); + else if (status == ArModuleLoader::STATUS_FAILED_OPEN) + printf("Failed to find or open the simpleMod module\n"); + else if (status == ArModuleLoader::STATUS_INVALID) + printf("Invalid file\n"); + else if (status == ArModuleLoader::STATUS_INIT_FAILED) + printf("Module Init failed\n"); + else if (status == ArModuleLoader::STATUS_SUCCESS) + printf("Module succedded\n"); + else if (status == ArModuleLoader::STATUS_EXIT_FAILED) + printf("Module exit sequence failed\n"); +} + +int main() +{ + ArModuleLoader::Status status; + ArSerialConnection con; + ArRobot robot; + int ret; + std::string str; + + Aria::init(); + + status=ArModuleLoader::load("./joydriveActionMod", &robot); + printStatus(status); + + if (status == ArModuleLoader::STATUS_INIT_FAILED) + return(1); + + if ((ret = con.open()) != 0) + { + str = con.getOpenMessage(ret); + printf("Open failed: %s\n", str.c_str()); + Aria::shutdown(); + return 1; + } + + robot.setDeviceConnection(&con); + if (!robot.blockingConnect()) + { + printf("Could not connect to robot... exiting\n"); + Aria::shutdown(); + return 1; + } + + robot.comInt(ArCommands::SONAR, 0); + robot.comInt(ArCommands::ENABLE, 1); + robot.comInt(ArCommands::SOUNDTOG, 0); + + robot.run(true); + + status=ArModuleLoader::close("./joydriveActionMod"); + printStatus(status); + + Aria::shutdown(); + return 0; +} diff --git a/Legacy/Aria/advanced/joydriveActionModule.vcproj b/Legacy/Aria/advanced/joydriveActionModule.vcproj new file mode 100644 index 0000000..caf48cb --- /dev/null +++ b/Legacy/Aria/advanced/joydriveActionModule.vcproj @@ -0,0 +1,177 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/advanced/joydriveUserControl.cpp b/Legacy/Aria/advanced/joydriveUserControl.cpp new file mode 100644 index 0000000..3e4a784 --- /dev/null +++ b/Legacy/Aria/advanced/joydriveUserControl.cpp @@ -0,0 +1,110 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#include "Aria.h" + +int main(int argc, char **argv) +{ + std::string str; + int ret; + time_t lastTime; + int trans, rot; + + ArJoyHandler joyHandler; + ArSerialConnection con; + ArRobot robot(NULL, false); + + joyHandler.init(); + joyHandler.setSpeeds(100, 700); + + if (joyHandler.haveJoystick()) + { + printf("Have a joystick\n\n"); + } + else + { + printf("Do not have a joystick, set up the joystick then rerun the program\n\n"); +// exit(0); + } + + if ((ret = con.open()) != 0) + { + str = con.getOpenMessage(ret); + printf("Open failed: %s\n", str.c_str()); + exit(0); + } + + + robot.setDeviceConnection(&con); + if (!robot.blockingConnect()) + { + printf("Could not connect to robot... exiting\n"); + exit(0); + } + + robot.comInt(ArCommands::SONAR, 0); + robot.comInt(ArCommands::ENABLE, 1); + robot.comInt(ArCommands::SOUNDTOG, 0); + //robot.comInt(ArCommands::ENCODER, 1); + + //robot.comStrN(ArCommands::SAY, "\1\6\2\105", 4); + + lastTime = time(NULL); + while (1) + { + if (!robot.isConnected()) + { + printf("No longer connected to robot, exiting.\n"); + exit(0); + } + robot.loopOnce(); + if (lastTime != time(NULL)) + { + printf("\rx %6.1f y %6.1f tth %6.1f vel %7.1f mpacs %3d", robot.getX(), + robot.getY(), robot.getTh(), robot.getVel(), + robot.getMotorPacCount()); + fflush(stdout); + lastTime = time(NULL); + } + if (joyHandler.haveJoystick() && (joyHandler.getButton(1) || + joyHandler.getButton(2))) + { + if (ArMath::fabs(robot.getVel()) < 10.0) + robot.comInt(ArCommands::ENABLE, 1); + joyHandler.getAdjusted(&rot, &trans); + robot.comInt(ArCommands::VEL, trans); + robot.comInt(ArCommands::RVEL, -rot); + } + else + { + robot.comInt(ArCommands::VEL, 0); + robot.comInt(ArCommands::RVEL, 0); + } + ArUtil::sleep(100); + } + + +} + diff --git a/Legacy/Aria/advanced/peoplebotDemo.cpp b/Legacy/Aria/advanced/peoplebotDemo.cpp new file mode 100644 index 0000000..4d7144b --- /dev/null +++ b/Legacy/Aria/advanced/peoplebotDemo.cpp @@ -0,0 +1,1582 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#include "Aria.h" + +#define CAMERA_X_CORRECTION 0 +//-.085 +#define BACKUP_DIST -600 +#define BACKUP_TIME 3000 + +class ArActionTableSensorLimiter : public ArAction +{ +public: + ArActionTableSensorLimiter(void); + virtual ~ArActionTableSensorLimiter(void) {} + virtual ArActionDesired *fire(ArActionDesired currentDesired); +protected: + ArActionDesired myDesired; +}; + +ArActionTableSensorLimiter::ArActionTableSensorLimiter(void) : + ArAction("Table sensor limiter") +{ + +} + +ArActionDesired *ArActionTableSensorLimiter::fire( + ArActionDesired currentDesired) +{ + myDesired.reset(); + +// Note the following commented out section will not work with IR's that +// are sent through byte 4 of the IO packet. +// Reference the NewTableSensingIR parameter + /* + printf("%d ", myRobot->getDigIn()); + if (!(myRobot->getDigIn() & ArUtil::BIT0)) + printf("leftTable "); + if (!(myRobot->getDigIn() & ArUtil::BIT1)) + printf("rightTable "); + if (!(myRobot->getDigIn() & ArUtil::BIT3)) + printf("leftBREAK "); + if (!(myRobot->getDigIn() & ArUtil::BIT2)) + printf("rightBREAK "); + printf("\n"); + */ + + if (myRobot->isLeftTableSensingIRTriggered() || + myRobot->isRightTableSensingIRTriggered()) + { + myDesired.setMaxVel(0); + return &myDesired; + } + return NULL; +} + +class DriveTo : public ArAction +{ +public: + enum State { + STATE_START_LOOKING, + STATE_LOOKING, + STATE_FAILED, + STATE_SUCCEEDED + }; + DriveTo(ArACTS_1_2 *acts, ArGripper *gripper, ArPTZ *amptu); + ~DriveTo(void); + virtual ArActionDesired *fire(ArActionDesired currentDesired); + bool setChannel(int channel); + State getState(void) { return myState; } + enum { + WIDTH = 160, + HEIGHT = 120 + }; +protected: + ArActionDesired myDesired; + ArACTS_1_2 *myActs; + ArGripper *myGripper; + ArPTZ *myAMPTU; + ArPose myLastPose; + ArTime myLastMoved; + int myChannel; + bool myPickup; + State myState; + ArTime myLastSeen; +}; + +DriveTo::DriveTo(ArACTS_1_2 *acts, ArGripper *gripper, ArPTZ *amptu) : + ArAction("DriveTo", "Drives to something.") +{ + myActs = acts; + myGripper = gripper; + myAMPTU = amptu; + myChannel = 0; + myState = STATE_FAILED; + //setChannel(1); +} + +DriveTo::~DriveTo(void) +{ + +} + +ArActionDesired *DriveTo::fire(ArActionDesired currentDesired) +{ + ArACTSBlob blob; + double xRel, yRel; + ArPose pose; + double dist; + + if (myState == STATE_SUCCEEDED || myState == STATE_FAILED) + { + myDesired.setVel(0); + myDesired.setDeltaHeading(0); + return &myDesired; + } + + if (myState == STATE_START_LOOKING) + { + myState = STATE_LOOKING; + myLastSeen.setToNow(); + myLastPose = myRobot->getPose(); + myLastMoved.setToNow(); + } + + pose = myRobot->getPose(); + dist = myLastPose.findDistanceTo(pose); + if (dist < 5 && myLastMoved.mSecSince() > 1500) + { + printf("DriveTo: Failed, no movement in the last 1500 msec.\n"); + myState = STATE_FAILED; + myDesired.setVel(0); + myDesired.setDeltaHeading(0); + return &myDesired; + } + else if (dist > 5) + { + myLastMoved.setToNow(); + myLastPose = myRobot->getPose(); + } + + if (myActs->getNumBlobs(myChannel) == 0 || + !myActs->getBlob(myChannel, 1, &blob)) + { + if (myLastSeen.mSecSince() > 1000) + { + printf("DriveTo: Lost the blob, failed.\n"); + myState = STATE_FAILED; + myDesired.setVel(0); + myDesired.setDeltaHeading(0); + return &myDesired; + } + } + else + { + myLastSeen.setToNow(); + } + + xRel = (double)(blob.getXCG() - WIDTH/2.0) / (double)WIDTH + CAMERA_X_CORRECTION; + yRel = (double)(blob.getYCG() - HEIGHT/2.0) / (double)HEIGHT; + + //printf("xRel %.3f yRel %.3f\n", xRel, yRel); + + myDesired.reset(); + // this if the stuff we want to do if we're not going to just drive forward + // and home in on the color, ie the pickup-specific stuff + if (currentDesired.getMaxVelStrength() > 0 && + currentDesired.getMaxVel() < 125) + { + printf("DriveTo: Close to a wall of some sort, succeeded.\n"); + myState = STATE_SUCCEEDED; + myDesired.setVel(0); + myDesired.setDeltaHeading(0); + return &myDesired; + } + + if (ArMath::fabs(xRel) < .10) + { + //printf("Going straight ahead\n"); + myDesired.setDeltaHeading(0); + } + else + { + //printf("Turning %.2f\n", -xRel * 20); + if (-xRel > 1.0) + myDesired.setDeltaHeading(20); + else if (-xRel < -1.0) + myDesired.setDeltaHeading(-20); + else + myDesired.setDeltaHeading(-xRel * 20); + } + myDesired.setVel(150); + return &myDesired; +} + +bool DriveTo::setChannel(int channel) +{ + if (channel >= 1 && channel <= ArACTS_1_2::NUM_CHANNELS) + { + myChannel = channel; + myState = STATE_START_LOOKING; + return true; + } + else + return false; +} + + +class PickUp : public ArAction +{ +public: + enum State { + STATE_START_LOOKING, + STATE_LOOKING, + STATE_FAILED, + STATE_SUCCEEDED + }; + PickUp(ArACTS_1_2 *acts, ArGripper *gripper, ArPTZ *amptu); + ~PickUp(void); + virtual ArActionDesired *fire(ArActionDesired currentDesired); + bool setChannel(int channel); + State getState(void) { return myState; } + enum { + WIDTH = 160, + HEIGHT = 120 + }; +protected: + ArActionDesired myDesired; + ArACTS_1_2 *myActs; + ArGripper *myGripper; + ArPTZ *myAMPTU; + int myChannel; + bool myPickup; + bool myTried; + bool myPointedDown; + State myState; + ArPose myLastPose; + ArTime myLastMoved; + ArTime myLastSeen; + ArTime mySentGripper; + ArTime myTriedStart; + bool myWaitingOnGripper; + bool myWaitingOnLower; + bool myWaitingOnRaised; + bool myStartRaised; + bool myLowered; +}; + +PickUp::PickUp(ArACTS_1_2 *acts, ArGripper *gripper, ArPTZ *amptu) : + ArAction("PickUp", "Picks up something.") +{ + myActs = acts; + myGripper = gripper; + myAMPTU = amptu; + myChannel = 0; + myState = STATE_FAILED; + //setChannel(2); +} + +PickUp::~PickUp(void) +{ + +} + +ArActionDesired *PickUp::fire(ArActionDesired currentDesired) +{ + ArPose pose; + ArACTSBlob blob; + bool blobSeen = false; + double xRel, yRel; + double dist; + + + myDesired.reset(); + if (myState == STATE_SUCCEEDED) + { + //printf("PickUp: Succeeded\n"); + myDesired.setVel(0); + myDesired.setDeltaHeading(0); + return &myDesired; + } + else if (myState == STATE_FAILED) + { + //printf("PickUp: Failed\n"); + myDesired.setVel(0); + myDesired.setDeltaHeading(0); + return &myDesired; + } + + if (myActs->getNumBlobs(myChannel) > 0 && + (blobSeen = myActs->getBlob(myChannel, 1, &blob))) + { + myLastSeen.setToNow(); + } + + // this if the stuff we want to do if we're not going to just drive forward + // and home in on the color, ie the pickup-specific stuff + if (myState == STATE_START_LOOKING) + { + myGripper->gripOpen(); + mySentGripper.setToNow(); + myPointedDown = false; + myState = STATE_LOOKING; + myLastSeen.setToNow(); + myTried = false; + myLastMoved.setToNow(); + myLastPose = myRobot->getPose(); + myWaitingOnGripper = true; + myWaitingOnLower = false; + myLowered = false; + myWaitingOnRaised = false; + myStartRaised = false; + printf("@@@@@ Pickup: Starting\n"); + } + + // we want to sit still until the lift is down or for a second and a half + + if (myWaitingOnGripper) + { + if (mySentGripper.mSecSince() < 500 || + (myGripper->getGripState() != 1 + && mySentGripper.mSecSince() < 2000)) + { + myGripper->gripOpen(); + myDesired.setVel(0); + myDesired.setDeltaHeading(0); + myLastMoved.setToNow(); + myLastPose = myRobot->getPose(); + return &myDesired; + } + else + { + myWaitingOnGripper = false; + } + myLastMoved.setToNow(); + myLastPose = myRobot->getPose(); + } + + //printf("sensors %d %d stall %d %d\n",!(myRobot->getDigIn() & ArUtil::BIT2), + //!(myRobot->getDigIn() & ArUtil::BIT3), + //myRobot->isLeftMotorStalled(), myRobot->isRightMotorStalled()); + if ((myRobot->isLeftBreakBeamTriggered() && + myRobot->isRightBreakBeamTriggered()) || + myRobot->isLeftMotorStalled() || myRobot->isRightMotorStalled()) + { + if (!myWaitingOnLower && !myLowered && !myWaitingOnRaised) + { + myWaitingOnLower = true; + printf("PickUp: Lowering gripper\n"); + mySentGripper.setToNow(); + } + } + if (myWaitingOnLower) + { + /// TODO + if (mySentGripper.mSecSince() < 600 || + (!myGripper->isLiftMaxed() + && mySentGripper.mSecSince() < 20000)) + { + myGripper->liftDown(); + myDesired.setVel(0); + myDesired.setDeltaHeading(0); + myLastMoved.setToNow(); + myLastPose = myRobot->getPose(); + return &myDesired; + } + else + { + myWaitingOnLower = false; + myWaitingOnRaised = true; + myStartRaised = true; + } + myLastMoved.setToNow(); + myLastPose = myRobot->getPose(); + } + + if (myWaitingOnRaised) + { + if (myStartRaised) + { + printf("PickUp: Raising gripper a little bit\n"); + myGripper->liftCarry(15); + mySentGripper.setToNow(); + myStartRaised = false; + } + if (mySentGripper.mSecSince() > 1000) + { + printf("PickUp: Raised the gripper a little bit\n"); + myWaitingOnRaised = false; + myLowered = true; + } + myDesired.setVel(0); + myDesired.setDeltaHeading(0); + myLastMoved.setToNow(); + myLastPose = myRobot->getPose(); + return &myDesired; + } + + if (myLowered && myGripper->getBreakBeamState() != 0) + { + if (!myTried) + { + printf("PickUp: Trying to pick up.\n"); + myTriedStart.setToNow(); + } + myTried = true; + myGripper->gripClose(); + if (myGripper->getGripState() == 2 || myTriedStart.mSecSince() > 5000) + { + printf("PickUp: Succeeded, have block.\n"); + myGripper->liftUp(); + myState = STATE_SUCCEEDED; + } + myDesired.setVel(0); + myDesired.setDeltaHeading(0); + return &myDesired; + } + // this means that the grippers are closed, but we don't have anything in + // them, ie that we failed to get the block + else if (myTried && (myGripper->getGripState() == 2 || + myTriedStart.mSecSince() > 5000)) + { + myState = STATE_FAILED; + myGripper->gripOpen(); + ArUtil::sleep(3); + myGripper->liftUp(); + printf("PickUp: Grippers closed, didn't get a block, failed.\n"); + myDesired.setVel(0); + myDesired.setDeltaHeading(0); + return &myDesired; + } + + + pose = myRobot->getPose(); + dist = myLastPose.findDistanceTo(pose); + if (dist < 5 && myLastMoved.mSecSince() > 2500) + { + printf("PickUp: Failed, no movement in the last 2500 msec.\n"); + myState = STATE_FAILED; + myGripper->gripOpen(); + myGripper->liftUp(); + myDesired.setVel(0); + myDesired.setDeltaHeading(0); + return &myDesired; + } + else if (dist > 5) + { + myLastMoved.setToNow(); + myLastPose = myRobot->getPose(); + } + + if (!blobSeen) + { + if (((!myPointedDown && myLastSeen.mSecSince() > 1500) || + (myPointedDown && myLastSeen.mSecSince() > 4000)) && + myGripper->getBreakBeamState() == 0) + { + printf("PickUp: Lost the blob, failed, last saw it %ld msec ago.\n", + myLastSeen.mSecSince()); + myState = STATE_FAILED; + myGripper->gripOpen(); + ArUtil::sleep(3); + myGripper->liftUp(); + myDesired.setVel(0); + myDesired.setDeltaHeading(0); + return &myDesired; + } + } + else + myLastSeen.setToNow(); + + if (blobSeen) + { + xRel = (double)(blob.getXCG() - WIDTH/2.0) / (double)WIDTH + CAMERA_X_CORRECTION; + yRel = -(double)(blob.getYCG() - HEIGHT/2.0) / (double)HEIGHT; + //printf("xRel %.3f yRel %.3f: ", xRel, yRel); + } + else + { + //printf("No blob: "); + } + + if (blobSeen && yRel < -.2 && !myPointedDown) + { + printf("PickUp: Pointing the camera down!!!\n"); + myAMPTU->panTilt(0, -75); + myPointedDown = true; + } + + + if (!blobSeen || ArMath::fabs(xRel) < .001) + { + //printf("Going straight ahead\n"); + myDesired.setDeltaHeading(0); + } + else + { + //printf("Turning %.2f\n", -xRel * 30); + if (-xRel > 1.0) + myDesired.setDeltaHeading(30); + else if (-xRel < -1.0) + myDesired.setDeltaHeading(-30); + else + myDesired.setDeltaHeading(-xRel * 30); + } + if (myRobot->isLeftTableSensingIRTriggered() || + myRobot->isRightTableSensingIRTriggered()) + myDesired.setVel(50); + else + myDesired.setVel(100); + return &myDesired; +} + +bool PickUp::setChannel(int channel) +{ + if (channel >= 1 && channel <= ArACTS_1_2::NUM_CHANNELS) + { + myChannel = channel; + myState = STATE_START_LOOKING; + return true; + } + else + return false; +} + +class DropOff : public ArAction +{ +public: + enum State { + STATE_START_LOOKING, + STATE_LOOKING, + STATE_FAILED, + STATE_SUCCEEDED + }; + DropOff(ArACTS_1_2 *acts, ArGripper *gripper, ArPTZ *amptu); + ~DropOff(void); + virtual ArActionDesired *fire(ArActionDesired currentDesired); + bool setChannel(int channel); + State getState(void) { return myState; } + enum { + WIDTH = 160, + HEIGHT = 120 + }; +protected: + ArActionDesired myDesired; + ArACTS_1_2 *myActs; + ArGripper *myGripper; + ArPTZ *myAMPTU; + int myChannel; + bool myPickup; + bool myTried; + bool myPointedDown; + State myState; + ArPose myLastPose; + ArTime myLastMoved; + ArTime myLastSeen; + ArTime mySentGripper; + ArTime myTriedStart; + bool myWaitingOnGripper; + bool myWaitingOnLower; + bool myWaitingOnRaised; + bool myStartRaised; + bool myLowered; +}; + +DropOff::DropOff(ArACTS_1_2 *acts, ArGripper *gripper, ArPTZ *amptu) : + ArAction("DropOff", "Picks up something.") +{ + myActs = acts; + myGripper = gripper; + myAMPTU = amptu; + myChannel = 0; + myState = STATE_FAILED; + //setChannel(2); +} + +DropOff::~DropOff(void) +{ + +} + +ArActionDesired *DropOff::fire(ArActionDesired currentDesired) +{ + ArPose pose; + ArACTSBlob blob; + bool blobSeen = false; + double xRel, yRel; + double dist; + + + myDesired.reset(); + if (myState == STATE_SUCCEEDED) + { + printf("DropOff: Succeeded\n"); + myDesired.setVel(0); + myDesired.setDeltaHeading(0); + return &myDesired; + } + else if (myState == STATE_FAILED) + { + printf("DropOff: Failed\n"); + myDesired.setVel(0); + myDesired.setDeltaHeading(0); + return &myDesired; + } + + if (myActs->getNumBlobs(myChannel) > 0 && + (blobSeen = myActs->getBlob(myChannel, 1, &blob))) + { + myLastSeen.setToNow(); + } + + // this if the stuff we want to do if we're not going to just drive forward + // and home in on the color, ie the pickup-specific stuff + if (myState == STATE_START_LOOKING) + { + mySentGripper.setToNow(); + myPointedDown = false; + myState = STATE_LOOKING; + myLastSeen.setToNow(); + myTried = false; + myLastMoved.setToNow(); + myLastPose = myRobot->getPose(); + //myWaitingOnGripper = true; + myWaitingOnLower = false; + myLowered = false; + myWaitingOnRaised = false; + myStartRaised = false; + printf("@@@@@ DropOff: Starting\n"); + } + + // we want to sit still until the lift is down or for a second and a half + /* + if (myWaitingOnGripper) + { + if (mySentGripper.mSecSince() < 500 || + (myGripper->getGripState() != 1 + && mySentGripper.mSecSince() < 4000)) + { + myDesired.setVel(0); + myDesired.setDeltaHeading(0); + myLastMoved.setToNow(); + myLastPose = myRobot->getPose(); + return &myDesired; + } + else + { + myWaitingOnGripper = false; + } + myLastMoved.setToNow(); + myLastPose = myRobot->getPose(); + } + */ + //printf("sensors %d %d stall %d %d\n",!(myRobot->getDigIn() & ArUtil::BIT2), + //!(myRobot->getDigIn() & ArUtil::BIT3), + //myRobot->isLeftMotorStalled(), myRobot->isRightMotorStalled()); + if ((myRobot->isLeftBreakBeamTriggered() && + myRobot->isRightBreakBeamTriggered()) || + myRobot->isLeftMotorStalled() || myRobot->isRightMotorStalled()) + { + if (!myWaitingOnLower && !myLowered && !myWaitingOnRaised) + { + myWaitingOnLower = true; + printf("DropOff: Lowering gripper\n"); + mySentGripper.setToNow(); + } + } + if (myWaitingOnLower) + { + /// TODO + if (mySentGripper.mSecSince() < 600 || + (!myGripper->isLiftMaxed() && mySentGripper.mSecSince() < 20000)) + { + myGripper->liftDown(); + myDesired.setVel(0); + myDesired.setDeltaHeading(0); + myLastMoved.setToNow(); + myLastPose = myRobot->getPose(); + return &myDesired; + } + else + { + printf("DropOff: Lowered!\n"); + myWaitingOnLower = false; + myWaitingOnRaised = true; + myStartRaised = true; + } + myLastMoved.setToNow(); + myLastPose = myRobot->getPose(); + } + + if (myWaitingOnRaised) + { + if (myStartRaised) + { + printf("DropOff: Raising gripper a little bit\n"); + myGripper->liftCarry(15); + mySentGripper.setToNow(); + myStartRaised = false; + } + if (mySentGripper.mSecSince() > 1000) + { + printf("DropOff: Raised the gripper a little bit\n"); + myWaitingOnRaised = false; + myLowered = true; + } + myDesired.setVel(0); + myDesired.setDeltaHeading(0); + myLastMoved.setToNow(); + myLastPose = myRobot->getPose(); + return &myDesired; + } + + if (myLowered) + { + if (!myTried) + { + printf("DropOff: Trying to let go of the block.\n"); + myTriedStart.setToNow(); + myTried = true; + } + myGripper->gripOpen(); + if (myGripper->getGripState() == 1 || myTriedStart.mSecSince() > 3000) + { + printf("DropOff: Succeeded, dropped off the block.\n"); + myGripper->liftUp(); + myState = STATE_SUCCEEDED; + } + myDesired.setVel(0); + myDesired.setDeltaHeading(0); + return &myDesired; + } + + pose = myRobot->getPose(); + dist = myLastPose.findDistanceTo(pose); + if (dist < 5 && myLastMoved.mSecSince() > 2500) + { + printf("DropOff: Failed, no movement in the last 2500 msec.\n"); + myState = STATE_FAILED; + myGripper->gripOpen(); + myGripper->liftUp(); + myDesired.setVel(0); + myDesired.setDeltaHeading(0); + return &myDesired; + } + else if (dist > 5) + { + myLastMoved.setToNow(); + myLastPose = myRobot->getPose(); + } + + if (!blobSeen) + { + if (((!myPointedDown && myLastSeen.mSecSince() > 1500) || + (myPointedDown && myLastSeen.mSecSince() > 4000)) && + myGripper->getBreakBeamState() == 0) + { + printf("DropOff: Lost the blob, failed, last saw it %ld msec ago.\n", + myLastSeen.mSecSince()); + myState = STATE_FAILED; + myGripper->gripOpen(); + ArUtil::sleep(3); + myGripper->liftUp(); + myDesired.setVel(0); + myDesired.setDeltaHeading(0); + return &myDesired; + } + } + else + myLastSeen.setToNow(); + + if (blobSeen) + { + xRel = (double)(blob.getXCG() - WIDTH/2.0) / (double)WIDTH + CAMERA_X_CORRECTION; + yRel = -(double)(blob.getYCG() - HEIGHT/2.0) / (double)HEIGHT; + //printf("xRel %.3f yRel %.3f: ", xRel, yRel); + } + else + { + //printf("No blob: "); + } + + if (blobSeen && yRel < -.2 && !myPointedDown) + { + printf("DropOff: Pointing the camera down!!!\n"); + myAMPTU->panTilt(0, -75); + myPointedDown = true; + } + + + if (!blobSeen || ArMath::fabs(xRel) < .001) + { + //printf("Going straight ahead\n"); + myDesired.setDeltaHeading(0); + } + else + { + //printf("Turning %.2f\n", -xRel * 30); + if (-xRel > 1.0) + myDesired.setDeltaHeading(30); + else if (-xRel < -1.0) + myDesired.setDeltaHeading(-30); + else + myDesired.setDeltaHeading(-xRel * 30); + } + if (myRobot->isLeftTableSensingIRTriggered() || + myRobot->isRightTableSensingIRTriggered()) + myDesired.setVel(50); + else + myDesired.setVel(100); + return &myDesired; +} + +bool DropOff::setChannel(int channel) +{ + if (channel >= 1 && channel <= ArACTS_1_2::NUM_CHANNELS) + { + myChannel = channel; + myState = STATE_START_LOOKING; + return true; + } + else + return false; +} + +class Acquire : public ArAction +{ +public: + enum State { + STATE_START_LOOKING, + STATE_LOOKING, + STATE_FAILED, + STATE_SUCCEEDED + }; + Acquire(ArACTS_1_2 *acts, ArGripper *gripper); + virtual ~Acquire(void); + virtual ArActionDesired *fire(ArActionDesired currentDesired); + bool setChannel(int channel); + State getState(void) { return myState; } +protected: + State myState; + int myChannel; + ArSectors myFirstTurn; + ArSectors mySecondTurn; + ArActionDesired myDesired; + ArACTS_1_2 *myActs; + ArGripper *myGripper; + ArTime myStartUp; + bool myTryingGripper; +}; + +Acquire::Acquire(ArACTS_1_2 *acts, ArGripper *gripper) : + ArAction("Acquire", "Turns until it can find the given channel, gives up after 1 revolution") +{ + myActs = acts; + myGripper = gripper; + myState = STATE_FAILED; +} + +Acquire::~Acquire(void) +{ +} + +ArActionDesired *Acquire::fire(ArActionDesired currentDesired) +{ + myDesired.reset(); + myDesired.setVel(0); + //printf("%d %d %d\n", myActs->getNumBlobs(1),myActs->getNumBlobs(2), + //myActs->getNumBlobs(3)); + switch (myState) { + case STATE_START_LOOKING: + myFirstTurn.clear(); + mySecondTurn.clear(); + myState = STATE_LOOKING; + myGripper->liftUp(); + myGripper->gripClose(); + printf("Acquire: Raising lift\n"); + myStartUp.setToNow(); + myTryingGripper = true; + case STATE_LOOKING: + /// TODO + if (myTryingGripper && (myStartUp.mSecSince() < 600 || + ((!myGripper->isLiftMaxed() || + myGripper->getGripState() != 2) && + myStartUp.mSecSince() < 20000))) + { + myGripper->liftUp(); + myGripper->gripClose(); + myDesired.setVel(0); + myDesired.setDeltaHeading(0); + return &myDesired; + } + else if (myTryingGripper) + { + printf("Acquire: Done raising lift %ld after started.\n", + myStartUp.mSecSince()); + myTryingGripper = false; + } + if (myActs->getNumBlobs(myChannel) > 0) + { + myDesired.setDeltaHeading(0); + myState = STATE_SUCCEEDED; + printf("Acquire: Succeeded!\n"); + } + else if (myFirstTurn.didAll() && mySecondTurn.didAll()) + { + myDesired.setDeltaHeading(0); + myState = STATE_FAILED; + printf("Acquire: Did two revolutions, didn't see the blob, Failed!\n"); + } + else + { + myFirstTurn.update(myRobot->getTh()); + if (myFirstTurn.didAll()) + mySecondTurn.update(myRobot->getTh()); + myDesired.setDeltaHeading(8); + } + return &myDesired; + default: + myDesired.setVel(0); + myDesired.setDeltaHeading(0); + return &myDesired; + } +} + +bool Acquire::setChannel(int channel) +{ + if (channel >= 1 && channel <= ArACTS_1_2::NUM_CHANNELS) + { + myChannel = channel; + myState = STATE_START_LOOKING; + return true; + } + else + return false; +} + +class TakeBlockToWall +{ +public: + enum State { + STATE_START, + STATE_ACQUIRE_BLOCK, + STATE_PICKUP_BLOCK, + STATE_BACKUP, + STATE_FORWARD, + STATE_ACQUIRE_BLOCK2, + STATE_PICKUP_BLOCK2, + STATE_PICKUP_BACKUP, + STATE_ACQUIRE_DROP_WALL, + STATE_DRIVETO_DROP_WALL, + STATE_DROP_BACKUP, + STATE_ACQUIRE_LAP_WALL, + STATE_DRIVETO_LAP_WALL, + STATE_BACKUP_LAP_WALL, + STATE_FORWARD_LAP_WALL, + STATE_SWITCH, + STATE_FAILED + }; + TakeBlockToWall(ArRobot *robot, ArGripper *gripper, ArPTZ *amptu, + Acquire *acquire, DriveTo *driveTo, PickUp *pickUp, + DropOff *dropOff, + ArActionTableSensorLimiter *tableLimiter); + ~TakeBlockToWall(void); + void handler(void); + void setState(State state); + enum Color { + COLOR_FIRST_WALL = 1, + COLOR_SECOND_WALL = 3, + COLOR_BLOCK = 2 + }; + +protected: + ArTime myStateStartTime; + ArPose myStateStartPos; + ArRobot *myRobot; + ArFunctorC myHandlerCB; + ArGripper *myGripper; + ArPTZ *myAMPTU; + Acquire *myAcquire; + DriveTo *myDriveTo; + DropOff *myDropOff; + PickUp *myPickUp; + ArActionTableSensorLimiter *myTableLimiter; + State myState; + Color myDropWall; + Color myLapWall; + bool myNewState; + bool myGripOpenSent; +}; + +TakeBlockToWall::TakeBlockToWall(ArRobot *robot, ArGripper *gripper, + ArPTZ *amptu, Acquire *acquire, + DriveTo *driveTo, PickUp *pickUp, + DropOff *dropOff, + ArActionTableSensorLimiter *tableLimiter) : + myHandlerCB(this, &TakeBlockToWall::handler) +{ + myRobot = robot; + myRobot->addUserTask("TakeBlockToWall", 75, &myHandlerCB); + myGripper = gripper; + myAcquire = acquire; + myDriveTo = driveTo; + myDropOff = dropOff; + myTableLimiter = tableLimiter; + myPickUp = pickUp; + myAMPTU = amptu; + myState = STATE_START; + myNewState = true; +} + +TakeBlockToWall::~TakeBlockToWall(void) +{ +} + +void TakeBlockToWall::setState(State state) +{ + myState = state; + myNewState = true; + myStateStartTime.setToNow(); + myStateStartPos = myRobot->getPose(); +} + + +void TakeBlockToWall::handler(void) +{ + Color tempColor; + + switch (myState) + { + case STATE_START: + setState(STATE_ACQUIRE_BLOCK); + myDropWall = COLOR_FIRST_WALL; + myLapWall = COLOR_SECOND_WALL; + printf("!! Started state handling!\n"); + //handler(); + return; + break; + case STATE_ACQUIRE_BLOCK: + if (myNewState) + { + printf("!! Acquire block\n"); + myNewState = false; + myAMPTU->panTilt(0, -40); + myAcquire->activate(); + myAcquire->setChannel(COLOR_BLOCK); + myPickUp->deactivate(); + myDriveTo->deactivate(); + myDropOff->deactivate(); + myTableLimiter->deactivate(); + } + if (myGripper->getGripState() == 2 && + myGripper->getBreakBeamState() != 0) + { + printf("###### AcquireBlock: Successful (have cube?)\n"); + setState(STATE_PICKUP_BACKUP); + //handler(); + return; + } + else if (myGripper->getBreakBeamState() != 0) + { + printf("###### AcquireBlock: Successful (cube in gripper?)\n"); + setState(STATE_PICKUP_BLOCK); + //handler(); + return; + } + if (myAcquire->getState() == Acquire::STATE_FAILED || + myStateStartTime.mSecSince() > 35000) + { + printf("###### AcqiureBlock: failed\n"); + setState(STATE_BACKUP); + //handler(); + return; + } + else if (myAcquire->getState() == Acquire::STATE_SUCCEEDED) + { + printf("###### AcquireBlock: successful\n"); + setState(STATE_PICKUP_BLOCK); + //handler(); + return; + } + break; + case STATE_PICKUP_BLOCK: + if (myNewState) + { + printf("!! Pickup block\n"); + myNewState = false; + myAMPTU->panTilt(0, -35); + myAcquire->deactivate(); + myPickUp->activate(); + myPickUp->setChannel(COLOR_BLOCK); + myDriveTo->deactivate(); + myDropOff->deactivate(); + myTableLimiter->deactivate(); + } + if (myPickUp->getState() == PickUp::STATE_FAILED) + { + printf("###### PickUpBlock: failed\n"); + setState(STATE_BACKUP); + //handler(); + return; + } + else if (myPickUp->getState() == PickUp::STATE_SUCCEEDED) + { + printf("###### PickUpBlock: successful\n"); + setState(STATE_PICKUP_BACKUP); + //handler(); + return; + } + break; + case STATE_BACKUP: + if (myNewState) + { + myNewState = false; + myRobot->move(BACKUP_DIST * .75); + myAcquire->deactivate(); + myPickUp->deactivate(); + myDriveTo->deactivate(); + myDropOff->deactivate(); + myTableLimiter->deactivate(); + } + if (myRobot->isLeftMotorStalled() || myRobot->isRightMotorStalled()) + { + printf("###### Backup: Failed, going forwards\n"); + myRobot->clearDirectMotion(); + setState(STATE_FORWARD); + } + if (myStateStartTime.mSecSince() > BACKUP_TIME || + myStateStartPos.findDistanceTo(myRobot->getPose()) > BACKUP_DIST * .95 * .75) + { + printf("###### Backup: Succeeded\n"); + myRobot->clearDirectMotion(); + setState(STATE_ACQUIRE_BLOCK2); + //handler(); + return; + } + break; + case STATE_FORWARD: + if (myNewState) + { + myNewState = false; + myRobot->move(-BACKUP_DIST * .75); + myAcquire->deactivate(); + myPickUp->deactivate(); + myDriveTo->deactivate(); + myDropOff->deactivate(); + myTableLimiter->deactivate(); + } + if (myRobot->isLeftMotorStalled() || myRobot->isRightMotorStalled()) + { + printf("###### Forward: Failed\n"); + myRobot->clearDirectMotion(); + setState(STATE_FAILED); + } + if (myStateStartTime.mSecSince() > BACKUP_TIME || + myStateStartPos.findDistanceTo(myRobot->getPose()) > + ArMath::fabs(BACKUP_DIST * .95 * .75)) + { + printf("###### Forward: Succeeded\n"); + myRobot->clearDirectMotion(); + setState(STATE_ACQUIRE_BLOCK2); + //handler(); + return; + } + break; + case STATE_ACQUIRE_BLOCK2: + if (myNewState) + { + printf("!! Acquire block 2\n"); + myNewState = false; + myAMPTU->panTilt(0, -40); + myAcquire->activate(); + myAcquire->setChannel(COLOR_BLOCK); + myPickUp->deactivate(); + myDriveTo->deactivate(); + myDropOff->deactivate(); + myTableLimiter->deactivate(); + } + if (myGripper->getGripState() == 2 && + myGripper->getBreakBeamState() != 0) + { + printf("###### AcquireBlock2: Successful (have cube?)\n"); + setState(STATE_PICKUP_BACKUP); + //handler(); + return; + } + else if (myGripper->getBreakBeamState() != 0) + { + printf("###### AcquireBlock2: Successful (cube in gripper?)\n"); + setState(STATE_PICKUP_BLOCK2); + //handler(); + return; + } + if (myAcquire->getState() == Acquire::STATE_FAILED || + myStateStartTime.mSecSince() > 35000) + { + printf("###### AcqiureBlock2: failed\n"); + setState(STATE_FAILED); + //handler(); + return; + } + else if (myAcquire->getState() == Acquire::STATE_SUCCEEDED) + { + printf("###### AcquireBlock2: successful\n"); + setState(STATE_PICKUP_BLOCK2); + //handler(); + return; + } + break; + case STATE_PICKUP_BLOCK2: + if (myNewState) + { + printf("!! Pickup block 2\n"); + myNewState = false; + myAcquire->deactivate(); + myPickUp->activate(); + myAMPTU->panTilt(0, -55); + myPickUp->setChannel(COLOR_BLOCK); + myDriveTo->deactivate(); + myDropOff->deactivate(); + myTableLimiter->deactivate(); + } + if (myPickUp->getState() == PickUp::STATE_FAILED) + { + printf("###### PickUpBlock2: failed\n"); + setState(STATE_FAILED); + //handler(); + return; + } + else if (myPickUp->getState() == PickUp::STATE_SUCCEEDED) + { + printf("###### PickUpBlock2: successful\n"); + setState(STATE_PICKUP_BACKUP); + //handler(); + return; + } + break; + case STATE_PICKUP_BACKUP: + if (myNewState) + { + myNewState = false; + myRobot->move(BACKUP_DIST); + myAcquire->deactivate(); + myPickUp->deactivate(); + myDriveTo->deactivate(); + myDropOff->deactivate(); + myTableLimiter->deactivate(); + } + if (myStateStartTime.mSecSince() > BACKUP_TIME || + myStateStartPos.findDistanceTo(myRobot->getPose()) > + ArMath::fabs(BACKUP_DIST * .95)) + { + printf("###### PickUp_BackUp: done\n"); + myRobot->clearDirectMotion(); + setState(STATE_ACQUIRE_DROP_WALL); + //handler(); + return; + } + break; + case STATE_ACQUIRE_DROP_WALL: + if (myNewState) + { + printf("!! Acquire Drop wall, channel %d\n", myDropWall); + myNewState = false; + myAMPTU->panTilt(0, -30); + myAcquire->activate(); + myAcquire->setChannel(myDropWall); + myPickUp->deactivate(); + myDriveTo->deactivate(); + myDropOff->deactivate(); + myTableLimiter->deactivate(); + } + if (myGripper->getGripState() != 2 || + myGripper->getBreakBeamState() == 0) + { + printf("###### AcquireDropWall:: failed (lost cube %d %d)\n", + myGripper->getGripState(), myGripper->getBreakBeamState()); + setState(STATE_BACKUP); + //handler(); + return; + } + if (myAcquire->getState() == Acquire::STATE_FAILED || + myStateStartTime.mSecSince() > 35000) + { + printf("###### AcquireDropWall:: failed\n"); + setState(STATE_FAILED); + //handler(); + return; + } + else if (myAcquire->getState() == Acquire::STATE_SUCCEEDED) + { + printf("###### AcquireDropWall: successful\n"); + setState(STATE_DRIVETO_DROP_WALL); + //handler(); + return; + } + break; + case STATE_DRIVETO_DROP_WALL: + if (myNewState) + { + printf("!! DropOff Drop wall, channel %d\n", myDropWall); + myNewState = false; + myAcquire->deactivate(); + myPickUp->deactivate(); + myDriveTo->deactivate(); + myDropOff->activate(); + myDropOff->setChannel(myDropWall); + myTableLimiter->deactivate(); + } + if (myDropOff->getState() == DropOff::STATE_FAILED) + { + printf("###### DropOffDropWall: failed\n"); + setState(STATE_FAILED); + //handler(); + return; + } + else if (myDropOff->getState() == DropOff::STATE_SUCCEEDED) + { + printf("###### DropOffDropWall: succesful\n"); + setState(STATE_DROP_BACKUP); + //handler(); + return; + } + break; + case STATE_DROP_BACKUP: + if (myNewState) + { + myNewState = false; + myRobot->move(BACKUP_DIST); + myAcquire->deactivate(); + myPickUp->deactivate(); + myDriveTo->deactivate(); + myDropOff->deactivate(); + myTableLimiter->deactivate(); + } + if (myStateStartTime.mSecSince() > BACKUP_TIME || + myStateStartPos.findDistanceTo(myRobot->getPose()) > + ArMath::fabs(BACKUP_DIST * .95)) + { + printf("###### Drop_Backup: done\n"); + myRobot->clearDirectMotion(); + setState(STATE_ACQUIRE_LAP_WALL); + //handler(); + return; + } + break; + case STATE_ACQUIRE_LAP_WALL: + if (myNewState) + { + printf("!! Acquire Lap wall, channel %d\n", myLapWall); + myNewState = false; + myAMPTU->panTilt(0, -30); + myAcquire->activate(); + myAcquire->setChannel(myLapWall); + myPickUp->deactivate(); + myDriveTo->deactivate(); + myDropOff->deactivate(); + myTableLimiter->activate(); + } + if (myAcquire->getState() == Acquire::STATE_FAILED || + myStateStartTime.mSecSince() > 35000) + { + printf("###### AcquireLapWall:: failed\n"); + setState(STATE_SWITCH); + //handler(); + return; + } + else if (myAcquire->getState() == Acquire::STATE_SUCCEEDED) + { + printf("###### AcquireLapWall: successful\n"); + setState(STATE_DRIVETO_LAP_WALL); + //handler(); + return; + } + break; + case STATE_DRIVETO_LAP_WALL: + if (myNewState) + { + printf("!! Driveto Lap wall, channel %d\n", myLapWall); + myNewState = false; + myAcquire->deactivate(); + myPickUp->deactivate(); + myDriveTo->activate(); + myDriveTo->setChannel(myLapWall); + myDropOff->deactivate(); + myTableLimiter->activate(); + } + if (myDriveTo->getState() == DriveTo::STATE_FAILED) + { + printf("###### DriveToLapWall: failed\n"); + setState(STATE_BACKUP_LAP_WALL); + //handler(); + return; + } + else if (myDriveTo->getState() == DriveTo::STATE_SUCCEEDED) + { + printf("###### DriveToLapWall: succesful\n"); + setState(STATE_BACKUP_LAP_WALL); + //handler(); + return; + } + break; + case STATE_BACKUP_LAP_WALL: + if (myNewState) + { + myNewState = false; + myRobot->move(BACKUP_DIST * .75); + myAcquire->deactivate(); + myPickUp->deactivate(); + myDriveTo->deactivate(); + myDropOff->deactivate(); + myTableLimiter->deactivate(); + } + if (myRobot->isLeftMotorStalled() || myRobot->isRightMotorStalled()) + { + printf("###### BackupLapWall: Failed, going forwards\n"); + myRobot->clearDirectMotion(); + setState(STATE_FORWARD_LAP_WALL); + } + if (myStateStartTime.mSecSince() > BACKUP_TIME || + myStateStartPos.findDistanceTo(myRobot->getPose()) > + ArMath::fabs(BACKUP_DIST * .95 * .75)) + { + printf("###### BackupLapWall: Succeeded\n"); + myRobot->clearDirectMotion(); + setState(STATE_SWITCH); + //handler(); + return; + } + break; + case STATE_FORWARD_LAP_WALL: + if (myNewState) + { + myNewState = false; + myRobot->move(-BACKUP_DIST * .75); + myAcquire->deactivate(); + myPickUp->deactivate(); + myDriveTo->deactivate(); + myDropOff->deactivate(); + myTableLimiter->deactivate(); + } + if (myRobot->isLeftMotorStalled() || myRobot->isRightMotorStalled()) + { + printf("###### ForwardLapWall: Failed\n"); + myRobot->clearDirectMotion(); + setState(STATE_FAILED); + } + if (myStateStartTime.mSecSince() > BACKUP_TIME || + myStateStartPos.findDistanceTo(myRobot->getPose()) > + ArMath::fabs(BACKUP_DIST * .95 * .75)) + { + printf("###### ForwardLapWall: Succeeded\n"); + myRobot->clearDirectMotion(); + setState(STATE_SWITCH); + //handler(); + return; + } + break; + + case STATE_SWITCH: + printf("!! Switching walls around.\n"); + tempColor = myDropWall; + myDropWall = myLapWall; + myLapWall = tempColor; + setState(STATE_ACQUIRE_BLOCK); + //handler(); + return; + case STATE_FAILED: + printf("@@@@@ Failed to complete the task!\n"); + myRobot->comInt(ArCommands::SONAR, 0); + ArUtil::sleep(50); + myRobot->comStr(ArCommands::SAY, "\52\77\37\62\42\70"); + ArUtil::sleep(500); + Aria::shutdown(); + myRobot->disconnect(); + myRobot->stopRunning(); + return; + } + +} + +int main(void) +{ + ArSerialConnection con; + ArRobot robot; + int ret; + std::string str; + ArActionLimiterForwards limiter("speed limiter near", 225, 600, 250); + ArActionLimiterForwards limiterFar("speed limiter far", 225, 1100, 400); + ArActionTableSensorLimiter tableLimiter; + ArActionLimiterBackwards backwardsLimiter; + ArActionConstantVelocity stop("stop", 0); + ArSonarDevice sonar; + ArACTS_1_2 acts; + ArPTZ *ptz; + ptz = new ArVCC4(&robot, true); + ArGripper gripper(&robot); + + Acquire acq(&acts, &gripper); + DriveTo driveTo(&acts, &gripper, ptz); + DropOff dropOff(&acts, &gripper, ptz); + PickUp pickUp(&acts, &gripper, ptz); + + + TakeBlockToWall takeBlock(&robot, &gripper, ptz, &acq, &driveTo, &pickUp, + &dropOff, &tableLimiter); + + if (!acts.openPort(&robot)) + { + printf("Could not connect to acts, exiting\n"); + exit(0); + } + Aria::init(); + + robot.addRangeDevice(&sonar); + //con.setBaud(38400); + if ((ret = con.open()) != 0) + { + str = con.getOpenMessage(ret); + printf("Open failed: %s\n", str.c_str()); + Aria::shutdown(); + return 1; + } + + robot.setDeviceConnection(&con); + if (!robot.blockingConnect()) + { + printf("Could not connect to robot... exiting\n"); + Aria::shutdown(); + return 1; + } + + ptz->init(); + ArUtil::sleep(8000); + printf("### 2222\n"); + ptz->panTilt(0, -40); + printf("### whee\n"); + ArUtil::sleep(8000); + robot.setAbsoluteMaxTransVel(400); + + robot.setStateReflectionRefreshTime(250); + robot.comInt(ArCommands::ENABLE, 1); + robot.comInt(ArCommands::SOUNDTOG, 0); + + ArUtil::sleep(200); + robot.addAction(&tableLimiter, 100); + robot.addAction(&limiter, 99); + robot.addAction(&limiterFar, 98); + robot.addAction(&backwardsLimiter, 97); + robot.addAction(&acq, 77); + robot.addAction(&driveTo, 76); + robot.addAction(&pickUp, 75); + robot.addAction(&dropOff, 74); + robot.addAction(&stop, 30); + + robot.run(true); + + Aria::shutdown(); + return 0; +} diff --git a/Legacy/Aria/advanced/sickAutoLogger.cpp b/Legacy/Aria/advanced/sickAutoLogger.cpp new file mode 100644 index 0000000..ca9eb53 --- /dev/null +++ b/Legacy/Aria/advanced/sickAutoLogger.cpp @@ -0,0 +1,217 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#include "Aria.h" + +int main(int argc, char **argv) +{ + bool done; + double distToTravel = 2300; + + // whether to use the sim for the laser or not, if you use the sim + // for hte laser, you have to use the sim for the robot too + bool useSim = false; + // the laser + ArSick sick; + // connection + ArDeviceConnection *con; + // Laser connection + ArSerialConnection laserCon; + // robot + ArRobot robot; + + // set a default filename + //std::string filename = "c:\\log\\1scans.2d"; + std::string filename = "1scans.2d"; + // see if we want to use a different filename + //if (argc > 1) + //Lfilename = argv[1]; + printf("Logging to file %s\n", filename.c_str()); + // start the logger with good values + sick.configureShort(useSim, ArSick::BAUD38400, + ArSick::DEGREES180, ArSick::INCREMENT_HALF); + ArSickLogger logger(&robot, &sick, 300, 25, filename.c_str()); + + // mandatory init + Aria::init(); + + // add it to the robot + robot.addRangeDevice(&sick); + + //ArAnalogGyro gyro(&robot); + + + // if we're not using the sim, make a serial connection and set it up + if (!useSim) + { + ArSerialConnection *serCon; + serCon = new ArSerialConnection; + serCon->setPort(); + //serCon->setBaud(38400); + con = serCon; + } + // if we are using the sim, set up a tcp connection + else + { + ArTcpConnection *tcpCon; + tcpCon = new ArTcpConnection; + tcpCon->setPort(); + con = tcpCon; + } + + // set the connection on the robot + robot.setDeviceConnection(con); + // try to connect, if we fail exit + if (!robot.blockingConnect()) + { + printf("Could not connect to robot... exiting\n"); + Aria::shutdown(); + return 1; + } + + + // set up a key handler so escape exits and attach to the robot + ArKeyHandler keyHandler; + robot.attachKeyHandler(&keyHandler); + + // run the robot, true here so that the run will exit if connection lost + robot.runAsync(true); + + + + // if we're not using the sim, set up the port for the laser + if (!useSim) + { + laserCon.setPort(ArUtil::COM3); + sick.setDeviceConnection(&laserCon); + } + + + // now that we're connected to the robot, connect to the laser + sick.runAsync(); + + + if (!sick.blockingConnect()) + { + printf("Could not connect to SICK laser... exiting\n"); + robot.disconnect(); + Aria::shutdown(); + return 1; + } + +#ifdef WIN32 + // wait until someone pushes the motor button to go + while (1) + { + robot.lock(); + if (!robot.isRunning()) + exit(0); + if (robot.areMotorsEnabled()) + { + robot.unlock(); + break; + } + robot.unlock(); + ArUtil::sleep(100); + } +#endif + + // basically from here on down the robot just cruises around a bit + + robot.lock(); + // enable the motors, disable amigobot sounds + robot.comInt(ArCommands::ENABLE, 1); + + ArTime startTime; + // move a couple meters + robot.move(distToTravel); + robot.unlock(); + startTime.setToNow(); + do { + ArUtil::sleep(100); + robot.lock(); + robot.setHeading(0); + done = robot.isMoveDone(60); + robot.unlock(); + } while (!done); + + /* + // rotate a few times + robot.lock(); + robot.setVel(0); + robot.setRotVel(60); + robot.unlock(); + ArUtil::sleep(12000); + */ + + robot.lock(); + robot.setHeading(180); + robot.unlock(); + do { + ArUtil::sleep(100); + robot.lock(); + robot.setHeading(180); + done = robot.isHeadingDone(); + robot.unlock(); + } while (!done); + + // move a couple meters + robot.lock(); + robot.move(distToTravel); + robot.unlock(); + startTime.setToNow(); + do { + ArUtil::sleep(100); + robot.lock(); + robot.setHeading(180); + done = robot.isMoveDone(60); + robot.unlock(); + } while (!done); + + robot.lock(); + robot.setHeading(0); + robot.setVel(0); + robot.unlock(); + startTime.setToNow(); + do { + ArUtil::sleep(100); + robot.lock(); + robot.setHeading(0); + done = robot.isHeadingDone(); + robot.unlock(); + } while (!done); + + + sick.lockDevice(); + sick.disconnect(); + sick.unlockDevice(); + robot.lock(); + robot.disconnect(); + robot.unlock(); + // now exit + Aria::shutdown(); + return 0; +} + diff --git a/Legacy/Aria/advanced/sickAutoLogger.vcproj b/Legacy/Aria/advanced/sickAutoLogger.vcproj new file mode 100644 index 0000000..01fec3c --- /dev/null +++ b/Legacy/Aria/advanced/sickAutoLogger.vcproj @@ -0,0 +1,177 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/advanced/sickSpinLogger.cpp b/Legacy/Aria/advanced/sickSpinLogger.cpp new file mode 100644 index 0000000..7f6c957 --- /dev/null +++ b/Legacy/Aria/advanced/sickSpinLogger.cpp @@ -0,0 +1,162 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#include "Aria.h" + +int main(int argc, char **argv) +{ + bool done; + double distToTravel = 2300; + + // whether to use the sim for the laser or not, if you use the sim + // for hte laser, you have to use the sim for the robot too + bool useSim = false; + // the laser + ArSick sick; + // connection + ArDeviceConnection *con; + // Laser connection + ArSerialConnection laserCon; + // robot + ArRobot robot; + + // set a default filename + //std::string filename = "c:\\log\\1scans.2d"; + std::string filename = "1scans.2d"; + // see if we want to use a different filename + //if (argc > 1) + //Lfilename = argv[1]; + printf("Logging to file %s\n", filename.c_str()); + // start the logger with good values + sick.configureShort(useSim, ArSick::BAUD38400, + ArSick::DEGREES180, ArSick::INCREMENT_HALF); + ArSickLogger logger(&robot, &sick, 300, 25, filename.c_str()); + + // mandatory init + Aria::init(); + + // add it to the robot + robot.addRangeDevice(&sick); + + //ArAnalogGyro gyro(&robot); + + + // if we're not using the sim, make a serial connection and set it up + if (!useSim) + { + ArSerialConnection *serCon; + serCon = new ArSerialConnection; + serCon->setPort(); + //serCon->setBaud(38400); + con = serCon; + } + // if we are using the sim, set up a tcp connection + else + { + ArTcpConnection *tcpCon; + tcpCon = new ArTcpConnection; + tcpCon->setPort(); + con = tcpCon; + } + + // set the connection on the robot + robot.setDeviceConnection(con); + // try to connect, if we fail exit + if (!robot.blockingConnect()) + { + printf("Could not connect to robot... exiting\n"); + Aria::shutdown(); + return 1; + } + + + // set up a key handler so escape exits and attach to the robot + ArKeyHandler keyHandler; + robot.attachKeyHandler(&keyHandler); + + // run the robot, true here so that the run will exit if connection lost + robot.runAsync(true); + + + + // if we're not using the sim, set up the port for the laser + if (!useSim) + { + laserCon.setPort(ArUtil::COM3); + sick.setDeviceConnection(&laserCon); + } + + + // now that we're connected to the robot, connect to the laser + sick.runAsync(); + + + if (!sick.blockingConnect()) + { + printf("Could not connect to SICK laser... exiting\n"); + robot.disconnect(); + Aria::shutdown(); + return 1; + } + +#ifdef WIN32 + // wait until someone pushes the motor button to go + while (1) + { + robot.lock(); + if (!robot.isRunning()) + exit(0); + if (robot.areMotorsEnabled()) + { + robot.unlock(); + break; + } + robot.unlock(); + ArUtil::sleep(100); + } +#endif + + // basically from here on down the robot just cruises around a bit + + robot.lock(); + // enable the motors, disable amigobot sounds + robot.comInt(ArCommands::ENABLE, 1); + + // move a couple meters + robot.setRotVel(3000); + robot.unlock(); + + ArUtil::sleep(15 * 1000); + + robot.lock(); + robot.disconnect(); + robot.unlock(); + keyHandler.restore(); + exit(1); + + // now exit + return 0; +} + diff --git a/Legacy/Aria/advanced/sickSquareLogger.cpp b/Legacy/Aria/advanced/sickSquareLogger.cpp new file mode 100644 index 0000000..e55f980 --- /dev/null +++ b/Legacy/Aria/advanced/sickSquareLogger.cpp @@ -0,0 +1,214 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#include "Aria.h" + +ArRobot *robot; + +void printer(void) +{ + printf("vel %5.0f rot vel %5.0f\n", robot->getVel(), robot->getRotVel()); +} + + +int main(int argc, char **argv) +{ + double speed = 1000; + double squareSide = 2000; + + // whether to use the sim for the laser or not, if you use the sim + // for hte laser, you have to use the sim for the robot too + // robot + robot = new ArRobot; + // the laser + ArSick sick; + // set up our simpleConnector + ArSimpleConnector simpleConnector(&argc, argv); + + // set up a key handler so escape exits and attach to the robot + ArKeyHandler keyHandler; + robot->attachKeyHandler(&keyHandler); + + // parse its arguments + if (simpleConnector.parseArgs()) + { + simpleConnector.logOptions(); + keyHandler.restore(); + exit(1); + } + + // if there are more arguments left then it means we didn't + // understand an option + /* + if (argc > 1) + { + simpleConnector.logOptions(); + keyHandler.restore(); + exit(1); + } + */ + + // set a default filename + //std::string filename = "c:\\log\\1scans.2d"; + std::string filename = "1scans.2d"; + // see if we want to use a different filename + //if (argc > 1) + //Lfilename = argv[1]; + printf("Logging to file %s\n", filename.c_str()); + // start the logger with good values + + //sick.configureShort(useSim, ArSick::BAUD38400, ArSick::DEGREES180, ArSick::INCREMENT_HALF); + ArSickLogger logger(robot, &sick, 300, 25, filename.c_str()); + + // mandatory init + Aria::init(); + + // add it to the robot + robot->addRangeDevice(&sick); + + //ArAnalogGyro gyro(robot); + + + // set up the robot for connecting + if (!simpleConnector.connectRobot(robot)) + { + printf("Could not connect to robot->.. exiting\n"); + Aria::shutdown(); + return 1; + } + + robot->setRotVelMax(300); + robot->setRotAccel(300); + robot->setRotDecel(300); + + robot->setAbsoluteMaxTransVel(2000); + robot->setTransVelMax(2000); + robot->setTransAccel(500); + robot->setTransDecel(500); + /* + robot->comInt(82, 30); // rotkp + robot->comInt(83, 200); // rotkv + robot->comInt(84, 0); // rotki + robot->comInt(85, 15); // transkp + robot->comInt(86, 450); // transkv + robot->comInt(87, 4); // transki + */ + robot->comInt(82, 30); // rotkp + robot->comInt(83, 200); // rotkv + robot->comInt(84, 0); // rotki + robot->comInt(85, 30); // transkp + robot->comInt(86, 450); // transkv + robot->comInt(87, 4); // transki + // run the robot, true here so that the run will exit if connection lost + robot->runAsync(true); + + + + // set up the laser before handing it to the laser mode + simpleConnector.setupLaser(&sick); + + // now that we're connected to the robot, connect to the laser + sick.runAsync(); + + if (!sick.blockingConnect()) + { + printf("Could not connect to SICK laser... exiting\n"); + robot->disconnect(); + Aria::shutdown(); + return 1; + } + + robot->lock(); + robot->addUserTask("printer", 50, new ArGlobalFunctor(&printer)); + robot->unlock(); + +#ifdef WIN32 + // wait until someone pushes the motor button to go + while (1) + { + robot->lock(); + if (!robot->isRunning()) + exit(0); + if (robot->areMotorsEnabled()) + { + robot->unlock(); + break; + } + robot->unlock(); + ArUtil::sleep(100); + } +#endif + + // basically from here on down the robot just cruises around a bit + + printf("Starting moving\n"); + robot->lock(); + // enable the motors, disable amigobot sounds + robot->comInt(ArCommands::ENABLE, 1); + robot->setHeading(0); + robot->setVel(1000); + robot->unlock(); + + ArUtil::sleep(speed / 500.0 * 1000.0); + printf("Should be up to speed, moving on first side\n"); + ArUtil::sleep(squareSide / speed * 1000); + printf("Turning to second side\n"); + robot->lock(); + robot->setHeading(90); + robot->setVel(speed); + robot->unlock(); + ArUtil::sleep(squareSide / speed * 1000); + printf("Turning to third side\n"); + robot->lock(); + robot->setHeading(180); + robot->setVel(speed); + robot->unlock(); + ArUtil::sleep(squareSide / speed * 1000); + printf("Turning to last side\n"); + robot->lock(); + robot->setHeading(-90); + robot->setVel(speed); + robot->unlock(); + ArUtil::sleep(squareSide / speed * 1000); + printf("Pointing back original direction and stopping\n"); + robot->lock(); + robot->setHeading(0); + robot->setVel(0); + robot->unlock(); + ArUtil::sleep(300); + + printf("Stopped\n"); + sick.lockDevice(); + sick.disconnect(); + sick.unlockDevice(); + robot->lock(); + robot->disconnect(); + robot->unlock(); + + // now exit + Aria::shutdown(); + return 0; +} + diff --git a/Legacy/Aria/bin/SIMULATOR_README.txt b/Legacy/Aria/bin/SIMULATOR_README.txt new file mode 100644 index 0000000..dafd0fc --- /dev/null +++ b/Legacy/Aria/bin/SIMULATOR_README.txt @@ -0,0 +1,3 @@ +SRIsim is no longer included with Aria. There is now a separately +downloadable MobileSim simulator at our support webpage +http://robots.activmedia.com diff --git a/Legacy/Aria/docs/figures/Amigobot.jpg b/Legacy/Aria/docs/figures/Amigobot.jpg new file mode 100644 index 0000000000000000000000000000000000000000..861a188dcac8bbe1d09ddeb738d08b7e1164684e GIT binary patch literal 15525 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 V&oWXo{h+o)%uTIL>WnTX{0}463L5|b literal 0 HcmV?d00001 diff --git a/Legacy/Aria/docs/figures/ArRobot_Task_Cycle.dia b/Legacy/Aria/docs/figures/ArRobot_Task_Cycle.dia new file mode 100644 index 0000000000000000000000000000000000000000..7bdc31958d0686559cf4e8fd7e7e6f700bdd8cbc GIT binary patch literal 3636 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 E1F3mfMgRZ+ literal 0 HcmV?d00001 diff --git a/Legacy/Aria/docs/figures/MobileSim_with_laser.png b/Legacy/Aria/docs/figures/MobileSim_with_laser.png new file mode 100644 index 0000000000000000000000000000000000000000..c15784c04be428a47bb4dc2aecd9b8df2cf5b999 GIT binary patch literal 27783 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 M8C@*Wx^eIS0Z=a^lK=n! literal 0 HcmV?d00001 diff --git a/Legacy/Aria/docs/figures/Robot_Communication_Options.png b/Legacy/Aria/docs/figures/Robot_Communication_Options.png new file mode 100644 index 0000000000000000000000000000000000000000..fc59a5acc2c935e6bbc4c207b04890530bfa41e2 GIT binary patch literal 167992 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 bI>b(_f6#C8nCoUDzUJ$j=v~sa+x0&HypjOP literal 0 HcmV?d00001 diff --git a/Legacy/Aria/docs/figures/Robot_Communications_Options.dia b/Legacy/Aria/docs/figures/Robot_Communications_Options.dia new file mode 100644 index 0000000000000000000000000000000000000000..294a38ff07db560fa1c1b5a2ddca882d76f091ad GIT binary patch literal 6864 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 K%3=a5z5xIa_(;Y8 literal 0 HcmV?d00001 diff --git a/Legacy/Aria/docs/overview.dox b/Legacy/Aria/docs/overview.dox new file mode 100644 index 0000000..8faf5c4 --- /dev/null +++ b/Legacy/Aria/docs/overview.dox @@ -0,0 +1,1879 @@ + +/** + @defgroup ImportantClasses Important Classes + @brief These classes are essential far all programs using Aria to control a robot. + + @defgroup OptionalClasses Optional Classes + @brief These classes provide additional features that may be used in some programs. + + @defgroup ActionClasses Predefined ArAction Classes + @brief These classes implement component behaviors as ArAction subclasses (see ArAction and the overview for more details on actions) + + @defgroup DeviceClasses Device Interface Classes + @brief These classes provide interfaces to hardware devices such as sensors. Some use +"connector" objects for configure, connection and sometimes to create the +interface objects. Read documentation fro details. + + @defgroup UtilityClasses Utility Classes + @brief These classes provide useful cross-platform system tools, math and string tools, and other miscellaneous programming utilities. + + @defgroup MTX MTX/Pioneer LX Specific Classes + @brief These classes are only used on Pioneer LX and other MTX-type robots. +*/ + +/** + \mainpage ARIA Developer's Reference Manual + +MobileRobots Advanced Robotics Interface for Applications (ARIA) + +

+Copyright 2002, 2003, 2004, 2005 ActivMedia Robotics, LLC. All rights reserved.
+Copyright 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. All rights reserved.
+Copyright 2011, 2012, 2013 Adept Technology. All rights reserved. +

+ + +\htmlonly + +\endhtmlonly + +\section toc Contents +
    +
  • \ref intro +
      +
    • \ref javapython
    • +
    • \ref matlab
    • +
    +
  • +
  • \ref licensing
  • +
  • \ref AriaPackage +
      +
    • \ref arpack
    • +
    • \ref arpackother
    • +
    +
  • +
  • \ref codingConventions
  • +
  • \ref arCliServ
  • +
  • \ref commClasses +
      +
    • \ref connectRobot
    • +
    +
  • +
  • \ref HardwareConfiguration +
      +
    • \ref RobotParameterFiles
    • +
    • \ref RuntimeOptions
    • +
    +
  • +
  • \ref robot +
      +
    • \ref commands
    • +
    • \ref packetHandlers
    • +
    • \ref CommandPackets
    • +
    • \ref syncRobot
    • +
    • \ref stateReflection
    • +
    • \ref callback
    • +
    +
  • +
  • \ref ClientCommands +
      +
    • \ref robotDirectCommands
    • +
    • \ref robotMotionCommands
    • +
    • \ref actions
    • +
    • \ref actionDesired
    • +
    • \ref resolvers
    • +
    • \ref predefinedActions
    • +
    • \ref actionInteractions
    • +
    +
  • +
  • \ref rangeDevices
  • +
  • \ref functors
  • +
  • \ref userInput
  • +
  • \ref threading +
      +
    • \ref syncObject
    • +
    • \ref asynctasks
    • +
    +
  • +
  • \ref aria
  • +
+ +\subsection tocToolbox Additional tools in the ARIA toolbox: +
    +
  • \ref devices
  • +
  • \ref utility
  • +
  • \ref arconfig
  • +
  • \ref sockets
  • +
  • \ref arinfogroup
  • +
  • \ref maps
  • +
  • \ref ArNetworking
  • +
  • \ref sound
  • +
+ +\subsection tocDevHelp Helpful information about C++ development with ARIA: +
    +
  • \ref emacs
  • +
  • \ref noneverydayC +
      +
    • \ref stl
    • +
    • \ref defaultArgs
    • +
    • \ref constructorChaining
    • +
    • \ref charsAndStrings
    • +
    • \ref arexport
    • +
    • \ref exceptions
    • +
    +
  • +
+ + +\subsection tocAdv Advanced Usage: +
    +
  • \ref pieceMealUse
  • +
  • \ref hardConnectRobot +
      +
    • \ref openDevice
    • +
    • \ref devConnect
    • +
    • \ref connrw
    • +
    +
  • +
+ + \section intro Introduction + +Welcome to ARIA, an object-oriented, robot control +applications-programming interface for MobileRobots (and ActivMedia) +intelligent mobile robots. + +Written in the C++ language, ARIA is client-side software for easy, +high-performance access to and management of the robot, as well +as to the many accessory robot sensors and effectors. ARIA includes +many useful utilities for general robot programming and cross-platform +(Linux and Windows) programming as well. + +You can access ARIA at different +levels, from simply sending commands to the robot through ArRobot +to development of higher-level intelligent behavior using @ref actions. +(For a description of how to integrate parts of ARIA with +your other code, see \ref pieceMealUse.) + +An auxiliary library called ArNetworking is also included with ARIA. +ArNetworking provides an easy to use, extensible framework for communication with +remote programs over a network, such as MobileEyes. + +This page contains an overview of ARIA. Read this overview to become familiar +with the ARIA library and how to get started using it. +Click a class or function link to view its details. +A selection of the most important ARIA classes is listed in @ref +ImportantClasses in the menu to the left, as well as @ref OptionalClasses, @ref +DeviceClasses, @ref UtilityClasses and @ref ActionClasses. All +classes are available in the full class list and hierarchy links on the left. + +New users should view this document along with the ARIA examples, README.txt, and +your robot's operating manual as well. + +You can download new versions of ARIA from http://robots.mobilerobots.com/ARIA + + \subsection whouses What is ARIA? How does it relate to other MobileRobots software? + +ARIA is a programming library (SDK) for C++ programmers +who want to access their MobileRobots or ActivMedia platform and accessories at either +a high or low level. +ARIA is also for those who have already prepared robot-control software and want to +deploy it on one or more MobileRobots or ActivMedia mobile robot platforms. +ARIA also provides various tools useful for robot programming in general. + +In addition to providing a complete robot and accessory API to developers, +ARIA also serves as a +foundation for other libraries providing additional +capabilities: For creating applications with built-in advanced navigation routines, +you can use the additional ARNL or SONARNL libraries. To communicate with the +MobileEyes graphical display/control program, or for general +communication over the network, you can use ArNetworking. ArNetworking is +included with ARIA in the ArNetworking directory. +See the ArNetworking Reference +Manual for more information. + +Other libraries are available as well for specialized purposes, including +speech synthesis and recognition, audio stream recording, playback and network +transmission, video image capture, color tracking, etc. +Browse the MobileRobots support web pages http://www.activrobots.com and +http://robots.mobilerobots.com for these libraries and other mobile robotics +resources, including the MobileSim simulator which can be used used for +programming and debugging before driving an actual robot. + +Programmers working with ARIA should be familiar with +using typical C++ concepts, including +using classes and objects with simple inheritance, pointers, memory management, +the STL containers, and the compiling and linking process. (See below +for notes about accessing ARIA from Python or Java.) Experience with +multiple threads is also helpful. + +Read on for information about the key pieces of ARIA and how to get started. +See the README.txt file for a brief practical overview of ARIA software development +on Linux and Windows. Many example programs are available as well. + + \subsection javapython Java and Python + +ARIA, ArNetworking, ARNL and SONARNL now work in Java and Python! Each library has a +Java wrapper and a Python +wrapper. This means that you can write +ARIA programs in Java or Python almost as if ARIA itself was written in these +languages. This wrapper is automatically generated by SWIG, +and the Python and Java APIs are almost the same as the +C++ library. Exceptions will be noted in this reference manual. + +Read javaExamples/README.txt file for directions on how to use +the Java wrapper and pythonExamples/README.txt for directions +on how to use the Python wrapper, and likewise see ArNetworking/javaExamples +and ArNetworking/pythonExamples for information about and examples of the +ArNetworking Java and Python wrappers. + + \subsection matlab Matlab + +A subset of essential robot control and accessor functions from ARIA are now also available for use in +Matlab. See matlab/README.txt for instructions on how to create +and use this interface, and notes on what is available and what its requirements and supported platforms are. + + \section licensing License and Sharing + +ARIA is released under the GNU Public License, which means that the entire +source code is included and may be copied. However, if you +distribute any work which incorporates ARIA, you must also distribute the entire +source code to that work, including ARIA with any modifications you may have +made, under the same license terms. Read the included license text for +details. We open-sourced ARIA under the GPL not only for your convenience, +but also so that you could share your enhancements to the software with the +robotics community (you can share them via the aria-users mailing list). If +you wish your enhancements to make it into the ARIA baseline, you will +need to assign the copyright on those changes to MobileRobots, contact +aria-support@mobilerobots.com with these changes or with questions about +this. + +Accordingly, please do share your work, and please sign up for the +exclusive ARIA-users@mobilerobots.com newslist so that you can benefit +from others' work, too. + +For answers to frequently asked questions about what the GPL allows +and requires, see http://www.gnu.org/licenses/gpl-faq.html . + +On the other hand, ARIA may be also licensed for proprietary, closed-source applications. +Contact sales@mobilerobots.com for details. + + \section AriaPackage The ARIA Package + + \subsection arpack ARIA/ + +\htmlonly +
+
README.txt
+
Getting started; essential info. Includes tips on installing + ARIA, rebuilding it, building example programs, and + using platform development tools. + Also see the README files in the examples/, advanced/, and tests/ + directories.
+ +
LICENSE.txt
+
GPL license for redistributing ARIA or programs using ARIA
+ +
Changes.txt
+
Summary of changes featured in each version of ARIA
+ +
INSTALL.txt
+
Detailed instructions for installing ARIA on different platforms
+ +
docs/
+
Library reference documentation (this manual).
+ +
examples/
+
ARIA example programs -- a good place to start. Also see the Examples + section of this reference manual; selected examples are also linked from + classes and methods used by those examples. +
+ + +
include/
+
Header files for ARIA
+ +
src/
+
ARIA C++ source code files
+ +
params/
+
Robot definition (parameter) files (p3dx.p, for example). + Mostly used transparently by ARIA, but can be customized + if neccesary. +
+ +
lib/
+
Win32 DLL export library (.lib) files and Linux shared library (.so) + files
+ +
bin/
+
Win32 binaries and DLLs
+
+\endhtmlonly + + \subsection arpackother Other ARIA Files of Note + +\htmlonly +
+
Aria.sln
MS Visual C++ workspace for building + ARIA libraries and examples
+
Aria.vcproj
MSVC++ project file used in Aria.sln + for the ARIA library.
+
Makefile
Linux makefile for building ARIA and + examples
+
Makefile.dep
Linux file dependency rules (used internally + by Makefile)
+
utils/
+
Utility programs, used internally by MobileRobots software development, + plus some file format conversion tools +
+
ArNetworking/
Networking infrastructure library, + included with ARIA, but a separate library
+
tests/
Test files, somewhat esoteric but + useful during ARIA development
+
advanced/
Advanced demos and examples, not + always for the faint of heart (or ARIA novice)
+
pythonExamples/
Information about and examples of + using ARIA via Python
+
javaExamples/
Information about and examples of + using ARIA via Java
+
python/
Contains ARIA Python module and + other files
+
java/
Contains ARIA Java package and other + files
+
+\endhtmlonly + + \section codingConventions Documentation and Coding Convention + +ARIA follows the following coding conventions: + +
    +
  1. Class names begin with "Ar" and are in mixed case.
  2. +
  3. Enums and other constants either begin with a capital letter or are all in caps.
  4. +
  5. Avoid preprocessor definitions whenever possible (instead using enumerations or inline methods)
  6. +
  7. Member variables in classes are prefixed with 'my'.
  8. +
  9. Static variables in classes are prefixed with 'our'.
  10. +
  11. Member function names start with a lower case.
  12. +
  13. Capitalize each word except the first one in a variable or method name; likeThisForExample
  14. +
  15. All classes may be used in a multi-threaded program, either by being + inherently threadsafe, or (more typically) by providing an API for protecting it by + locking mutexes. See class documentation for notes on access from + multiple threads. +
  16. +
+ +@sa @ref emacs + + \section arCliServ ARIA-Robot Client-Server Relationship + +For those of you who are familiar with SRI International's Saphira +software and ActivMedia Robotics' mobile robots and their related +technologies, the underlying client-server control architecture for +the mobile platform, sensors, and accessories hasn't changed much in +ARIA. It's just gotten a lot better and more accessible. + +The core mobile robot "server" proceses are implemented in the Pioneer and AmigoBot Operating +System firmware (ARCOS, AROS, P2OS, AmigOS, etc.), which runs +on the robot's microcontroller. +These proceses manage the more critical and time-sensitive low-level tasks of robot control and operation, including +maintaining requested motion and heading state and estimating position from odometry, as well as acquiring sensor information +(sonar and compass, for example) and driving many accessory components like +the PTZ camera, TCM2 compass/inclinometer, and the Pioneer 5-DOF +Arm. The robot, its microcontroller, firmware, and integrated devices (such as +sonar) together are sometimes referred +to as the "robot platform". The robot firmware does not, however, perform any high-level robotic tasks. +Rather, it is the job of an intelligent client running on a connected +PC to perform these application-level robotic control strategies and tasks, +such as obstacle detection and avoidance, sensor fusion, localization, +features recognition, mapping, intelligent navigation, PTZ camera +control, Arm motion, and much more. ARIA's role is to support these client applications +and their communcation with the robot firmware, to any devices that connect to +the computer rather than the robot platform, and to remote software via a +network. + +The heart of ARIA is the ArRobot class. This class manages the communication +cycle with the firmware, receiving and providing access to data about the +robot platform's operating state, +triggering tasks within that cycle and determining commands to be sent back +to the robot (see @ref actions and @ref syncRobot). It also serves as a container for references to other ARIA objects +(such as range devices) and a toolbox of general functions related to the mobile +robot. + +Through its @ref actions infrastructure, ARIA provides a powerful +mechanism for combining independent behaviors to achieve +coordinated motion control and intelligent guidance. With +Actions, you easily implement the motion aspects of applications +such as guided teleoperation, visual tracking, autonomous navigation, etc. + +Other ARIA classes provide interfaces to +access and control accessory sensors and devices, +including operation and state reflection for sonar and laser range +finders, pan-tilt units, arms, inertial navigation devices, and many +others. + + + \section commClasses Robot Communication + +One of the most important functions of ARIA, and one of the first and +things that your application program must do, is to establish +the connection between an ArRobot object instance and the robot platform +operating system (firmware). + +In addition to the mobile robot itself, some accessories, +such as the sonar, the Pioneer Gripper, PTZ cameras, Pioneer Arm, compass, and others, are +internally connected to the robot microcontroller's AUX or digital I/O +lines, and use the robot connection as well (therefore the interface +classes for these objects require a reference to an ArRobot object, +which must be connected for the devices to work). Other accessories, such as +the SICK laser, video capture cards, etc. are connected directly to the onboard +computer. + +There are several ways to connect a computer running ARIA to the robot's +microcontroller or to a simulator. +This figure provides +a schematic overview of the many ARIA-robot communication options. +Consult your robot Operations Manual for more information about computer-robot +hardware setup and communications. + + \subsection connectRobot Connecting with a Robot or the Simulator + +An ArRobotConnector object is used to set up and +perform the connection to the robot, based on robot parameter files, +and run-time configuration via command-line +arguments (see \ref HardwareConfiguration). Similarly, ArLaserConnector +is used to connect to laser rangefinding devices. (Other connectors are +also used for other kinds of accessory devices.) +ArRobotConnector and ArLaserConnector are used in most of the example programs, including +@ref simpleConnect.cpp, @ref wander.cpp, and @ref demo.cpp. (Some +example still use the older ArSimpleConnector). +ArRobotConnector will first try to connect to +a simulator on a local TCP port, and if no simulator is running, it will then +connect to the robot on a local serial port. +This makes it easy to develop and debug your program using the simulator, then +simply copy it onto the robot's computer and run without modification. +ArRobotConnector also parses some command line arguments if supplied, which +can explicitly specify a remote hostname and/or port to connect with via TCP, +or to specify an alternate local serial port to use for robot connection, +as well as other options. If a program uses ArRobotConnector, running it +with the "-help" command line argument will print a list of options. + +Here is an example which uses ArRobotConnector to connect the ArRobot and +ArLaserConnector to connect to a laser rangefinder. +@code +#include "Aria.h" +int main(int argc, char** argv) +{ + Aria::init(); + ArArgumentParser parser(&argc, argv); + parser.loadDefaultArguments(); + ArRobot robot; + ArRobotConnector robotConnector(&parser, &robot); + + // Try connecting to the robot. + if(!robotConnector.connectRobot(&robot)) + { + // Error! + ArLog::log(ArLog::Terse, "Error, could not connect to robot.\n"); + robotConnector.logOptions(); + Aria::exit(1); + } + + // Run the ArRobot processing/task cycle thread. + robot.runAsync(true); + + ArLaserConnector laserConnector(&parser, &robot, &robotConnector); + + // Parse command line arguments (there may be arguments specifying + // what lasers to try to connect to) + if(!Aria::parseArgs()) + { + Aria::logOptions(); + Aria::exit(2); + } + + // Try connecting to all lasers specified in the robot's parameter file + // and in command line arguments + if(!laserConnector.connectLasers()) + { + ArLog::log(ArLog::Terse, "Error, could not connect to lasers.\n"); + Aria::logOptions(); + Aria::exit(3); + } + + // Now we're connected, and the robot and laser objects are running in + // background threads reading and processing data. (You can get access + // to the ArLaser objects using ArRobot::findLaser() or + // ArRobot::getLaserMap(). + ... +@endcode + + + \section HardwareConfiguration Specifying Details about Robot and Device Connections + +On any individual robot, there are many possible combinations of hardware +accessories, and several options for connecting accessories to the robot +and computer. The device interface and connector classes (ArRobotConnector, +ArLaserConnector, etc.) need information about what devices are connected +and how they are connected, especially if they vary from their defaults. + +This information is obtained from two sources: ARIA's parameter file(s) for +the robot, +and from program runtime arguments via ArArgumentParser (which reads +default program argument values from /etc/Aria.args (on Linux) and the ARIAARGS +environment variable (on both Linux and Windows), then reads current +program arguments from the command line). + +Some examples of hardware configuration options that may need to be +specified are what kinds of laser rangefinders are connected, and +to which ports, laser connection and data parameters, what kind +of GPS is connected and to what port (if a GPS is used). Furthermore, +if you are connecting to a robot over a wireless TCP connection from an offboard +computer rather than an onboard computer, you must provide a runtime +command line argument giving the robot network name (and optionally port number). + +\subsection RobotParameterFiles Robot Parameter Files + +Robot parameter files are read by ARIA after a connection to the robot is +made and the robot type and individual name are obtained (see @ref +connectRobot). These files provide ARIA with robot-specific conversion factors +and physical charactaristics, as well as accessory device connection information. + +See @ref ParamFiles for more information. + +\subsection RuntimeOptions Program Runtime Options + +Various classes in ARIA (notably the Connector classes) use program runtime +options (a/k/a command-line arguments). + +See @ref CommandLineOptions for a summary of all the options that various +classes in ARIA accept. + +Arguments are provided to other ARIA classes by an ArArgumentParser +object. All ARIA programs should create an ArArgumentParser, call +ArArgumentParser::loadDefaultArguments() to load any arguments that +appear in the /etc/Aria.args file or ARIAARGS environment variable, +and provide that object to any class constructors that accept it. +Once all such objects are created, you can call Aria::logOptions() to +print out a summary of all relevant options (e.g. call Aria::logOptions(); +and Aria::exit() if ArArgumentParser::checkHelpAndWarnUnparsed() returns +true, because the user gave the --help option). Finally, call +Aria::parseArgs() to cause each of them to check the ArArgumentParser for +their respective arguments. + + + + \section robot ArRobot + +ArRobot is the heart of an ARIA program, acting as +robot communications gateway, central manager +of robot state, tool for synchronizing program-added tasks and callbacks, +ArAction objects, etc. + + \subsection commands Client Commands and Server Information Packets + +Client-server communications between ARIA and a +mobile robot platform or simulator use packet-based +protocols. (In this context, the client is the software using +ARIA to operate a robot, and the server is the robot platform's firmware.) +The details of the client-server protocol can be found in your robot's +Operations or Technical Manual. + +ArRobot (using the +ArDeviceConnection, ArRobotPacketReceiver, ArRobotPacketSender, ArRobotPacket, +and ArSerialConnection classes) +handles the details of constructing and sending a +command packets to the robot as well as receiving and decoding +the packets recieved from the robot server. + + \subsection packetHandlers Packet Handlers + +Server Information Packets (SIPs) are packets sent by the robot server +containing information updates about the +robot and its accessories. +The standard SIP is sent by the +robot to a connected client automatically every 100 milliseconds +(this frequency may be configured in the firmware parameters). +It contains the robot's current position and estimates, +current translational and rotational speeds, sonar +reading updates, battery voltage, analog and digital I/O states, and more. +These data are stored and used +by ArRobot's State Reflection (see \ref stateReflection +below) and are accessible via methods of the ArRobot class. +(Note, within the ArRobot source code the standard SIP is also called a "motor" packet.) + +Extended SIPs use the same packet format as the +standard SIP, but with a different packet "type" code. Examples of extended +SIPs include I/O port data, data from the gripper, or special robot +data like raw encoder data. +To receive extended SIPs, the client program +must request them. In ARIA, this is normally done by the device interface +classes (see @ref devices) when they are initialized or when the robot connection is established. +You may also attach your own custom packet handlers to ArRobot using +ArRobot::addPacketHandler(). You can use this to do your own additional processing +of extended SIP data, or if creating an alternate implementation of a device +interface class. + + \subsection CommandPackets Command Packets + +To control the robot platform, a client program sends command packets +through the robot connection. This can be done using %ArRobot's @ref +robotMotionCommands, using @ref actions, or at the most basic level, +@ref robotDirectCommands. +Each of these methods results in command packets sent to +the robot. This means that if both Actions and motion commands are used, +or if independent program modules are sending motion commands, they may conflict. +See \ref ClientCommands below for more about sending motion commands. + + + \subsection syncRobot Robot Synchronization Cycle + +The standard SIP is sent on a constant cycle, and reception of this +SIP triggers a new iteration of ArRobot's +synchronized task processing cycle. +This cycle consists of a series of tasks, +including SIP packet handling, invocation of sensor interpretation tasks, action handling and +resolution, state reflection, and invocation of user tasks, in that order. +Since the task cycle is (normally) triggered by the +reception of each SIP (unless the robot platform begins to fails to send SIPs +or the task cycle is explicitly dissasociated from the robot connection -- see +below), each task will be invoked in a predictable order, +have the most recent data to act upon, no task will miss an opportunity +to use a SIP, and as long as the tasks do not take too much time to execute, +each SIP is handled as soon as possible after the robot sends it. + +@image html ArRobot_Task_Cycle.png Overview of the ArRobot task cycle + +To begin the processing cycle, call ArRobot::run() to enter +the cycle synchronously, or ArRobot::runAsync() to run the cycle +in a new background thread. ArRobot::stopRunning() stops the +processing cycle. + +ArRobot provides methods to add your own sensor-interpretation +and generic user task callbacks. To add a task callback, create an ArFunctor +function object (see \ref functors) and +then add it using ArRobot::addSensorInterpTask() or +ArRobot::addUserTask(). These tasks +can be removed using ArRobot::remSensorInterpTask() or +ArRobot::remUserTask(). + +ArRobot locks it's mutex (see ArRobot::lock() and ArRobot::unlock()) during +each iteration of the task cycle, so your task callbacks must not lock this +mutex--a deadlock will occur. +(However, locks must still be used for safe access to any other thread +or ArAsyncTask, such as lasers and other range devices, or ARNL's planning or +localization tasks.) This mutex lock protects ArRobot data from +modification by other threads (if they correctly use the lock during access), +and interruption of the series of tasks. So if you access ArRobot from any other thread (including the main +thread, if you used ArRobot::runAsync() to run the task cycle), you must +use ArRobot::lock() and ArRobot::unlock() to lock and unlock the robot before +and after any method call or use of any data in ArRobot. + +It is also possible to run the processing cycle without a connection to a robot, +if desired. +This alternative cycle is not triggered by receiving a packet, instead it has its own +steady, "chained" cycle time (default is 100 milliseconds which you may +examine and reset with ArRobot::getCycleTime() and +ArRobot::setCycleTime()). +You may also explicitly disassociate ArRobot's processing cycle from incoming +SIP processing at any time by calling ArRobot::setCycleChained() ("Chained" means that it is +the end of a previous cycle that triggers the next after suitable delay to meet +the desired cycle frequency). However, in doing so, +you may degrade performance, as the robot's cycle will only be +run every ArRobot::getCycleTime() milliseconds, and each time only the most recently +read (oldest) SIP is used (even if the robot has sent more than one since the +last cycle). + + +ArRobot's synchronization task list is ipmlemented as a tree, with five +major branches. Though it is uncommon to do so, a client program may modify this +tree or disable branch tasks of the tree. +If a particular task is disabled, none of its +children will be called. +The root of the task tree can be obtained by calling ArRobot::getSyncTaskRoot(), +which returns an ArSyncTask object. + + +@warning A user task or sensor interpretation task must run quickly. If one or more +user tasks or actions runs such that the task cycle takes too long (more that 100ms) +then the performance and behavior of the robot and of ARIA-robot communications +will be negatively affected. In particular, do not call any functions that +could block or wait for an unknown amount of time (such as locking a mutex +that could be locked for a long time by another thread) +or do any long loops waiting for a condition. Long-running activity can be performed +in a separate asynchronous thread (See ArASyncTask) instead, and results can be +shared with the user task via storage which is protected by a mutex only during +immediate reading and writing of the storage variables. + + + \subsection stateReflection State Reflection + +State reflection in the ArRobot class is the way ARIA maintains +a snapshot of the robot's operating conditions and values, such +as estimated pose, current velocity, battery voltage, etc. +as extracted from the latest standard SIP. ArRobot methods for +examining these values include ArRobot::getPose(), ArRobot::getX(), +ArRobot::getY(), ArRobot::getTh(), ArRobot::getVel(), ArRobot::getRotVel(), +ArRobot::getBatteryVoltage(), ArRobot::isLeftMotorStalled(), +ArRobot::isRightMotorStalled(), ArRobot::getCompass(), +ArRobot::getAnalogPortSelected(), ArRobot::getAnalog(), ArRobot::getDigIn(), +ArRobot::getDigOut(). + +The standard SIP also contains sonar reading updates, which are +reflected in ArRobot and examined with the methods: +ArRobot::getNumSonar(), ArRobot::getSonarRange(), ArRobot::isSonarNew(), +ArRobot::getSonarReading(), ArRobot::getClosestSonarRange(), +ArRobot::getClosestSonarNumber(). The sonar interface class, ArSonarDevice, +also receives this information (see \ref rangeDevices). + +ArRobot also uses the state reflection task to send previously requested +motion commands (see @ref robotMotionCommands) to the robot, so the motion +commands sent to the robot reflects those desired values set in ArRobot's state +reflection by actions or motion command methods, and also so that the watchdog +on the robot does not time out and disable the robot (if no motion command is +set, ArCommands::PULSE is sent each cycle). +You can further tune state reflection's motion command sending rate if neccesary with ArRobot::setStateReflectionRefreshTime().) +If desired, you may turn the motion-control state reflector off in the +ArRobot::ArRobot() constructor (set the @a doStateReflection parameter to +false). This will cause motion command functions to only be send the command once directly to the +robot whenever they are called, rather than storing the command to send each cycle. + + \subsection callback Robot Callbacks + +There are a number of useful callbacks invoked by ArRobot on connection +events. You can add and remove them with the functions +ArRobot::addConnectCB(), ArRobot::remConnectCB(), +ArRobot::addFailedConnectCB(), ArRobot::remFailedConnectCB(), +ArRobot::addDisconnectNormallyCB(), ArRobot::remDisconnectNormallyCB(), +ArRobot::addDisconnectOnErrorCB(), ArRobot::remDisconnectOnErrorCB(), +ArRobot::addRunExitCB(), ArRobot::remRunExitCB(). Read their individual +documentation pages for details. + +@sa @ref robotConnectionCallbacks.cpp + + + \section ClientCommands Controlling the robot with Commands and Actions + +Your ARIA client can drive the robot and run its various accessories +through ArRobot's Direct Commands, Motion Commands, or through Actions. + +@note The robot's movement speed will be limited by several parameters. First, +the maximum velocities, accelerations and decelerations given in ARIA's robot +parameter file (.p file) (TransVelMax, +RotVelMax, TransAccel, TransDecel, RotAccel, RotDecel, and for the Seekur only, +LatVelMax, LatAccel and LatDecel) are used to limit motion +commands sent by ARIA, if the value is nonzero. Next, the max velocities given in the +robot firmware (ARCOS) configuration are used to limit motion commands recieved by the robot. +All of these maximum values can be changed at runtime with the ArRobot::setTransVelMax(), +ArRobot::setRotVelMax(), and for the Seekur only, ArRobot::setLatVelMax() calls. +These calls change the parameters in the robot firmware, as well as in ARIA. +That is, they override any maximum values given in the robot parameter file (.p file). +Finally, the "Top" parameters in the firmware (ARCOS) configuration limit +speeds; these cannot be changed at runtime, only using the configuration +program. Most robot parameter files use 0 values as maximums, disabling ARIA's +initial limiting check; however, to make the Seekur easier to initially teleoperate at safe +speeds, the velocity limits in seekur.p are set. Change these limits to 0 to remove +those speed limits, and use the platform's defaults, or use ArRobot's methods to +change them at program runtime. + + \subsection robotDirectCommands Direct Commands + +At the lowest level of robot access, you may send any command packet directly to the robot +or simulator platform through ArRobot. Direct commands consist of a 1-byte command +number followed by none or more arguments, as defined by the robot's +operating system (ARCOS, AROS, P2OS, AmigOS, etc.). For example, the command +number 4, ENABLE, enables the robot's motors if accompanied by the +argument 1, and disables the motors with the argument 0. +Use ArRobot::com() for commands that +have no argument, such as PULSE; ArRobot::comInt() for a 2-byte integer +argument, signed or unsigned, such as the motors ENABLE command; +ArRobot::com2Bytes() for commands that accept two individual bytes +as the argument, such as the VEL2 command; and ArRobot::comStr() or +ArRobot::comStrN() for a null-terminated or fixed-length +string argument, respectively, such as the sonar POLLING +sequencing command. + +The ArCommands class contains an enum with all the direct commands; +ArCommands::ENABLE, for example. Not all Direct Commands are supported by every +MobileRobots robot, but unrecognized (or malformed) +commands are simply ignored. + +Please consult your robot's technical manual for details, such +as the Chapter 6 in the Pioneer 3 +Operations Manual, for client command numbers and syntax. + +For most commands, a method exists in ArRobot that either sends the command +immediately, or stores it for the state reflection task to send. However, +the direct command methods allow you to send any unusual or special commands +directly to the robot platform or simulator, without any intervening processing. + + \subsection robotMotionCommands Motion Command Functions + +At a level just above ArRobot's Direct Commands are the Motion +Command Functions. These are explicit simple movement commands sent by ArRobot's +state reflection task. +For example, ArRobot::setVel() to set the translational velocity, +ArRobot::setRotVel to set rotational velocity, ArRobot::setVel2() to +or set each wheel speeds separately, ArRobot::setHeading() to set a +global heading angle to turn to, ArRobot::move() to drive a given distance, +or ArRobot::stop() to stop all motion. ArRobot also provides methods +for setting speed limits beyond the limits set in the firmware configuration. +These motion functions work at part of with @ref stateReflection, and ArRobot may +resend commands each cycle to try to achieve the desired state. + +Be aware that a Direct or a Motion Command may conflict with controls +from Actions or other upper-level processes and lead to unexpected +consequences. Use ArRobot::clearDirectMotion() to cancel the overriding +effect of a previously set Motion Command so that your Action is able to regain +control the robot. Or limit the time a Motion Command prevents other +motion actions with ArRobot::setDirectMotionPrecedenceTime(). Otherwise, +the Motion Command will prevent actions forever. Use +ArRobot::getDirectMotionPrecedenceTime() to see how long a Motion +Command takes precedence once set. + + \subsection actions Actions + +While simple sequences motion commands can be easy to use, trying to achieve +more sophisticated motion using only motion commands +can quickly become difficult. To make it possible to define +complex behaviors out of independent, reusable components, +ARIA provides the higher-level Actions system. +Actions are individual objects that independently +provide motion requests which are evaluated and then combined each cycle +to produce a final set of movement commands. This allows you to build complex +behavior from simple building blocks for dynamic and continuous motion control. + +Actions are defined by creating a subclass of the ArAction the base class +which overloads the ArAction::fire() method. +See the @ref actionExample.cpp example program. +ARIA also includes some useful pre-made action classes (see @ref ActionClasses +for a list). Include these in your programs, or use them as examples when +creating your own custom ArAction subclass. + +Actions are attached to an ArRobot object with ArRobot::addAction(), along with +a priority which determines its position in the action list. +ArAction::setRobot() is called on an action object when it is added to a robot. +You can override this in your action subclass. (For example, this would be useful to add a +connection callback, if there were some calculations you wished to do +upon connection to the robot.) + +Actions are evaluated by ArRobot's action resolver in descending order of priority +(highest priority first, lowest priority last) in each task cycle just prior +to @ref stateReflection. The action resolver invokes each action's fire() +method, combining their desired motion commands (the ArActionDesired objects +they return) to a +single ArActionDesired object, which is then used in state reflection to send +motion commands to the robot. + +@note Sending simple motion commands (e.g. by using ArRobot::setVel()) while +actions are also active can result in conflicts between your simple motion +commands and the action resolver's commands. See the discussion of +@ref robotMotionCommands above. + +As the resolver is invoking each action, by it passes +the current desired motion combined from the previously invoked, higher priority +actions, as the currentDesired argument to fire(). +This can be useful information if +needed. (For example, a stall-recovery action could +be programmed not to exert its motion effects if it has been +pre-empted by a stop action, so this stall-recovery action would check +currentDesired to see if either the "strength" is "used up" or if there is a maximum +velocity, and if so, reset its own state.) However, there is no need +for an action to pay attention to the currentDesired if not necessary. + +@warning An action must run quickly. If one or more actions or robot +user tasks runs such that the task cycle takes too long (more that 100ms) +then the performance and behavior of the robot and of ARIA-robot communications +will be negatively affected. In particular, do not call any functions that +could block or wait for an unknown amount of time (such as locking a mutex +that could be locked for a long time by another thread) +or do any long loops waiting for a condition. Long-running activity can be performed +in a separate asynchronous thread (See ArASyncTask) instead, and results can be +shared with the action via storage which is protected by a mutex only during +immediate reading and writing of the storage variables. + + \subsection actionDesired Action Desired + +ArActionDesired objects are used to pass desired action channel values +and strengths out of an ArAction::fire() method back to the resolver. +An ArActionDesired object should always be +reset (ArActionDesired::reset()) before it is reused. + +There are six action channels: velocity (ArActionDesired::setVel), +heading (ArActionDesired::setDeltaHeading or +ArActionDesired::setHeading for absolute heading), +maximum forward translational velocity +(ArActionDesired::setMaxVel), maximum reverse translational velocity +(ArActionDesired::setMaxNegVel), and maximum rotational velocity +(ArActionDesired::setMaxRotVel). + +An action gives each channel a strength between 0.0, the lowest, and 1.0, +the highest. Strengths are used by the resolver to compute the +relative effect of the associated channel when combining multiple +actions' desired movements. + +The maximum velocity, maximum negative velocity, and maximum +rotational velocity channels simply impose speed limits and thereby +indirectly control the robot. + +For more advanced usage, ArActionDesired objects can be merged +(ArActionDesired::merge) and averaged (ArActionDesired::startAverage, +ArActionDesired::addAverage, ArActionDesired::endAverage). + + \subsection resolvers The Action Resolver + +ArResolver is the base action resolver class. ArPriorityResolver is +the default resolver used by ArRobot. + +The resolver used by ArRobot may be changed by calling ArRobot::setResolver, +if you wish to create an alternative ArResolver implementation. +There may only be one resolver per ArRobot object. +(Though a resolver could contain +within it multiple resolvers of its own.) Note that although a robot has +one particular resolver bound to it, a resolver instance is not tied to +any robot. + +The priority resolver works by iterating through the action list in descending +priority (from greatest priority value to lowest), setting each robot movement channel (trans. velocity, heading, +max. velocity, etc.) based on +the contributing actions' desired values (as returned from their fire() methods) +in proportion to their +respective strengths as well as the actions' priorities, updating each movement channel +until its strength becomes 1.0 or the action +list is exhausted. Once a channel's accumulated strength reaches 1.0, no more changes may be made to +that channel (this is how higher priority actions can prevent lower priority +actions from changing a channel). Same-priority actions are averaged together if +they both provide outputs for the same channel. + +As an example, the following table illustrates at each step an action's desired value +and strength for the velocity channel, and the resulting change to +the resolver's final velocity channel value and strength decision, +for four fictional actions (A, B, C and D): + +
setCameraRel Command to pan and tilt the camera from the + current position by the values given in the + first two arguments. If a third argument is + given, zoom from the current position.
setCameraAbs Command to pan and tilt the camera to the + absolute positions given by the first two + arguments. If a third argument is given, set + the zoom to that absolute position.
setCameraPct Command to pan and tilt the camera to the + given positions as percentage of their overall + ranges.
getCameraData Data request to get current pan and tilt values. + Also get zoom value if available.
getCameraInfo Data request to get pan and tilt ranges. Also + gets the zoom range if available.
+ + + + + + + +
step # action priority value of action's desired-velocity channel strength of action's desired-velocity channel current final velocity value current final velocity strength
1 A 4 -400 0.25 -400 0.25
2 B 3 -100 1.0 Combined for use in step 4
3 C 3 200 0.50
4 B&C 3 0 0.75 -100 1.0
5 D 1 500 0.50 no change no change
final result-1001.0
+ + +Notice in the example that the same-priority actions B and C are +averaged before being combined with the previously computed values from step 1. +The resulting combination is: +( (B desired velocity: -100) X (B velocity strength: 1.0) + +(C desired velocity: 200) X (C velocity strength: 0.5) ) / 2 => (-100 + 100) / 2 => 0 +Therefore actions B and C end up cancelling each other out. Combining this result with +the "currentDesired" values computed in step 1 gives +(step 1 desired velocity: -400) X (step 1 velocity strength: 0.25) + (step 4 +desired velocity: 0) X +(step 4 velocity strength: 0.75) => -100. + +In this example, it turns out that at step 5, action D has no effect since the +strength for this channel has reached 1.0 at step 4, before that action was +considered by the resolver. + +The same method is used for all of the other channels. + + \subsection predefinedActions Predefined Actions + +ARIA includes several predefined action classes. +See @ref ActionClasses for a list. Include these in your programs, or use them as examples when +creating your own custom ArAction subclass. + +Movement action classes have an "ArAction" prefix and set +either or both the translational velocity (setVel) and heading +(setDeltaHeading and setHeading) channels to effect motion. Limiting action classes +are prefixed with "ArActionLimiter" and set one or more of the +maximum translational and rotational velocity channels, to slow down or +prevent motion, usually based on conditions such as nearby sensor readings. + +See the ArAction base class's list of subclasses. + + \subsection actionInteractions Mixing Actions + +Actions are most useful when mixed. The @ref teleopActionsExample.cpp +example program is a good +example of mixing limiting and movement actions. It creates +several limiting actions, including Limiter, LimiterFar, and so +on, and two movement actions, joydriveAct and +keydriveAct. The limiting actions have higher priority than the +movement ones, thereby preventing driving if it might be potentially unsafe +due to obstacles detected by sensors. + +This example also illustrates fundamental, yet very powerful features +of ARIA actions and how they contribute to the overall behavior of the +mobile robot. Because they are individuals, contributing discretely to +the movements of the robot, actions are easily reusable. For example, a +limiting action that prevents the robot from crashing +into a wall when translating forward, can be used, as is, in +another ARIA program and have the identical effect, except that +instead of driving the robot with a joystick, the new program's +lower-priority movement action might use color-tracking to have the +robot follow a rolling ball. The ball-following action doesn't need +to know anything about the finer arts of safe navigation--the +higher-priority limiting actions take care of that. + +Another ARIA example program, @ref wander.cpp demonstrates how +different movement actions can be used and how they interact. The +stall-recover action in wander (ArActionStallRecover) influences the +robot's movements only when the motors are stalled, disabling the +lower priority actions by using up all translational and rotational +strength until the robot has extracted from the stall. You should also +examine %ArActionStallRecover.cpp in the src/ directory +to see how the action changes its motion control +influences based on the stall state. +Also note how ArActionAvoidFront and ArActionConstantVelocity +interact. + + \subsection actionGroups Action Groups + +Action groups allow you to easily enable (activate) or disable (de-activate) +a set of actions at once. +You must first create an ArActionGroup attached to an ArRobot. Then, when you +add an ArAction to the ArActionGroup, it is automatically added to the ArRobot, as +well as to the group. + +Several predefined action groups are provided by ARIA. + +@sa @ref actionGroupExample.cpp + + + \section rangeDevices Range Devices + +Range devices (ArRangeDevice) are abstractions of sensors which detect +the presence of obstacles in the space around the robot, providing +a series of spatial readings over time. +ARIA's range device classes transform all readings into specific points in the same +two-dimensional global coordinate system. (This is the same coordinate system +as ArRobot's pose). + +Currently, the main +ArRangeDevice implementations included with ARIA are: sonar (ArSonarDevice), +laser (ArLaser and subclasses), the robot bumpers (ArBumpers), and the "table-sensing" infrared +sensors of a PeopleBot (ArIRs). Camera and 3D range devices (MobileRanger +devices) are supported by separate software. +In addition, ArForbiddenRangeDevice is a "virtual" range device that creates range readings +that border "forbidden area" and "forbidden line" regions +in an ArMap, and ArRangeDeviceFilter processes the output +another ArRangeDevice object in a few ways and provides the processed data through the +ArRangeDevice interface. Its parameters can be modified on line through +ArConfig. + +ArRangeDevice holds two kinds of ArRangeBuffer objects to store readings: +current and +cumulative, though not all ArRangeDevice implementations supply data to the +cumulative buffer. The current buffer contains the +most recent set of readings; the cumulative buffer contains readings gathered +over a longer period time, limited by the buffer's size (see +ArRangeBuffer::setSize()). + +Some range devices also provide "raw" readings, which are the original values given +by the device itself. Some range devices are also considered "Planar", which +means that the readings may undergo some processing to remove duplicates etc., +and which include raw readings. This includes the lasers. + +Range devices are connected to a specific ArRobot instance, to obtain +position and other information from the robot when readings are received and +stored, and also to provide a way to find all range devices attached to the robot. +Some range devices use the robot connection to communicate to their device (e.g. +ArSonarDevice, +ArBumpers, ArIRs). +Attach an ArRangeDevice to your ArRobot object with ArRobot::addRangeDevice() and +remove it with ArRobot::remRangeDevice(). The list of all attached devices +can be queried using ArRobot::findRangeDevice() and ArRobot::hasRangeDevice(). +The list can be obtained by calling ArRobot::getRangeDeviceList(). + +(Note that although sonar are integrated with the robot microcontroller, and +the microcontroller always sends sonar data to the robot (if the robot has +sonar), you still must attach an ArSonarDevice object to the robot to use it.) + +ArRangeDevice also includes some methods to help find the closest reading to the +robot within a selected box, or a polar sector: +ArRangeDevice::currentReadingPolar(), +ArRangeDevice::currentReadingBox(), +ArRangeDevice::cumulativeReadingPolar(), +ArRangeDevice::cumulativeReadingBox(). + +ArRobot also includes similar methods to do common operations on all +attached range devices, +including ArRobot::checkRangeDevicesCurrentPolar(), +ArRobot::checkRangeDevicesCurrentBox(), +ArRobot::checkRangesDevicesCumulativePolar(), and +ArRobot::checkRangeDevicesCumulativeBox() to find the closest range reading +to the robot within some region. + +Each range device has a mutex +(Use ArRangeDevice::lockDevice() and ArRangeDevice::unlockDevice() to lock +and unlock it) +so that it can be accessed safely by multiple threads. For +example, ArLMS2xx uses a thread to read data from a laser, but the +checkRangeDevice functions in ArRobot lockDevice() so they can read +the data without conflicting with ArLMS2xx's data-reading thread, then use +unlockDevice() when done. See \ref threading for more about threading in ARIA. + + + + + \section functors Functors + +Functors are used throughout ARIA. +Functor is short for function pointer. A Functor lets you call a +function without knowing the declaration of the function. Instead, the +compiler and linker figure out how to properly call the function. + +Function pointers are fully supported by the C language. C++ treats +function pointers like C, but to call class methods, an instance object +is required, as well as type information about the class. +Therefore, ARIA contains a set of template classes to contain this information. + +ARIA makes heavy use of ArFunctors as "callback" functions. +To instantiate a functor, you first need to +identify how many arguments the function needs and if it returns a +value. Many times a pointer to the abstract ArFunctor base class is used, which +can be invoked with no arguments and no return value. +Subclasses are used for functions with different numbers of arguments +and return values. ArFunctor1, ArFunctor2, +ArRetFunctor, ArRetFunctor1, and ArRetFunctor2 for example. When invoked, +the arguments may be supplied which are passed to the target function or +method, and a return value may also be given. The types for the arguments +and/or return value are given as template arguments. + +When creating a functor object, however, you must also provide the type +and instance of an object to invoke the method of; or explicitly state +that the function is a class-less global function. Do this by using one +of the concrete base classes of ArFunctor instead of the abstract classes: +ArFunctorC, ArFunctor1C, ArFunctor2C, ArRetFunctorC, ArRetFunctor1C, +ArRetFunctor2C, ArGlobalFunctor, ArGlobalFunctor1, etc. + +Example: + +@code + class ExampleClass { + public: + void aFunction(int n); + }; + + ... + + ExampleClass obj; + ArFunctor1C functor(&obj, &ExampleClass::aFunction); + + ... + + functor.invoke(42); +@endcode + +ExampleClass is a class which contains a function called +aFunction(). The functor functor is declared +as an ArFunctor1C, a functor which invokes a class method +and takes one argument. The template parameters specify the type of the +class (ExampleClass) and the type of the method argument +(int). functor is then initialized with +a pointer to the ExampleClass instance to call the +method on, and a pointer to the class method to call. When a functor +is contained within the class, it is typcially initialized in the +constructor, giving this as the object instance. + +A functor must be initialized with the method to call and, if a "C" functor, +a class instance. An unitilialized functor will crash at runtime when invoked. + +It is also possible to give values for the method arguments in the functor +initialization, see ArFunctor documentation for details. + +Once the functor object is created in this fashion, it can now be +passed to another function or object that wants a callback functor. And the +method ExampleClass::aFunction() will be called on the object +obj when the functor is invoked. + +To invoke a functor, simply call the invoke() function +on the functor. If it takes arguments, call invoke() with those +arguments. If the functor has a return value, call invokeR. The +return value of the function will be passed back through the invokeR() +function. If the functor was initialized with argument values, +and invoke() is called without argument values, the argument values +provided at initialization are passed. + + + + + \section userInput Keyboard and Joystick Input + +ARIA provides several classes getting live joystick and keyboard input, +and action classes (see @ref actions) that use that input to drive the robot. + +ArJoyHandler is a cross-platform interface to joystick data. +It's key functions are ArJoyHandler::getButtons, ArJoyHandler::getAdjusted, +ArJoyHandler::setSpeeds, and ArJoyHandler::getDoubles. + +ArKeyHandler is a cross-platform interface for recieving single keystroke +events (instead of buffered lines of text). +It's key function is ArKeyHandler::addKeyHandler, +which binds a specific key to a given functor. It contains an enum +ArKeyHandler::KEY that contains values for special keys. +You can also attach a key handler to a robot with ArRobot::attachKeyHandler(), +which adds some default key handlers, including a handler for Escape that +disconnects and exits the program (especially useful on Windows, where Ctrl-C +or the terminal close box won't properly clean up). +Since a PC can only have ony keyboard, ARIA keeps an ArKeyHandler pointer +globally, which may be queried with Aria::getKeyHandler(). + +@note if you are using Linux, creating a key handler will make the program hang +if put into the background with Ctrl-Z. + +ARIA provides two simple actions, ArActionKeydrive and ArActionJoydrive, to +drive a robot from keyboard and joystick input. +These actions are used by +the @ref teleopActionsExample.cpp example program. +ARIA also provides a more flexible +ArActionRatioInput, which can combine several input sources (such as keyboard, +computer joystick, robot-platform (microcontroller) joystick, +or teleoperation commands recieved via ArNetworking) in a more +consistent and configurable manner. See the class documentation for more +details. + + + + + + \section threading Threading + +ARIA is highly multi-threaded. This section presents some of the +critical concepts behind writing threaded ARIA code. + +ARIA provides a number of support classes to make it easier to write +object-oriented threaded code. They are: ArASyncTask, ArCondition, +ArMutex, and ArThread. + +Thread-safe code mostly means proper coordination between threads when +handling the same data. You want to avoid the problem of one +or more threads reading or writing the data at the same time that other +threads read or write the data. +data. To prevent this problem from happening, the data needs to be +protected with synchronization objects. + + \subsection syncObject Thread Syncronizing Objects + +In ARIA, the synchronization objects are ArMutex and ArCondition. +ArMutex is the most useful one. ArMutex (mutex is short for mutual +exclusion.) provides a wrapper around system calls (pthreads functions +on Linux and CriticalSection functions on Windows) that +exclude other threads from continuing while the mutex object is "locked". +When threads lock a mutex while accessing shared data, it is ensured +that only one thread is accessing that shared data at a time. +Therefore, the proper way to use a mutex is to lock it right +before accessing the shared data, and to always unlock it when done. +If the mutex is not already locked, then it becomes locked and the thread +continues. If the mutex is already locked by another thread, then it blocks +in the lock call until the other thread unlocks it. If a mutex is never +unlocked (e.g. a function returns due to an error condition without unlocking +it), then any further attempts to lock it will block forever, creating +a "deadlock". +See the mutex example program to see how ArMutex is used. The documentation of a method +may indicate whether locking is necessary before using it; in general, +when using an object that may be shared by other threads, +all threads using it must lock the same mutex (usually contained within +the object's class with methods provided for locking and unlocking) while using +the object. + +ArCondition is an occasionally used utility that puts the current thread to sleep until another thread +signals it to wake up and continue executing. This can be used to wait in a +thread for an indefinite amount of time until some event occurs in a another +thread which signals the ArCondition. + + \subsection asynctasks Asynchronous Task Class + +ARIA provides the ArASyncTask which can be subclassed to implement a +long-running thread and its state +as an object. As opposed to robot-syncronized tasks, asynchronous tasks run +in seperate threads. Like ArMutex, this class wraps the operating system's threading +calls in a cross-platform way. Typically, an ArASyncTask will reperesent a +thread that runs in a loop for the entire program. + +To use ArASyncTask, derive a class from ArASyncTask and +override the ArASyncTask::runThread() function. This function is +automatically called within the new thread when that new thread +gets created. To create and start the thread, call +ArASyncTask::create(). When the ArASyncTask::runThread() function +exits, the thread will exit and be destroyed. Seperate threads can +request that the task exit by calling ArASyncTask::stopRunning(), and within the thread, +you can check for this request with ArASyncTask::getRunningWithLock(). + +This class is mainly a convenience wrapper around ArThread so that you +can easily create your own object that encapsulates the concept of a +thread. + + + + + \section aria Global Data + +The static Aria class contains miscellaneous global data in ARIA. + +ARIA contains a list of all the ArRobot instances. Use the +Aria::findRobot() to find a robot by name, or use Aria::getRobotList() +to get a list of the robots. + +Use Aria::getDirectory() to find ARIA's top-level path +(Usually either C:\\Program Files\\MobileRobots\\%Aria on Windows, or +/usr/local/Aria on Linux). This is useful, +for instance, to locate +robot parameter files for individual operational details. Use +Aria::setDirectory() to change this path for the run of the program if +you feel the need to override what ARIA has decided. + +Call Aria::init() at program start to perform global initialization, and use +Aria::exit() to exit all ARIA threads before exiting your program. + +The Aria class also contains global objects for sharing configuration +parameters and other information: see \ref arconfig and \ref arinfogroup +sections below. + +@sa @ref arconfig +@sa @ref arinfogroup + + + + \section devices Device and Accessory Interface Classes + +ARIA includes classes to communicate with various kinds of devices. + +(Many of these devices are optional accessories, and not all robots have them +installed.) + +Some are mentioned below. See @ref DeviceClasses for a list. + +
    +
  • Range devices. See @ref rangeDevices for more about range devices. +
      +
    • The various subclasses of ArLaser are for laser rangefinder sensors. Use ArLaserConnector + to automatically create and set up ArLaser objects of the appropriate +types based on robot and program configuration parameters. The lasers created by ArLaserConnector will be available as ArLaser objects stored in ArRobot.
    • +
    • ArSonarDevice for Pioneer and Amigobot built-in sonar.
    • +
    • ArBumpers treats the robot's bumper switch triggers as positions for range device + readings.
    • +
    • ArRangeDeviceFilter provides an ArRangeDevice interface to data from any + other range device that has been filtered in different ways.
    • +
    • ArForbiddenRangeDevice is a virtual range device that returns readings + indicating the edges of forbidden lines and forbidden areas from + an ArMap
    • +
    • ArIRs treats triggers of a Peoplebot's infrared "table" sensors as + positions for range device readings.
    • +
    + devices +
  • + +
  • Pan/Tilt servos and camera bases. + ArPTZ defines a common interface, and subclasses access specific devices, + including: +
      +
    • ArVCC4 provides pan, tilt, zoom and other control of a Canon camera + via the robot microcontroller's AUX serial port.
    • +
    • ArSonyPTZ provides pan, tilt, zoom and other actions of a Sony camera + via the robot microcontroller's AUX serial port.
    • +
    • ArDPPTU provides control of a Directed Perceptions Pan/Tilt unit (used + for stereo cameras).
    • +
    +
  • + +
  • ArAnalogGyro provides data from the optional analog gyro on Pioneer, +PeopleBot, PatrolBot, PowerBot or AmigoBot. If the HasGyro parameter in the robot's +internal firmware configuration is 2 (the default on most robots), then the robot automatically uses the gyro for +position correction before sending its pose estimate to ARIA. However, +if GyroType is 1, then create an ArAnalogGyro object to begin receiving data +from the robot and allow it to apply those corrections to the position in the +ArRobot object. + + The gyro also measures its own temperature as part of its operation, + and ArAnalogGyro makes that value available as well. +
  • + +
  • ArGripper provides access to a Pioneer gripper.
  • + +
  • ArP2Arm provides access to a Pioneer arm.
  • + +
  • ArTCM2 provides access to an on-board TCM2 compass, if present.
  • + +
  • ArACTS_1_2 communicates with the ACTS program to get object tracking + information. + +
  • ArVersalogicIO provides access to the digital and analog I/O ports + on Versalogic motherboards (Linux only). (Support depends on + whether the robot has a Versalogic motherboard, and which board it has.)
  • + + +
  • ArSystemStatus provides data about the operating system (Linux only) + such as CPU usage and wireless network signal strength. +
  • + +
  • ArGPS provides access to data received from a Global Positioning System + device. Subclasses implement special actions required for specific devices, + such as ArNovatelGPS for the NovAtel G2 and similar devices and ArTrimbleGPS +for the Trimble GPS. Use ArGPSConnector to create the appropriate ArGPS device +based on robot and program configuration parameters. +
  • +
+ +Some device interfaces are provided by additional libraries, as well. See +those libraries for details. + + + + + + + + \section utility Utility Classes + +Some of the general-purpose utility classes included with are ArMath, ArUtil, ArTime, ArPose, ArLog, +ArSectors, ArRingQueue, ArLineFinder, the GPS-related subclasses of Ar3DPoint, ArMD5Calculator +(and the functions in md5.h), ArMutex, ArCondition and ArASyncTask. See @ref +UtilityClasses for a list of utility classes. + + \section arconfig ArConfig + +ArConfig is a mechanism for storing configuration parameters for different +independent modules in a text file. The global Aria class +maintains a global ArConfig pointer which any program module may access. +Use ArConfig::addParam to register a new parameter with ArConfig, and use +ArConfig::addProcessFileCB to register a callback functor called when the +configuration changes (by loading the file with ArConfig::parseFile, or other +means such as an update from a remote client via ArNetworking). + + \section arinfogroup Shared Info Groups + +In a program composed of multiple independent modules, it is often necessary +to exchange or combine data between them in a general and immediate way. To do this, ARIA provides +the ArStringInfoGroup class, of which the global ARIA class contains an instance +(in addition to an ArConfig instance used specifically for configuration information +which changes infrequently, by loading a file or by user input.) +An example of ArStringInfoGroup is the ArServerInfoStrings class contained in +the ArNetworking auxiliary library. At program initialization, a callback +functor may be added to the global ArStringInfoGroup object which on invocation immediately passes a +string key/value pair from the ArStringInfoGroup object over to an ArServerInfoStrings +object, which provides access to this data over the network (e.g. to MobileEyes). +Independent components of the program may then change the values in the InfoGroup +object without needing any special +knowledge of the recipients of the data (in this example is the +ArServerInfoStrings class). Since MobileEyes displays this data in a small table +next to other robot information like position in speed, this is a useful way +to provide informative statistics about the robot and software's current operation. +(On Linux, for example, you could use the ArSystemStatus class to publish +information from the operating system, like CPU load). + + \section maps Maps + +In mobile robot applications, you will often need to store a map of the robot's +environment to use in navigation, localization, etc. ARIA provides the ArMap +class for reading map data from a file, obtaining and modifying its contents in your +application, and writing it back to file. An ArMap contains data about the +sensed/sensable environment (walls, obstacles, etc.), and human-provided +objects such as goal points. + +The \ref MapFileFormat page describes the map file format in detail. + +ARNL, SONARNL and MobileSim all use ArMap format map files. + + \section sockets Sockets + +The ArSocket class is a wrapper around the socket network +communication layer of your operating system. ARIA mostly uses +ArSocket to open a server port and to connect to another server port. + +To connect to a port, simply construct a socket containing the +hostname or IP address of the host, a port number, and the ARIA socket +type (TCP or UDP). For example: + +@code + ArSocket sock("host.name.com", 4040, ArSocket::TCP); +@endcode + +Or call the ArSocket::connect() function, such as: + +@code + ArSocket sock; + sock.connect("host.name.com", 4040, ArSocket::TCP); +@endcode + +To open a server on (for example) port 4040, simply construct a socket: + +@code + ArSocket sock(4040, true, ArSocket::TCP); +@endcode + +Or call open(4040, ArSocket::TCP) on an ArSocket object constructed +with the default constructor. + + + \section ArNetworking ArNetworking + + For a more advanced networking infrastructure, see the ArNetworking companion + library, + distributed with ARIA. ArNetworking provides an extensible system of + data requests and updates between client and server applications via TCP or + UDP, using the same base "packet" concept as robot communication. + For example, use ArNetworking to connect multiple robots working together, + off-board user interfaces to on-board control servers, or robot control programs to + off-board data resources. + + \section sound Sound and Speech + + + ARIA provides foundation sound support, and separate libraries use this + for speech and network audio. + +
    + +
  1. ARIA's ArSoundsQueue provides a method for handling sound output + generated by various components of a large ARIA application in sequence + and in loops. + It is a sound playback and speech synthesis manager, which + uses a thread-safe queue of sound and speech synthesis requests, and runs + a background processing thread for it. Use this for most of your non-trivial + audio playback and voice synthesis needs. + The speech synthesis libraries, the voice recognition library, and the NetAudio + library are designed to be used in conjunction with this class to coordinate their + usage of the sound device. +
  2. + +
  3. ARIA's ArSoundPlayer provides a basic cross-platform sound-file playback + capability. + Sound files are in WAV (Windows RIFF) format. This class provides static methods + that can be used by ArSoundsQueue for sound file playback. +
  4. + +
  5. Separate libraries provide wrappers around some + speech synthesis (Text-to-speech) and recognition products: +
      +
    • The ArSpeechSynth_Festival library uses the free Festival system from the + University of Edinburgh to perform speech synthesis. It provides + the ArFestival class as a wrapper around Festival. +
    • +
    • The ArSpeechSynth_Cepstral library uses the Swift library from + Cepstral, Inc. to perform speech synthesis. It provides the ArCepstral + class for this. ArCepstral offers a few extra features over + ArFestival, and Cepstral, Inc. provides high quality voices for use with Swift. +
    • +
    • The ArSpeechRec_Sphinx library uses Sphinx from Carnegie Mellon + University to perform speech recognition. ArSphinx provides an interface to this. +
    • +
    +
  6. + +

    Functions common to both of the speech synthesis libraries are included in a base + class, ArSpeechSynth. +

    + +
  7. The separate ArNetAudio library provides network voice audio recording, transmission and playback: +
      +
    • ArNetAudioServer automatically decodes and plays or records and + encodes audio for a network server (typically running on a robot's on-board + computer) and sends and receives the encoded audio to/from a client.
    • +
    • ArNetAudioClient automatically decodes and plays or records and + encodes audio for a network client, sending and receiving the encoded + audio to/from a server (i.e. a robot's on-board computer).
    • +
    • ArNetAudioIO is the common class performing cross-platform Audio I/O + (via the free PortAudio library), and voice encoding/decoding (via the free Speex codec). + It is used by ArNetAudioClient and ArNetAudioServer, but is also available for + stand alone use. +
    • +
    +
  8. + + +
+ + \section emacs Emacs + +Here is the configuration specification the developers at MobileRobots +Inc. use in their .emacs files, in case you want to modify the +code using emacs and not deal with differences in indentation and +such. + +
+    (setq c-default-style '((other . "user")))
+    (c-set-offset 'substatement-open 0)
+    (c-set-offset 'defun-block-intro 2)
+    (c-set-offset 'statement-block-intro 2)
+    (c-set-offset 'substatement 2)
+    (c-set-offset 'topmost-intro -2)
+    (c-set-offset 'arglist-intro '++)
+    (c-set-offset 'statement-case-intro '*)
+    (c-set-offset 'member-init-intro 2)
+    (c-set-offset 'inline-open 0)
+    (c-set-offset 'brace-list-intro 2)
+    (c-set-offset 'statement-cont 0)
+    (defvar c-mode-hook 'c++-mode)
+
+ + \section noneverydayC Non-everyday use of C++ + +ARIA uses some features of C++ that some programmers may not be aware of yet, +and includes some workarounds for platform differences. + + \subsection stl Standard Template Library + +ARIA makes heavy use of the C++ standard template library (STL). So you +should understand the STL in order to get the best use from some of +the more advanced parts of ARIA. + + \subsection defaultArgs Default Arguments + +In the function declaration a default value for an argument may be specified. +Arguments with default values may then be omitted from the function call. + +For example, after declaring this function with a default value for its integer +argument: +@code + void foo(int number = 3); +@endcode +it can be used in two different ways: +@code + // Use the default value for the argument: + foo(); + + // Or, use don't use the default: + foo(99); +@endcode + +This behavior is quite useful for having defaults for more obscure options +you will usually not need to change, but still allowing you to change them if +necessary without making ARIA more complex. + +Also note that the function definition must not have the assignment in +it, only the declaration. Therefore the definition if our example function would +look like this: +@code + void foo(int number) + { + //... + } +@endcode + + \subsection constructorChaining Constructor Chaining + +Constructor chaining is quite simple though sometimes not used by C++ programmers. Each +constructor can give arguments to the constructors of the member +variables it contains and to the constructors of classes from which it inherits. For +example if you have: + +@code + class BaseClass + { + public: + BaseClass(int someNumber); + }; +@endcode +and +@code + class SubClass : public BaseClass + { + public: + SubClass(void); + int anotherNumber; + }; +@endcode +When you write your constructor for SubClass you can initialize both +baseClass and anotherNumber: +@code + SubClass::SubClass(void) : BaseClass(3), anotherNumber(37) + { + // ... + } +@endcode +Note how the constructors to be initialized must follow a colon (:) after the +constructor, and be separated by commas. Member variables +must be initialized in the order they are in the class. Note +that initializing integers is not all that unique or useful, but using +this to initialize callback \ref functors is quite useful. + +Constructor chaining is used in many many places by ARIA, thus it must +be understood in order to understand ARIA, but the above is all that +really needs to be known. + + \subsection charsAndStrings Chars and Strings, Win workaround + +During development problems were encountered with Windows if +a std::string was passed into a DLL. Thus for all input to ARIA +const char * is used, but for all internal storage and all reporting +std::strings are passed back out of ARIA. + + \subsection arexport AREXPORT + +Because of the Windows set up for using DLLs, this macro is used +to take care of the required declaration attributes for DLLs. Largely +users do not need to worry about AREXPORT, but only functions which have +AREXPORT and inline functions are usable with DLLs in Windows (all of the +ARIA functions which are documented in this manual are usable). + + \subsection exceptions Exceptions + +ARIA neither throws nor catches any exceptions. + + + + + + \section Advanced Topics and Esoterica + + \subsection pieceMealUse Piecemeal Use of ARIA + +The most basic layer of ARIA is ArDeviceConnection and subclasses, which +handle low-level communication with the robot server. On top of the +connection layer, we have a packet layer--ArBasePacket and +ArRobotPacket--the basic algorithms for constructing command packets +and decoding server information packets. + +Above the packet layer is the packet handler classes, +ArRobotPacketReceiver and ArRobotPacketSender, when send and receive +packets to and from the robot. Finally, on top of all these lowest +layers is ArRobot, which is a gathering point for all things, but can +be used in a quite basic format without all of the bells and whistles. +ArRobot has built-in tasks, actions, state reflection and so forth, all +of which can be disabled from the constructor (ArRobot::ArRobot) and +ignored or reimplemented. + +Also note that if all you do is turn off state reflection, which only +affects sending ArRobot-mediated motion commands to the robot, not +receiving SIPs from the robot, none of the other activities which +ArRobot engages on its loop will take up hardly any time, so it +probably isn't worth building your own set of tasks, but the power to +do so is there for the intrepid. + +One other thing worth noting is that you can call ArRobot::loopOnce() +and it will run through its loop a single time and return. This is so +that you can use ARIA from your own control structure. If you are +using loopOnce you may also find it beneficial to call +ArRobot::incCounter, so that the loop counter will be updated. You +could also just call ArRobot::packetHandler, ArRobot::actionHandler, +or ArRobot::stateReflector on your own, as these are the most +important internal functions, though if you make your own loop you +should probably call ArRobot::incCounter any way that you do it, as +this is how sonar are known to be new or not, and such. + +We recommend that whatever you do you use the same type of strict +threading/locking that ARIA observes. + + + \subsection hardConnectRobot Connecting with a Robot or the Simulator the hard way + +ArDeviceConnection is ARIA's communications object; ArSerialConnection +and ArTcpConnection are its built-in children most commonly used to +manage communication between a MobileRobots or ActivMedia robot or the robot +simulator, respectively. These classes are not device-specific, +however, so use ArSerialConnection, for instance, to also configure a +serial port and establish a connection with a robot accessory, such as +with the SICK laser range finder. + + + \subsection openDevice Opening the Connection + +After creating and opening a device connection, associate it with its +ARIA device handlers, most commonly with ArRobot::setDeviceConnection +for the robot or the simulator. + +For example, early in an ARIA program, specify the connection device and +associate it with the robot: + +@code + ArTcpConnection con; + ArRobot robot; +@endcode + +Later in the program, after initializing the ARIA system +(Aria::init(); is mandatory), set the Connection port to its default +values (for TCP, host is "localhost" and port number is 8101), and +then open the port: + +@code + con.setPort(); + if (!con.openSimple()) + { + printf("Open failed."); + Aria::shutdown(); + return 1; + } +@endcode + +TCP and Serial connections have their own implementation of open which +is not inherited, but has default arguments that make the generic open +work for the all default cases. And open returns a status integer +which can be passed to the re-implemented and inherited +ArDeviceConnection::getOpenMessage in order to retrieve related status +string, which is useful in reporting errors to the user without having +to know about the underlying device. + + \subsection devConnect Robot Client-Server Connection + +After associating the device with the robot, now connect with the +robot's servers, ArRobot::blockingConnect or ArRobot::asyncConnect, for +example, to establish the client-server connection between ARIA +ArRobot and the robot microcontroller or robot +simulator. The blockingConnect method doesn't return from the call until +a connection succeeds or fails: + +@code + robot.setDeviceConnection(&con); + if (!robot.blockingConnect()) + { + printf("Could not connect to robot... Exiting."); + Aria::shutdown(); + return 1; + } +@endcode + +The previous examples connect with the simulator through a TCP +socket on your PC. Use tcpConn.setPort(host, port) to set the TCP +hostname or IP address and related socket number to another machine on +the network. For instance, use tcpConn.setPort("bill", 8101); to +connect to the simulator which is running on the networked computer +"bill" through port 8101. + +Replace ArTcpConnection con; with ArSerialConnection con; +to connect with a robot through the default serial port (/dev/ttyS0 +or COM1), or another you specify with ArSerialConnection::setPort(), + such as con.setPort("COM3");. + +At some point, you may want to open the port with the more +verbose con.open(). + + \subsection connrw Connection Read, Write, Close and Timestamping + +The two main functions of a device connection are +ArDeviceConnection::read and ArDeviceConnection::write. Simple +enough. ArDeviceConnection::close also is inherited and important. You +probably won't use direct read or write to the robot device, although +you could. Rather, ArRobot provides a host of convenient methods that +package your robot commands, and gather and distribute the various +robot information packets, so that you don't have to attend those +mundane details. See the next section for details. + +All ArDeviceConnection subclasses have support for timestamping +(ArDeviceConnection::getTimeRead). With the robot connection, +timestamping merely says what time a robot SIP came in, which can be +useful for interpolating the robot's location more precisely. + + + +*/ + + + + diff --git a/Legacy/Aria/docs/params.dox b/Legacy/Aria/docs/params.dox new file mode 100644 index 0000000..11973dc --- /dev/null +++ b/Legacy/Aria/docs/params.dox @@ -0,0 +1,285 @@ + + +/** + +@page ParamFiles Robot Parameter Files + +ARIA's robot parameter files contain information that can differ between +different robot model types (e.g. "p3dx", "p3dx-sh", "p3at", "p3at-sh", +"amigo", "amigo-sh", etc.), and between +individual robots. This includes some physical dimensions, device connection +settings, and protocol conversion factors. The parameter files are included +with ARIA and are installed along with the rest of ARIA in the "params" +subdirectory. These files always end with ".p". + +The parameter files are read by ArRobot after it connects to the robot, and +stored in the ArRobot and ArRobotParams classes (Use +ArRobot::getRobotParams() to get a pointer to its ArRobotParams object.) + +When ArRobot connects to a robot it receives strings identifying the robot model +(the model's Pioneer "subtype" or "subclass") and an individual robot nickname. It uses +these names to load parameter files. It first loads the parameter file that +corresponds to the model subtype, e.g. "p3dx-sh.p" or "powerbot.p" and stores +those parameters. A log message is printed indicating that it loaded parameters +from that file. ARIA includes robot parameter files for all current robot types. +If such a file cannot be found, but ARIA recognizes the robot +subtype, it stores internal default constants as those parameter values, and +prints a log message indicating this. + +Next, if a file exists which corresponds +to this particular robot's nickname (name.p), then it loads that file, +which can override any settings provided in the robot type parameters or +defaults. + +An individual robot's nickname is stored in the robot firmware configuration, +and may be changed using the firmware configuration tool. For example, if a +robot uses the ARCOS firmware for the SH microcontroller, connect with ARCOScf +and change the "Name" parameter, then save the new configuration. Each robot is +assigned a unique name when assembled and configured by MobileRobots, but you +may change it if you want to use your own names. However, if you change the +name stored in the firmware configuration, you must rename its parameter files +in any ARIA or ARNL/SONARNL/MOGS installation on all computers that connect to +it as well. + +In almost all circumstances, modifying +the standard parameters for robot types is unneccesary; change your robot's name.p +instead. + + +@section ParamFileDeviceParams Device Parameters + +The most common parameters that must be changed in name.p are parameters +regarding how some of an individual robot's devices are connected to the robot +or the onboard computer, if an individual robot has a unique configuration. + +If you are using a name.p file, and later remove ARIA, reinstall the operating system and +erase the disk, make a backup of this file. If you change any connections, or +need to recreate a lost name.p file, however, you can edit name.p +in the "params" subdirectory. + + +In addition to the parameter files, if a program is using ARIA's argument parsing and +connector classes, then it can be executed with command-line arguments which +also affect robot and device parameters (see @ref CommandLineOptions), and may override some of the device +parameters given in the parameter file. + +@subsection ParamFileGeneralParams General Robot Parameters + +The "General settings", "Conversion factors" and "Movement control +parameters" sections give some general parameters about the robot. +Many of these parameters are invariant for all instances of a particular robot +type (such as the conversion factors, class/subclass names), and should not be +changed. You could change the physical dimensions if you have modified the +robot; +ARNL uses these when path planning. You can also set @a SwitchToBaudRate +to 0 to disable the automatic renegotiation of connection data rate after ARIA +connects (if, for example, this causes problems with your particular +computer or a USB-serial device). + +For example, p3dx-sh.p contains the following: + +@verbatim +Section General settings +Class Pioneer ; general type of robot +Subclass p3dx-sh ; specific type of robot +RobotRadius 250 ; radius in mm +RobotDiagonal 120 ; half-height to diagonal of octagon +RobotWidth 425 ; width in mm +RobotLength 511 ; length in mm of the whole robot +RobotLengthFront 210 ; length in mm to the front of the robot (if this is 0 + ; (or non existant) this value will be set to half of + ; RobotLength) +RobotLengthRear 301 ; length in mm to the rear of the robot (if this is 0 + ; (or non existant) this value will be set to half of + ; RobotLength) +Holonomic true ; turns in own radius +MaxRVelocity 500 ; absolute maximum degrees / sec +MaxVelocity 2200 ; absolute maximum mm / sec +MaxLatVelocity 0 ; absolute lateral maximum mm / sec +HasMoveCommand true ; has built in move command +RequestIOPackets false ; automatically request IO packets +RequestEncoderPackets false ; automatically request encoder packets +SwitchToBaudRate 38400 ; switch to this baud if non-0 and supported on robot + + +Section Movement control parameters +; if these are 0 the parameters from robot flash will be used, otherwise these +; values will be used +SettableVelMaxes true ; if TransVelMax and RotVelMax can be set +TransVelMax 0 ; maximum desired translational velocity for the robot +RotVelMax 0 ; maximum desired rotational velocity for the robot +SettableAccsDecs true ; if the accel and decel parameters can be set +TransAccel 0 ; translational acceleration +TransDecel 0 ; translational deceleration +RotAccel 0 ; rotational acceleration +RotDecel 0 ; rotational deceleration +HasLatVel false ; if the robot has lateral velocity +LatVelMax 0 ; maximum desired lateral velocity for the robot +LatAccel 0 ; lateral acceleration +LatDecel 0 ; lateral deceleration +@endverbatim + + +@subsection ParamFileLaserParams Laser Rangefinding Devices + +For each laser rangefinder device, a "Laser parameters" section is added to the parameter +file. + +@verbatim +Section Laser parameters +LaserType lms2xx ; type of laser +LaserPortType ; type of port the laser is on +LaserPort COM3 ; port the laser is on +LaserAutoConnect false ; if the laser connector should autoconnect this laser + ; or not +LaserFlipped false ; if the laser is upside-down or not +LaserPowerControlled true ; if the power to the laser is controlled by serial port connection, and ARIA should wait for laser initialization after opening connection +LaserMaxRange 0 ; Max range of the laser, 0 to use default (only use + ; if you want to shorten it from the default), mm +LaserX 21 ; x location of laser, mm +LaserY 0 ; y location of laser, mm +LaserTh 0 ; rotation of laser, deg +LaserZ 0 ; height of the laser off the ground, mm (0 means + ; unknown) +LaserIgnore ; Readings within a degree of the listed degrees + ; (separated by a space) will be ignored +LaserStartDegrees ; start degrees for the sensor (leave blank for + ; default, use this to constrain the range) (double) +LaserEndDegrees ; start degrees for the sensor (leave blank for + ; default, use this to constrain the range) (double) +LaserDegreesChoice ; degrees choice for the sensor (leave blank for + ; default, use this to constrain the range) +LaserIncrement ; Increment for the sensor (leave blank for default, + ; use this to have a custom increment) (double) +LaserIncrementChoice ; Increment for the sensor (leave blank for default, + ; use this to have a larger increment) +LaserUnitsChoice ; Units for the sensor (leave blank for default, use + ; this to have a larger units) +LaserReflectorBitsChoice ; ReflectorBits for the sensor (leave blank for + ; default, use this to have a larger units) +LaserStartingBaudChoice ; StartingBaud for the sensor (leave blank for + ; default, use this to have a larger StartingBaud) +LaserAutoBaudChoice ; AutoBaud for the sensor (leave blank for default, + ; use this to have a larger units) +@endverbatim + +The first and default laser is in the "Laser parameters" section. The second laser +is in "Laser 2 parameters", the third in "Laser 3 parameters", and so on. + +@a LaserType indicates the kind of laser device present: lms2xx for a SICK LMS 200 and compatible, +or urg for an Hokoyu URG or UTM. Other types will be added as support is added to ARIA. + +@a LaserPortType and @a LaserPort indicate how the laser is connected to the onboard computer. +@a LaserPortType currently is either blank or has the value serial for a serial port. +@a LaserPort identifies which port of the given type to use: COM1, COM2, COM3, etc. +for the first, second, third, etc. serial ports (use the "COM" notation both on Linux and Windows). +As support for other connection types such as USB and TCP are added in the future new types will be possible. + +@a LaserAutoConnect indicates whether an ArLaserConnector object should automatically connect to the laser. If false, +then a program must specifically request that the connector initiate the connection; however most programs do this +if they expect to use a laser. + +@a LaserFlipped, @a LaserX, @a LaserY, @a LaserTh, and @a LaserZ indicate the +physical positioning of the laser on the robot. X, Y, Z and Th give its position +relative to the center of the robot. If @a LaserFlipped is true then the order +of the readings supplied by ArRangeDevice objects is reversed, so the order is +correct for a laser mounted upside-down from normal. + +You can list a set of degree values for which laser readings should be ignored +after @a LaserIgnore. Use this if parts of the robot or mounted equipment +obscure the laser's field of detection and cause undesirable readings. + +@a LaserPowerControlled indidcates whether ARIA should expect that the laser's +power state is controlled by the data device connection (e.g. serial port). +If true, ARIA should (re)-initialize the laser +after opening the connection, and wait for the laser to finish initializing. +If false ARIA should expect to be able to read valid data soon after opening +the connection. This value should be left as is for any particular type of +robot, unless you have modified the way the laser is connected from the +standard installation. + +The other parameters affect the configuration of the laser itself, and their +meaning may depend on the type of laser. You may leave them empty (supply no +value) to use defaults for that type. + +@subsection ParamFileGPSParams GPS Devices + +@verbatim +Section GPS parameters +GPSPossessed false ; if the robot has a gps +GPSPX -160 ; x location of gps receiver antenna on robot, mm +GPSPY 120 ; y location of gps receiver antenna on robot, mm +GPSType standard ; type of gps receiver (trimble, novatel, standard) +GPSPort COM2 ; port the gps is on +GPSBaud 9600 ; gps baud rate (9600, 19200, 38400, etc.) +@endverbatim + +@subsection ParamFileOtherDeviceParams Other Accessory Device Flags and Options + +The "Accessories" section contains advisory flags indicating whether the robot +has certain optional accessories. These are reflected in ArRobot and programs +can check them to determine the robot's capabilities, but ARIA's internal +default behavior is generally not affected by them: + +@verbatim +Section Accessories the robot has +TableSensingIR false ; if robot has upwards facing table sensing IR +NewTableSensingIR false ; if table sensing IR are sent in IO packet +FrontBumpers false ; if robot has a front bump ring +NumFrontBumpers 5 ; number of front bumpers on the robot +RearBumpers false ; if the robot has a rear bump ring +NumRearBumpers 5 ; number of rear bumpers on the robot +@endverbatim + +The "Sonar" and "IR" parameters sections indicates the physical layout of the sonar +and IR proximity sensors (if any). ARIA will use +these to position obstacle readings in space. The "Num" value must be accurate +with respect to the number of "Unit" lines that follow, but ARIA uses the number of readings +actually supplied by the firmware when calculating and storing readings. (For +example, if the robot only provides 8 sonar range readings, only 8 obstacle +positions will be calculated and stored.) + +(Example from p3dx-sh.p:) + +@verbatim +Section Sonar parameters +SonarNum 16 ; number of sonar on the robot +; SonarUnit +SonarUnit 0 69 136 90 +SonarUnit 1 114 119 50 +SonarUnit 2 148 78 30 +SonarUnit 3 166 27 10 +SonarUnit 4 166 -27 -10 +SonarUnit 5 148 -78 -30 +SonarUnit 6 114 -119 -50 +SonarUnit 7 69 -136 -90 +SonarUnit 8 -157 -136 -90 +SonarUnit 9 -203 -119 -130 +SonarUnit 10 -237 -78 -150 +SonarUnit 11 -255 -27 -170 +SonarUnit 12 -255 27 170 +SonarUnit 13 -237 78 150 +SonarUnit 14 -203 119 130 +SonarUnit 15 -157 136 90 + +Section IR parameters +IRNum 0 ; number of IRs on the robot +; For each IR, give a line like this: +; IRUnit +@endverbatim + +The "Compass parameters" section indicates what kind of compass and compass +installation method the robot has. Almost all robots have a "robot" integrated +compass, serialTCM is never used in normal production robots. + +@verbatim +Section Compass parameters +;SectionFlags for Compass parameters: +CompassType robot ; type of compass: robot (typical configuration), or + ; serialTCM (computer serial port) +CompassPort ; serial port name, if CompassType is serialTCM +@endverbatim + +*/ diff --git a/Legacy/Aria/doxygen.conf b/Legacy/Aria/doxygen.conf new file mode 100644 index 0000000..b7ad0d5 --- /dev/null +++ b/Legacy/Aria/doxygen.conf @@ -0,0 +1,1316 @@ +# Doxyfile 1.5.3 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file that +# follow. The default is UTF-8 which is also the encoding used for all text before +# the first occurrence of this tag. Doxygen uses libiconv (or the iconv built into +# libc) for the transcoding. See http://www.gnu.org/software/libiconv for the list of +# possible encodings. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = Aria + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = 2.8.0 + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = docs/ + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Finnish, French, German, Greek, Hungarian, +# Italian, Japanese, Japanese-en (Japanese with English messages), Korean, +# Korean-en, Lithuanian, Norwegian, Polish, Portuguese, Romanian, Russian, +# Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = NO + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like regular Qt-style comments +# (thus requiring an explicit @brief command for a brief description.) + +JAVADOC_AUTOBRIEF = YES + +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will +# interpret the first line (until the first dot) of a Qt-style +# comment as the brief description. If set to NO, the comments +# will behave just like regular Qt-style comments (thus requiring +# an explicit \brief command for a brief description.) + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the DETAILS_AT_TOP tag is set to YES then Doxygen +# will output the detailed description near the top, like JavaDoc. +# If set to NO, the detailed description appears after the member +# documentation. + +DETAILS_AT_TOP = YES + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = NO + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 4 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = \ + "javanote=

Java Wrapper Library: " \ + "java=

Java Wrapper Library: " \ + "pynote=

Python Wrapper Library: " \ + "python=

Python Wrapper Library: " \ + "swignote=

Java and Python Wrappers: " \ + "swig=

Java and Python Wrappers: " \ + "swigomit=

Java and Python Wrappers: Not available in Java or Python wrapper libraries. " \ + "notwindows=@note Not available on Windows " \ + "windowsonly=@note Available on Windows only " \ + "linuxonly=@note Available on Linux only " \ + "added=

Added: in ARIA " + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for Java. +# For instance, namespaces will be presented as packages, qualified scopes +# will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to +# include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. + +CPP_CLI_SUPPORT = NO + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = YES + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = NO + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be extracted +# and appear in the documentation as a namespace called 'anonymous_namespace{file}', +# where file will be replaced with the base name of the file that contains the anonymous +# namespace. By default anonymous namespace are hidden. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = YES + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = YES + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = NO + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = NO + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = NO + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# in the documentation. The default is NO. + +SHOW_DIRECTORIES = NO + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from the +# version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = YES + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = NO + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be abled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = YES + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text " + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = \ + docs/overview.dox \ + docs/params.dox \ + docs/options/all_options.dox \ + src/ \ + include/ \ + examples/ + +# This tag can be used to specify the character encoding of the source files that +# doxygen parses. Internally doxygen uses the UTF-8 encoding, which is also the default +# input encoding. Doxygen uses libiconv (or the iconv built into libc) for the transcoding. +# See http://www.gnu.org/software/libiconv for the list of possible encodings. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx +# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py + +FILE_PATTERNS = *.cpp \ + *.h + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = NO + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or +# directories that are symbolic links (a Unix filesystem feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +# Exclude any file that starts with the word proprietary. These files should +# never be publically distributed or referenced in any documentation. +EXCLUDE_PATTERNS = proprietary* + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the output. +# The symbol name can be a fully qualified name, a word, or if the wildcard * is used, +# a substring. Examples: ANamespace, AClass, AClass::ANamespace, ANamespace::*Test + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = examples/ docs/options/ + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = *.cpp *_options + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = docs/figures + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER +# is applied to all files. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. If you have enabled CALL_GRAPH or CALLER_GRAPH +# then you must also enable this option. If you don't then doxygen will produce +# a warning and turn it on anyway + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES (the default) +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES (the default) +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. Otherwise they will link to the documentstion. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = YES + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = Ar + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = ./ + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. For this to work a browser that supports +# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox +# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). + +HTML_DYNAMIC_SECTIONS = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 4 + +# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be +# generated containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, +# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are +# probably better off using the HTML help feature. + +GENERATE_TREEVIEW = YES + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = YES + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = letter + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = NO + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = YES + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = YES + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = YES + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = YES + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +# Define AREXPORT to be empty, so it gets removed from docs: +PREDEFINED = AREXPORT= + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse +# the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = docs/Aria.tag + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option is superseded by the HAVE_DOT option below. This is only a +# fallback. It is recommended to install and use dot, since it yields more +# powerful graphs. + +CLASS_DIAGRAMS = NO + +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see http://www.mcternan.me.uk/mscgen/) to +# produce the chart and insert it in the documentation. The MSCGEN_PATH tag allows you to +# specify the directory where the mscgen tool resides. If left empty the tool is assumed to +# be found in the default search path. + +MSCGEN_PATH = + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = NO + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = NO + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = NO + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = NO + +# If the CALL_GRAPH, SOURCE_BROWSER and HAVE_DOT tags are set to YES then doxygen will +# generate a call dependency graph for every global function or class method. +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable call graphs for selected +# functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the CALLER_GRAPH, SOURCE_BROWSER and HAVE_DOT tags are set to YES then doxygen will +# generate a caller dependency graph for every global function or class method. +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable caller graphs for selected +# functions only using the \callergraph command. + +CALLER_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = NO + +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = NO + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MAX_DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen if the number +# of direct children of the root node in a graph is already larger than +# MAX_DOT_GRAPH_NOTES then the graph will not be shown at all. Also note +# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. + +DOT_GRAPH_MAX_NODES = 50 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, which results in a white background. +# Warning: Depending on the platform used, enabling this option may lead to +# badly anti-aliased labels on the edges of a graph (i.e. they become hard to +# read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- + +# The SEARCHENGINE tag specifies whether or not a search engine should be +# used. If set to NO the values of all tags below this one will be ignored. + +SEARCHENGINE = NO diff --git a/Legacy/Aria/examples/All_Examples-vc2003.sln b/Legacy/Aria/examples/All_Examples-vc2003.sln new file mode 100644 index 0000000..2de0236 --- /dev/null +++ b/Legacy/Aria/examples/All_Examples-vc2003.sln @@ -0,0 +1,325 @@ +Microsoft Visual Studio Solution File, Format Version 8.00 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "actionExample", "actionExample-vc2003.vcproj", "{2B257343-C6CC-4017-87B6-959D447DA735}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demo", "demo-vc2003.vcproj", "{2FE13778-630C-434B-B3C0-AE0352E274CE}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gyroExample", "gyroExample-vc2003.vcproj", "{1A8C458C-0086-4788-AF12-F1DFA5EBAD53}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ipthru", "ipthru-vc2003.vcproj", "{B0CD9146-122F-49FD-A12A-7A970514DFB1}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "joydriveThreaded", "joydriveThreaded-vc2003.vcproj", "{B6C39214-2167-4B3D-8C01-2D98A5642F8E}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "joydriveUserTask", "joydriveUserTask-vc2003.vcproj", "{B6F8EFCF-6C73-4C5C-98F4-0166E0DB0B53}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sickLogger", "sickLogger-vc2003.vcproj", "{F2F3B4A0-9CDF-494F-B7B8-9442EBB6BA5F}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sickTeleop", "sickTeleop-vc2003.vcproj", "{705A253A-1107-4575-9F3D-B3A20420F731}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sonyPTZDemo", "sonyPTZDemo-vc2003.vcproj", "{F7696DAA-98A9-4E34-B6DE-5AAF4D2314D0}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "twoRobotWander", "twoRobotWander-vc2003.vcproj", "{587F7690-442B-4568-A0BF-75CBF57EF3FF}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wander", "wander-vc2003.vcproj", "{5239B513-8B95-4EDB-9FBA-63CB8D7CDEA3}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AriaDLL", "..\src\AriaDLL-vc2003.vcproj", "{606257AE-E882-4C66-84C0-72331642D09F}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wanderAndLogData", "wanderAndLogData-vc2003.vcproj", "{06616FA8-EBC6-4B23-B70C-E332A19160F1}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "actionGroupExample", "actionGroupExample-vc2003.vcproj", "{7AD289AA-1C88-4EF2-B095-3234C613A08D}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "socketClientExample", "socketClientExample-vc2003.vcproj", "{5571A55D-018E-485E-802E-D3F200D587DC}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "armExample", "armExample-vc2003.vcproj", "{731EC481-379F-4041-BEBD-358C26ACE117}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "auxSerialExample", "auxSerialExample-vc2003.vcproj", "{77DBE5F8-13CD-49FB-A4D9-35E360EC8992}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "directMotionExample", "directMotionExample-vc2003.vcproj", "{BD31FF37-DDBD-4BBD-9ABC-5DE439735DBF}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dpptuExample", "dpptuExample-vc2003.vcproj", "{EE1BFE24-2F7E-475C-A2F9-B11065EB6F5C}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "functorExample", "functorExample-vc2003.vcproj", "{4AD6E4D3-7C44-4697-8794-BFBA43BFE13D}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gotoActionExample", "gotoActionExample-vc2003.vcproj", "{FAD55BE4-E1C6-436D-BC7D-B0674FB8C067}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gripperExample", "gripperExample-vc2003.vcproj", "{8DB12A26-FF33-46BE-800E-2CBB06774473}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "joydriveActionExample", "joydriveActionExample-vc2003.vcproj", "{7E142B72-A049-4AB6-AB31-AEA652955B02}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "netServerExample", "netServerExample-vc2003.vcproj", "{806CF3BE-8A4D-4C32-8574-58F3E85CA08C}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "robotSyncTaskExample", "robotSyncTaskExample-vc2003.vcproj", "{69571F42-5098-41FB-B8A8-19ECCCDB9BB3}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "socketServerExample", "socketServerExample-vc2003.vcproj", "{CD42EA8C-AEEC-4B0A-AAE5-C8096EB9ACDF}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "soundsQueueExample", "soundsQueueExample-vc2003.vcproj", "{2F512A11-402E-496D-B20C-806414BDFE9F}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "teleopActionsExample", "teleopActionsExample-vc2003.vcproj", "{9E2494B2-5359-47C8-9122-549EDD467615}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vcc4CameraExample", "vcc4CameraExample-vc2003.vcproj", "{F1757D78-5C7C-468D-AB53-7571B3F48975}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gpsExample", "gpsExample-vc2003.vcproj", "{39B4C09E-E4E3-457F-B96C-B85D03C93B55}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "simpleConnect", "simpleConnect-vc2003.vcproj", "{D6C8A2A9-C3E1-4F70-924D-BDEA60B4C667}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AriaStatic", "..\src\AriaStatic-vc2003.vcproj", "{527BBF7C-631F-486B-8E4F-EA594299A71A}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "actsColorFollowingExample", "actsColorFollowingExample-vc2003.vcproj", "{E17D0EDD-D945-4DC4-9C7C-FA21E2933FB0}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "threadExample", "threadExample-vc2003.vcproj", "{8280A5D9-7E6E-420F-9E54-F08314A23983}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demoStatic", "demoStatic-vc2003.vcproj", "{261FB793-1763-411D-A71B-D8FD9DB3B704}" + ProjectSection(ProjectDependencies) = postProject + {527BBF7C-631F-486B-8E4F-EA594299A71A} = {527BBF7C-631F-486B-8E4F-EA594299A71A} + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfiguration) = preSolution + Debug = Debug + Release = Release + EndGlobalSection + GlobalSection(ProjectConfiguration) = postSolution + {2B257343-C6CC-4017-87B6-959D447DA735}.Debug.ActiveCfg = Debug|Win32 + {2B257343-C6CC-4017-87B6-959D447DA735}.Debug.Build.0 = Debug|Win32 + {2B257343-C6CC-4017-87B6-959D447DA735}.Release.ActiveCfg = Release|Win32 + {2B257343-C6CC-4017-87B6-959D447DA735}.Release.Build.0 = Release|Win32 + {2FE13778-630C-434B-B3C0-AE0352E274CE}.Debug.ActiveCfg = Debug|Win32 + {2FE13778-630C-434B-B3C0-AE0352E274CE}.Debug.Build.0 = Debug|Win32 + {2FE13778-630C-434B-B3C0-AE0352E274CE}.Release.ActiveCfg = Release|Win32 + {2FE13778-630C-434B-B3C0-AE0352E274CE}.Release.Build.0 = Release|Win32 + {1A8C458C-0086-4788-AF12-F1DFA5EBAD53}.Debug.ActiveCfg = Debug|Win32 + {1A8C458C-0086-4788-AF12-F1DFA5EBAD53}.Debug.Build.0 = Debug|Win32 + {1A8C458C-0086-4788-AF12-F1DFA5EBAD53}.Release.ActiveCfg = Release|Win32 + {1A8C458C-0086-4788-AF12-F1DFA5EBAD53}.Release.Build.0 = Release|Win32 + {B0CD9146-122F-49FD-A12A-7A970514DFB1}.Debug.ActiveCfg = Debug|Win32 + {B0CD9146-122F-49FD-A12A-7A970514DFB1}.Debug.Build.0 = Debug|Win32 + {B0CD9146-122F-49FD-A12A-7A970514DFB1}.Release.ActiveCfg = Release|Win32 + {B0CD9146-122F-49FD-A12A-7A970514DFB1}.Release.Build.0 = Release|Win32 + {B6C39214-2167-4B3D-8C01-2D98A5642F8E}.Debug.ActiveCfg = Debug|Win32 + {B6C39214-2167-4B3D-8C01-2D98A5642F8E}.Debug.Build.0 = Debug|Win32 + {B6C39214-2167-4B3D-8C01-2D98A5642F8E}.Release.ActiveCfg = Release|Win32 + {B6C39214-2167-4B3D-8C01-2D98A5642F8E}.Release.Build.0 = Release|Win32 + {B6F8EFCF-6C73-4C5C-98F4-0166E0DB0B53}.Debug.ActiveCfg = Debug|Win32 + {B6F8EFCF-6C73-4C5C-98F4-0166E0DB0B53}.Debug.Build.0 = Debug|Win32 + {B6F8EFCF-6C73-4C5C-98F4-0166E0DB0B53}.Release.ActiveCfg = Release|Win32 + {B6F8EFCF-6C73-4C5C-98F4-0166E0DB0B53}.Release.Build.0 = Release|Win32 + {F2F3B4A0-9CDF-494F-B7B8-9442EBB6BA5F}.Debug.ActiveCfg = Debug|Win32 + {F2F3B4A0-9CDF-494F-B7B8-9442EBB6BA5F}.Debug.Build.0 = Debug|Win32 + {F2F3B4A0-9CDF-494F-B7B8-9442EBB6BA5F}.Release.ActiveCfg = Release|Win32 + {F2F3B4A0-9CDF-494F-B7B8-9442EBB6BA5F}.Release.Build.0 = Release|Win32 + {705A253A-1107-4575-9F3D-B3A20420F731}.Debug.ActiveCfg = Debug|Win32 + {705A253A-1107-4575-9F3D-B3A20420F731}.Debug.Build.0 = Debug|Win32 + {705A253A-1107-4575-9F3D-B3A20420F731}.Release.ActiveCfg = Release|Win32 + {705A253A-1107-4575-9F3D-B3A20420F731}.Release.Build.0 = Release|Win32 + {F7696DAA-98A9-4E34-B6DE-5AAF4D2314D0}.Debug.ActiveCfg = Debug|Win32 + {F7696DAA-98A9-4E34-B6DE-5AAF4D2314D0}.Debug.Build.0 = Debug|Win32 + {F7696DAA-98A9-4E34-B6DE-5AAF4D2314D0}.Release.ActiveCfg = Release|Win32 + {F7696DAA-98A9-4E34-B6DE-5AAF4D2314D0}.Release.Build.0 = Release|Win32 + {587F7690-442B-4568-A0BF-75CBF57EF3FF}.Debug.ActiveCfg = Debug|Win32 + {587F7690-442B-4568-A0BF-75CBF57EF3FF}.Debug.Build.0 = Debug|Win32 + {587F7690-442B-4568-A0BF-75CBF57EF3FF}.Release.ActiveCfg = Release|Win32 + {587F7690-442B-4568-A0BF-75CBF57EF3FF}.Release.Build.0 = Release|Win32 + {5239B513-8B95-4EDB-9FBA-63CB8D7CDEA3}.Debug.ActiveCfg = Debug|Win32 + {5239B513-8B95-4EDB-9FBA-63CB8D7CDEA3}.Debug.Build.0 = Debug|Win32 + {5239B513-8B95-4EDB-9FBA-63CB8D7CDEA3}.Release.ActiveCfg = Release|Win32 + {5239B513-8B95-4EDB-9FBA-63CB8D7CDEA3}.Release.Build.0 = Release|Win32 + {606257AE-E882-4C66-84C0-72331642D09F}.Debug.ActiveCfg = Debug|Win32 + {606257AE-E882-4C66-84C0-72331642D09F}.Debug.Build.0 = Debug|Win32 + {606257AE-E882-4C66-84C0-72331642D09F}.Release.ActiveCfg = Release|Win32 + {606257AE-E882-4C66-84C0-72331642D09F}.Release.Build.0 = Release|Win32 + {06616FA8-EBC6-4B23-B70C-E332A19160F1}.Debug.ActiveCfg = Debug|Win32 + {06616FA8-EBC6-4B23-B70C-E332A19160F1}.Debug.Build.0 = Debug|Win32 + {06616FA8-EBC6-4B23-B70C-E332A19160F1}.Release.ActiveCfg = Release|Win32 + {06616FA8-EBC6-4B23-B70C-E332A19160F1}.Release.Build.0 = Release|Win32 + {7AD289AA-1C88-4EF2-B095-3234C613A08D}.Debug.ActiveCfg = Debug|Win32 + {7AD289AA-1C88-4EF2-B095-3234C613A08D}.Debug.Build.0 = Debug|Win32 + {7AD289AA-1C88-4EF2-B095-3234C613A08D}.Release.ActiveCfg = Release|Win32 + {7AD289AA-1C88-4EF2-B095-3234C613A08D}.Release.Build.0 = Release|Win32 + {5571A55D-018E-485E-802E-D3F200D587DC}.Debug.ActiveCfg = Debug|Win32 + {5571A55D-018E-485E-802E-D3F200D587DC}.Debug.Build.0 = Debug|Win32 + {5571A55D-018E-485E-802E-D3F200D587DC}.Release.ActiveCfg = Release|Win32 + {5571A55D-018E-485E-802E-D3F200D587DC}.Release.Build.0 = Release|Win32 + {731EC481-379F-4041-BEBD-358C26ACE117}.Debug.ActiveCfg = Debug|Win32 + {731EC481-379F-4041-BEBD-358C26ACE117}.Debug.Build.0 = Debug|Win32 + {731EC481-379F-4041-BEBD-358C26ACE117}.Release.ActiveCfg = Release|Win32 + {731EC481-379F-4041-BEBD-358C26ACE117}.Release.Build.0 = Release|Win32 + {77DBE5F8-13CD-49FB-A4D9-35E360EC8992}.Debug.ActiveCfg = Debug|Win32 + {77DBE5F8-13CD-49FB-A4D9-35E360EC8992}.Debug.Build.0 = Debug|Win32 + {77DBE5F8-13CD-49FB-A4D9-35E360EC8992}.Release.ActiveCfg = Release|Win32 + {77DBE5F8-13CD-49FB-A4D9-35E360EC8992}.Release.Build.0 = Release|Win32 + {BD31FF37-DDBD-4BBD-9ABC-5DE439735DBF}.Debug.ActiveCfg = Debug|Win32 + {BD31FF37-DDBD-4BBD-9ABC-5DE439735DBF}.Debug.Build.0 = Debug|Win32 + {BD31FF37-DDBD-4BBD-9ABC-5DE439735DBF}.Release.ActiveCfg = Release|Win32 + {BD31FF37-DDBD-4BBD-9ABC-5DE439735DBF}.Release.Build.0 = Release|Win32 + {EE1BFE24-2F7E-475C-A2F9-B11065EB6F5C}.Debug.ActiveCfg = Debug|Win32 + {EE1BFE24-2F7E-475C-A2F9-B11065EB6F5C}.Debug.Build.0 = Debug|Win32 + {EE1BFE24-2F7E-475C-A2F9-B11065EB6F5C}.Release.ActiveCfg = Release|Win32 + {EE1BFE24-2F7E-475C-A2F9-B11065EB6F5C}.Release.Build.0 = Release|Win32 + {4AD6E4D3-7C44-4697-8794-BFBA43BFE13D}.Debug.ActiveCfg = Debug|Win32 + {4AD6E4D3-7C44-4697-8794-BFBA43BFE13D}.Debug.Build.0 = Debug|Win32 + {4AD6E4D3-7C44-4697-8794-BFBA43BFE13D}.Release.ActiveCfg = Release|Win32 + {4AD6E4D3-7C44-4697-8794-BFBA43BFE13D}.Release.Build.0 = Release|Win32 + {FAD55BE4-E1C6-436D-BC7D-B0674FB8C067}.Debug.ActiveCfg = Debug|Win32 + {FAD55BE4-E1C6-436D-BC7D-B0674FB8C067}.Debug.Build.0 = Debug|Win32 + {FAD55BE4-E1C6-436D-BC7D-B0674FB8C067}.Release.ActiveCfg = Release|Win32 + {FAD55BE4-E1C6-436D-BC7D-B0674FB8C067}.Release.Build.0 = Release|Win32 + {8DB12A26-FF33-46BE-800E-2CBB06774473}.Debug.ActiveCfg = Debug|Win32 + {8DB12A26-FF33-46BE-800E-2CBB06774473}.Debug.Build.0 = Debug|Win32 + {8DB12A26-FF33-46BE-800E-2CBB06774473}.Release.ActiveCfg = Release|Win32 + {8DB12A26-FF33-46BE-800E-2CBB06774473}.Release.Build.0 = Release|Win32 + {7E142B72-A049-4AB6-AB31-AEA652955B02}.Debug.ActiveCfg = Debug|Win32 + {7E142B72-A049-4AB6-AB31-AEA652955B02}.Debug.Build.0 = Debug|Win32 + {7E142B72-A049-4AB6-AB31-AEA652955B02}.Release.ActiveCfg = Release|Win32 + {7E142B72-A049-4AB6-AB31-AEA652955B02}.Release.Build.0 = Release|Win32 + {806CF3BE-8A4D-4C32-8574-58F3E85CA08C}.Debug.ActiveCfg = Debug|Win32 + {806CF3BE-8A4D-4C32-8574-58F3E85CA08C}.Debug.Build.0 = Debug|Win32 + {806CF3BE-8A4D-4C32-8574-58F3E85CA08C}.Release.ActiveCfg = Release|Win32 + {806CF3BE-8A4D-4C32-8574-58F3E85CA08C}.Release.Build.0 = Release|Win32 + {69571F42-5098-41FB-B8A8-19ECCCDB9BB3}.Debug.ActiveCfg = Debug|Win32 + {69571F42-5098-41FB-B8A8-19ECCCDB9BB3}.Debug.Build.0 = Debug|Win32 + {69571F42-5098-41FB-B8A8-19ECCCDB9BB3}.Release.ActiveCfg = Release|Win32 + {69571F42-5098-41FB-B8A8-19ECCCDB9BB3}.Release.Build.0 = Release|Win32 + {CD42EA8C-AEEC-4B0A-AAE5-C8096EB9ACDF}.Debug.ActiveCfg = Debug|Win32 + {CD42EA8C-AEEC-4B0A-AAE5-C8096EB9ACDF}.Debug.Build.0 = Debug|Win32 + {CD42EA8C-AEEC-4B0A-AAE5-C8096EB9ACDF}.Release.ActiveCfg = Release|Win32 + {CD42EA8C-AEEC-4B0A-AAE5-C8096EB9ACDF}.Release.Build.0 = Release|Win32 + {2F512A11-402E-496D-B20C-806414BDFE9F}.Debug.ActiveCfg = Debug|Win32 + {2F512A11-402E-496D-B20C-806414BDFE9F}.Debug.Build.0 = Debug|Win32 + {2F512A11-402E-496D-B20C-806414BDFE9F}.Release.ActiveCfg = Release|Win32 + {2F512A11-402E-496D-B20C-806414BDFE9F}.Release.Build.0 = Release|Win32 + {9E2494B2-5359-47C8-9122-549EDD467615}.Debug.ActiveCfg = Debug|Win32 + {9E2494B2-5359-47C8-9122-549EDD467615}.Debug.Build.0 = Debug|Win32 + {9E2494B2-5359-47C8-9122-549EDD467615}.Release.ActiveCfg = Release|Win32 + {9E2494B2-5359-47C8-9122-549EDD467615}.Release.Build.0 = Release|Win32 + {F1757D78-5C7C-468D-AB53-7571B3F48975}.Debug.ActiveCfg = Debug|Win32 + {F1757D78-5C7C-468D-AB53-7571B3F48975}.Debug.Build.0 = Debug|Win32 + {F1757D78-5C7C-468D-AB53-7571B3F48975}.Release.ActiveCfg = Release|Win32 + {F1757D78-5C7C-468D-AB53-7571B3F48975}.Release.Build.0 = Release|Win32 + {39B4C09E-E4E3-457F-B96C-B85D03C93B55}.Debug.ActiveCfg = Debug|Win32 + {39B4C09E-E4E3-457F-B96C-B85D03C93B55}.Debug.Build.0 = Debug|Win32 + {39B4C09E-E4E3-457F-B96C-B85D03C93B55}.Release.ActiveCfg = Release|Win32 + {39B4C09E-E4E3-457F-B96C-B85D03C93B55}.Release.Build.0 = Release|Win32 + {D6C8A2A9-C3E1-4F70-924D-BDEA60B4C667}.Debug.ActiveCfg = Debug|Win32 + {D6C8A2A9-C3E1-4F70-924D-BDEA60B4C667}.Debug.Build.0 = Debug|Win32 + {D6C8A2A9-C3E1-4F70-924D-BDEA60B4C667}.Release.ActiveCfg = Release|Win32 + {D6C8A2A9-C3E1-4F70-924D-BDEA60B4C667}.Release.Build.0 = Release|Win32 + {527BBF7C-631F-486B-8E4F-EA594299A71A}.Debug.ActiveCfg = Debug|Win32 + {527BBF7C-631F-486B-8E4F-EA594299A71A}.Debug.Build.0 = Debug|Win32 + {527BBF7C-631F-486B-8E4F-EA594299A71A}.Release.ActiveCfg = Release|Win32 + {527BBF7C-631F-486B-8E4F-EA594299A71A}.Release.Build.0 = Release|Win32 + {E17D0EDD-D945-4DC4-9C7C-FA21E2933FB0}.Debug.ActiveCfg = Debug|Win32 + {E17D0EDD-D945-4DC4-9C7C-FA21E2933FB0}.Debug.Build.0 = Debug|Win32 + {E17D0EDD-D945-4DC4-9C7C-FA21E2933FB0}.Release.ActiveCfg = Release|Win32 + {E17D0EDD-D945-4DC4-9C7C-FA21E2933FB0}.Release.Build.0 = Release|Win32 + {8280A5D9-7E6E-420F-9E54-F08314A23983}.Debug.ActiveCfg = Debug|Win32 + {8280A5D9-7E6E-420F-9E54-F08314A23983}.Debug.Build.0 = Debug|Win32 + {8280A5D9-7E6E-420F-9E54-F08314A23983}.Release.ActiveCfg = Release|Win32 + {8280A5D9-7E6E-420F-9E54-F08314A23983}.Release.Build.0 = Release|Win32 + {261FB793-1763-411D-A71B-D8FD9DB3B704}.Debug.ActiveCfg = Debug|Win32 + {261FB793-1763-411D-A71B-D8FD9DB3B704}.Debug.Build.0 = Debug|Win32 + {261FB793-1763-411D-A71B-D8FD9DB3B704}.Release.ActiveCfg = Release|Win32 + {261FB793-1763-411D-A71B-D8FD9DB3B704}.Release.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + EndGlobalSection + GlobalSection(ExtensibilityAddIns) = postSolution + EndGlobalSection +EndGlobal diff --git a/Legacy/Aria/examples/All_Examples-vc2008.sln b/Legacy/Aria/examples/All_Examples-vc2008.sln new file mode 100644 index 0000000..79b9af0 --- /dev/null +++ b/Legacy/Aria/examples/All_Examples-vc2008.sln @@ -0,0 +1,286 @@ +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual C++ Express 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "actionExample", "actionExample-vc2008.vcproj", "{2B257343-C6CC-4017-87B6-959D447DA735}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demo", "demo-vc2008.vcproj", "{E1137892-32C1-4250-8784-8D48A6BEE2DD}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gyroExample", "gyroExample-vc2008.vcproj", "{1A8C458C-0086-4788-AF12-F1DFA5EBAD53}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ipthru", "ipthru-vc2008.vcproj", "{B0CD9146-122F-49FD-A12A-7A970514DFB1}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "joydriveThreaded", "joydriveThreaded-vc2008.vcproj", "{B6C39214-2167-4B3D-8C01-2D98A5642F8E}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "joydriveUserTask", "joydriveUserTask-vc2008.vcproj", "{B6F8EFCF-6C73-4C5C-98F4-0166E0DB0B53}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sickLogger", "sickLogger-vc2008.vcproj", "{F2F3B4A0-9CDF-494F-B7B8-9442EBB6BA5F}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sickTeleop", "sickTeleop-vc2008.vcproj", "{705A253A-1107-4575-9F3D-B3A20420F731}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wander", "wander-vc2008.vcproj", "{5239B513-8B95-4EDB-9FBA-63CB8D7CDEA3}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AriaDLL", "..\src\AriaDLL-vc2008.vcproj", "{606257AE-E882-4C66-84C0-72331642D09F}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wanderAndLogData", "wanderAndLogData-vc2008.vcproj", "{06616FA8-EBC6-4B23-B70C-E332A19160F1}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "actionGroupExample", "actionGroupExample-vc2008.vcproj", "{7AD289AA-1C88-4EF2-B095-3234C613A08D}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "socketClientExample", "socketClientExample-vc2008.vcproj", "{5571A55D-018E-485E-802E-D3F200D587DC}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "armExample", "armExample-vc2008.vcproj", "{731EC481-379F-4041-BEBD-358C26ACE117}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "auxSerialExample", "auxSerialExample-vc2008.vcproj", "{77DBE5F8-13CD-49FB-A4D9-35E360EC8992}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "directMotionExample", "directMotionExample-vc2008.vcproj", "{BD31FF37-DDBD-4BBD-9ABC-5DE439735DBF}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dpptuExample", "dpptuExample-vc2008.vcproj", "{EE1BFE24-2F7E-475C-A2F9-B11065EB6F5C}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "functorExample", "functorExample-vc2008.vcproj", "{4AD6E4D3-7C44-4697-8794-BFBA43BFE13D}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gotoActionExample", "gotoActionExample-vc2008.vcproj", "{FAD55BE4-E1C6-436D-BC7D-B0674FB8C067}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gripperExample", "gripperExample-vc2008.vcproj", "{8DB12A26-FF33-46BE-800E-2CBB06774473}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "joydriveActionExample", "joydriveActionExample-vc2008.vcproj", "{7E142B72-A049-4AB6-AB31-AEA652955B02}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "netServerExample", "netServerExample-vc2008.vcproj", "{806CF3BE-8A4D-4C32-8574-58F3E85CA08C}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "robotSyncTaskExample", "robotSyncTaskExample-vc2008.vcproj", "{69571F42-5098-41FB-B8A8-19ECCCDB9BB3}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "soundsQueueExample", "soundsQueueExample-vc2008.vcproj", "{2F512A11-402E-496D-B20C-806414BDFE9F}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "teleopActionsExample", "teleopActionsExample-vc2008.vcproj", "{9E2494B2-5359-47C8-9122-549EDD467615}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vcc4CameraExample", "vcc4CameraExample-vc2008.vcproj", "{F1757D78-5C7C-468D-AB53-7571B3F48975}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gpsExample", "gpsExample-vc2008.vcproj", "{39B4C09E-E4E3-457F-B96C-B85D03C93B55}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "simpleConnect", "simpleConnect-vc2008.vcproj", "{D6C8A2A9-C3E1-4F70-924D-BDEA60B4C667}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AriaStatic", "..\src\AriaStatic-vc2008.vcproj", "{527BBF7C-631F-486B-8E4F-EA594299A71A}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "actsColorFollowingExample", "actsColorFollowingExample-vc2008.vcproj", "{E17D0EDD-D945-4DC4-9C7C-FA21E2933FB0}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "threadExample", "threadExample-vc2008.vcproj", "{4BB4D8FF-F83B-406A-85AF-C7DF75ABCF59}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {2B257343-C6CC-4017-87B6-959D447DA735}.Debug|Win32.ActiveCfg = Debug|Win32 + {2B257343-C6CC-4017-87B6-959D447DA735}.Debug|Win32.Build.0 = Debug|Win32 + {2B257343-C6CC-4017-87B6-959D447DA735}.Release|Win32.ActiveCfg = Release|Win32 + {2B257343-C6CC-4017-87B6-959D447DA735}.Release|Win32.Build.0 = Release|Win32 + {E1137892-32C1-4250-8784-8D48A6BEE2DD}.Debug|Win32.ActiveCfg = Debug|Win32 + {E1137892-32C1-4250-8784-8D48A6BEE2DD}.Debug|Win32.Build.0 = Debug|Win32 + {E1137892-32C1-4250-8784-8D48A6BEE2DD}.Release|Win32.ActiveCfg = Release|Win32 + {E1137892-32C1-4250-8784-8D48A6BEE2DD}.Release|Win32.Build.0 = Release|Win32 + {1A8C458C-0086-4788-AF12-F1DFA5EBAD53}.Debug|Win32.ActiveCfg = Debug|Win32 + {1A8C458C-0086-4788-AF12-F1DFA5EBAD53}.Debug|Win32.Build.0 = Debug|Win32 + {1A8C458C-0086-4788-AF12-F1DFA5EBAD53}.Release|Win32.ActiveCfg = Release|Win32 + {1A8C458C-0086-4788-AF12-F1DFA5EBAD53}.Release|Win32.Build.0 = Release|Win32 + {B0CD9146-122F-49FD-A12A-7A970514DFB1}.Debug|Win32.ActiveCfg = Debug|Win32 + {B0CD9146-122F-49FD-A12A-7A970514DFB1}.Debug|Win32.Build.0 = Debug|Win32 + {B0CD9146-122F-49FD-A12A-7A970514DFB1}.Release|Win32.ActiveCfg = Release|Win32 + {B0CD9146-122F-49FD-A12A-7A970514DFB1}.Release|Win32.Build.0 = Release|Win32 + {B6C39214-2167-4B3D-8C01-2D98A5642F8E}.Debug|Win32.ActiveCfg = Debug|Win32 + {B6C39214-2167-4B3D-8C01-2D98A5642F8E}.Debug|Win32.Build.0 = Debug|Win32 + {B6C39214-2167-4B3D-8C01-2D98A5642F8E}.Release|Win32.ActiveCfg = Release|Win32 + {B6C39214-2167-4B3D-8C01-2D98A5642F8E}.Release|Win32.Build.0 = Release|Win32 + {B6F8EFCF-6C73-4C5C-98F4-0166E0DB0B53}.Debug|Win32.ActiveCfg = Debug|Win32 + {B6F8EFCF-6C73-4C5C-98F4-0166E0DB0B53}.Debug|Win32.Build.0 = Debug|Win32 + {B6F8EFCF-6C73-4C5C-98F4-0166E0DB0B53}.Release|Win32.ActiveCfg = Release|Win32 + {B6F8EFCF-6C73-4C5C-98F4-0166E0DB0B53}.Release|Win32.Build.0 = Release|Win32 + {F2F3B4A0-9CDF-494F-B7B8-9442EBB6BA5F}.Debug|Win32.ActiveCfg = Debug|Win32 + {F2F3B4A0-9CDF-494F-B7B8-9442EBB6BA5F}.Debug|Win32.Build.0 = Debug|Win32 + {F2F3B4A0-9CDF-494F-B7B8-9442EBB6BA5F}.Release|Win32.ActiveCfg = Release|Win32 + {F2F3B4A0-9CDF-494F-B7B8-9442EBB6BA5F}.Release|Win32.Build.0 = Release|Win32 + {705A253A-1107-4575-9F3D-B3A20420F731}.Debug|Win32.ActiveCfg = Debug|Win32 + {705A253A-1107-4575-9F3D-B3A20420F731}.Debug|Win32.Build.0 = Debug|Win32 + {705A253A-1107-4575-9F3D-B3A20420F731}.Release|Win32.ActiveCfg = Release|Win32 + {705A253A-1107-4575-9F3D-B3A20420F731}.Release|Win32.Build.0 = Release|Win32 + {5239B513-8B95-4EDB-9FBA-63CB8D7CDEA3}.Debug|Win32.ActiveCfg = Debug|Win32 + {5239B513-8B95-4EDB-9FBA-63CB8D7CDEA3}.Debug|Win32.Build.0 = Debug|Win32 + {5239B513-8B95-4EDB-9FBA-63CB8D7CDEA3}.Release|Win32.ActiveCfg = Release|Win32 + {5239B513-8B95-4EDB-9FBA-63CB8D7CDEA3}.Release|Win32.Build.0 = Release|Win32 + {606257AE-E882-4C66-84C0-72331642D09F}.Debug|Win32.ActiveCfg = Debug|Win32 + {606257AE-E882-4C66-84C0-72331642D09F}.Debug|Win32.Build.0 = Debug|Win32 + {606257AE-E882-4C66-84C0-72331642D09F}.Release|Win32.ActiveCfg = Release|Win32 + {606257AE-E882-4C66-84C0-72331642D09F}.Release|Win32.Build.0 = Release|Win32 + {06616FA8-EBC6-4B23-B70C-E332A19160F1}.Debug|Win32.ActiveCfg = Debug|Win32 + {06616FA8-EBC6-4B23-B70C-E332A19160F1}.Debug|Win32.Build.0 = Debug|Win32 + {06616FA8-EBC6-4B23-B70C-E332A19160F1}.Release|Win32.ActiveCfg = Release|Win32 + {06616FA8-EBC6-4B23-B70C-E332A19160F1}.Release|Win32.Build.0 = Release|Win32 + {7AD289AA-1C88-4EF2-B095-3234C613A08D}.Debug|Win32.ActiveCfg = Debug|Win32 + {7AD289AA-1C88-4EF2-B095-3234C613A08D}.Debug|Win32.Build.0 = Debug|Win32 + {7AD289AA-1C88-4EF2-B095-3234C613A08D}.Release|Win32.ActiveCfg = Release|Win32 + {7AD289AA-1C88-4EF2-B095-3234C613A08D}.Release|Win32.Build.0 = Release|Win32 + {5571A55D-018E-485E-802E-D3F200D587DC}.Debug|Win32.ActiveCfg = Debug|Win32 + {5571A55D-018E-485E-802E-D3F200D587DC}.Debug|Win32.Build.0 = Debug|Win32 + {5571A55D-018E-485E-802E-D3F200D587DC}.Release|Win32.ActiveCfg = Release|Win32 + {5571A55D-018E-485E-802E-D3F200D587DC}.Release|Win32.Build.0 = Release|Win32 + {731EC481-379F-4041-BEBD-358C26ACE117}.Debug|Win32.ActiveCfg = Debug|Win32 + {731EC481-379F-4041-BEBD-358C26ACE117}.Debug|Win32.Build.0 = Debug|Win32 + {731EC481-379F-4041-BEBD-358C26ACE117}.Release|Win32.ActiveCfg = Release|Win32 + {731EC481-379F-4041-BEBD-358C26ACE117}.Release|Win32.Build.0 = Release|Win32 + {77DBE5F8-13CD-49FB-A4D9-35E360EC8992}.Debug|Win32.ActiveCfg = Debug|Win32 + {77DBE5F8-13CD-49FB-A4D9-35E360EC8992}.Debug|Win32.Build.0 = Debug|Win32 + {77DBE5F8-13CD-49FB-A4D9-35E360EC8992}.Release|Win32.ActiveCfg = Release|Win32 + {77DBE5F8-13CD-49FB-A4D9-35E360EC8992}.Release|Win32.Build.0 = Release|Win32 + {BD31FF37-DDBD-4BBD-9ABC-5DE439735DBF}.Debug|Win32.ActiveCfg = Debug|Win32 + {BD31FF37-DDBD-4BBD-9ABC-5DE439735DBF}.Debug|Win32.Build.0 = Debug|Win32 + {BD31FF37-DDBD-4BBD-9ABC-5DE439735DBF}.Release|Win32.ActiveCfg = Release|Win32 + {BD31FF37-DDBD-4BBD-9ABC-5DE439735DBF}.Release|Win32.Build.0 = Release|Win32 + {EE1BFE24-2F7E-475C-A2F9-B11065EB6F5C}.Debug|Win32.ActiveCfg = Debug|Win32 + {EE1BFE24-2F7E-475C-A2F9-B11065EB6F5C}.Debug|Win32.Build.0 = Debug|Win32 + {EE1BFE24-2F7E-475C-A2F9-B11065EB6F5C}.Release|Win32.ActiveCfg = Release|Win32 + {EE1BFE24-2F7E-475C-A2F9-B11065EB6F5C}.Release|Win32.Build.0 = Release|Win32 + {4AD6E4D3-7C44-4697-8794-BFBA43BFE13D}.Debug|Win32.ActiveCfg = Debug|Win32 + {4AD6E4D3-7C44-4697-8794-BFBA43BFE13D}.Debug|Win32.Build.0 = Debug|Win32 + {4AD6E4D3-7C44-4697-8794-BFBA43BFE13D}.Release|Win32.ActiveCfg = Release|Win32 + {4AD6E4D3-7C44-4697-8794-BFBA43BFE13D}.Release|Win32.Build.0 = Release|Win32 + {FAD55BE4-E1C6-436D-BC7D-B0674FB8C067}.Debug|Win32.ActiveCfg = Debug|Win32 + {FAD55BE4-E1C6-436D-BC7D-B0674FB8C067}.Debug|Win32.Build.0 = Debug|Win32 + {FAD55BE4-E1C6-436D-BC7D-B0674FB8C067}.Release|Win32.ActiveCfg = Release|Win32 + {FAD55BE4-E1C6-436D-BC7D-B0674FB8C067}.Release|Win32.Build.0 = Release|Win32 + {8DB12A26-FF33-46BE-800E-2CBB06774473}.Debug|Win32.ActiveCfg = Debug|Win32 + {8DB12A26-FF33-46BE-800E-2CBB06774473}.Debug|Win32.Build.0 = Debug|Win32 + {8DB12A26-FF33-46BE-800E-2CBB06774473}.Release|Win32.ActiveCfg = Release|Win32 + {8DB12A26-FF33-46BE-800E-2CBB06774473}.Release|Win32.Build.0 = Release|Win32 + {7E142B72-A049-4AB6-AB31-AEA652955B02}.Debug|Win32.ActiveCfg = Debug|Win32 + {7E142B72-A049-4AB6-AB31-AEA652955B02}.Debug|Win32.Build.0 = Debug|Win32 + {7E142B72-A049-4AB6-AB31-AEA652955B02}.Release|Win32.ActiveCfg = Release|Win32 + {7E142B72-A049-4AB6-AB31-AEA652955B02}.Release|Win32.Build.0 = Release|Win32 + {806CF3BE-8A4D-4C32-8574-58F3E85CA08C}.Debug|Win32.ActiveCfg = Debug|Win32 + {806CF3BE-8A4D-4C32-8574-58F3E85CA08C}.Debug|Win32.Build.0 = Debug|Win32 + {806CF3BE-8A4D-4C32-8574-58F3E85CA08C}.Release|Win32.ActiveCfg = Release|Win32 + {806CF3BE-8A4D-4C32-8574-58F3E85CA08C}.Release|Win32.Build.0 = Release|Win32 + {69571F42-5098-41FB-B8A8-19ECCCDB9BB3}.Debug|Win32.ActiveCfg = Debug|Win32 + {69571F42-5098-41FB-B8A8-19ECCCDB9BB3}.Debug|Win32.Build.0 = Debug|Win32 + {69571F42-5098-41FB-B8A8-19ECCCDB9BB3}.Release|Win32.ActiveCfg = Release|Win32 + {69571F42-5098-41FB-B8A8-19ECCCDB9BB3}.Release|Win32.Build.0 = Release|Win32 + {2F512A11-402E-496D-B20C-806414BDFE9F}.Debug|Win32.ActiveCfg = Debug|Win32 + {2F512A11-402E-496D-B20C-806414BDFE9F}.Debug|Win32.Build.0 = Debug|Win32 + {2F512A11-402E-496D-B20C-806414BDFE9F}.Release|Win32.ActiveCfg = Release|Win32 + {2F512A11-402E-496D-B20C-806414BDFE9F}.Release|Win32.Build.0 = Release|Win32 + {9E2494B2-5359-47C8-9122-549EDD467615}.Debug|Win32.ActiveCfg = Debug|Win32 + {9E2494B2-5359-47C8-9122-549EDD467615}.Debug|Win32.Build.0 = Debug|Win32 + {9E2494B2-5359-47C8-9122-549EDD467615}.Release|Win32.ActiveCfg = Release|Win32 + {9E2494B2-5359-47C8-9122-549EDD467615}.Release|Win32.Build.0 = Release|Win32 + {F1757D78-5C7C-468D-AB53-7571B3F48975}.Debug|Win32.ActiveCfg = Debug|Win32 + {F1757D78-5C7C-468D-AB53-7571B3F48975}.Debug|Win32.Build.0 = Debug|Win32 + {F1757D78-5C7C-468D-AB53-7571B3F48975}.Release|Win32.ActiveCfg = Release|Win32 + {F1757D78-5C7C-468D-AB53-7571B3F48975}.Release|Win32.Build.0 = Release|Win32 + {39B4C09E-E4E3-457F-B96C-B85D03C93B55}.Debug|Win32.ActiveCfg = Debug|Win32 + {39B4C09E-E4E3-457F-B96C-B85D03C93B55}.Debug|Win32.Build.0 = Debug|Win32 + {39B4C09E-E4E3-457F-B96C-B85D03C93B55}.Release|Win32.ActiveCfg = Release|Win32 + {39B4C09E-E4E3-457F-B96C-B85D03C93B55}.Release|Win32.Build.0 = Release|Win32 + {D6C8A2A9-C3E1-4F70-924D-BDEA60B4C667}.Debug|Win32.ActiveCfg = Debug|Win32 + {D6C8A2A9-C3E1-4F70-924D-BDEA60B4C667}.Debug|Win32.Build.0 = Debug|Win32 + {D6C8A2A9-C3E1-4F70-924D-BDEA60B4C667}.Release|Win32.ActiveCfg = Release|Win32 + {D6C8A2A9-C3E1-4F70-924D-BDEA60B4C667}.Release|Win32.Build.0 = Release|Win32 + {527BBF7C-631F-486B-8E4F-EA594299A71A}.Debug|Win32.ActiveCfg = Debug|Win32 + {527BBF7C-631F-486B-8E4F-EA594299A71A}.Debug|Win32.Build.0 = Debug|Win32 + {527BBF7C-631F-486B-8E4F-EA594299A71A}.Release|Win32.ActiveCfg = Release|Win32 + {527BBF7C-631F-486B-8E4F-EA594299A71A}.Release|Win32.Build.0 = Release|Win32 + {E17D0EDD-D945-4DC4-9C7C-FA21E2933FB0}.Debug|Win32.ActiveCfg = Debug|Win32 + {E17D0EDD-D945-4DC4-9C7C-FA21E2933FB0}.Debug|Win32.Build.0 = Debug|Win32 + {E17D0EDD-D945-4DC4-9C7C-FA21E2933FB0}.Release|Win32.ActiveCfg = Release|Win32 + {E17D0EDD-D945-4DC4-9C7C-FA21E2933FB0}.Release|Win32.Build.0 = Release|Win32 + {4BB4D8FF-F83B-406A-85AF-C7DF75ABCF59}.Debug|Win32.ActiveCfg = Debug|Win32 + {4BB4D8FF-F83B-406A-85AF-C7DF75ABCF59}.Debug|Win32.Build.0 = Debug|Win32 + {4BB4D8FF-F83B-406A-85AF-C7DF75ABCF59}.Release|Win32.ActiveCfg = Release|Win32 + {4BB4D8FF-F83B-406A-85AF-C7DF75ABCF59}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Legacy/Aria/examples/All_Examples-vc2010.sln b/Legacy/Aria/examples/All_Examples-vc2010.sln new file mode 100644 index 0000000..e7091db --- /dev/null +++ b/Legacy/Aria/examples/All_Examples-vc2010.sln @@ -0,0 +1,265 @@ +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual C++ Express 2010 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "actionExample", "actionExample-vc2010.vcxproj", "{2B257343-C6CC-4017-87B6-959D447DA735}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demo", "demo-vc2010.vcxproj", "{E1137892-32C1-4250-8784-8D48A6BEE2DD}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gyroExample", "gyroExample-vc2010.vcxproj", "{1A8C458C-0086-4788-AF12-F1DFA5EBAD53}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ipthru", "ipthru-vc2010.vcxproj", "{B0CD9146-122F-49FD-A12A-7A970514DFB1}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "joydriveThreaded", "joydriveThreaded-vc2010.vcxproj", "{B6C39214-2167-4B3D-8C01-2D98A5642F8E}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sickLogger", "sickLogger-vc2010.vcxproj", "{F2F3B4A0-9CDF-494F-B7B8-9442EBB6BA5F}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wander", "wander-vc2010.vcxproj", "{5239B513-8B95-4EDB-9FBA-63CB8D7CDEA3}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AriaDLL", "..\src\AriaDLL-vc2010.vcxproj", "{606257AE-E882-4C66-84C0-72331642D09F}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wanderAndLogData", "wanderAndLogData-vc2010.vcxproj", "{06616FA8-EBC6-4B23-B70C-E332A19160F1}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "actionGroupExample", "actionGroupExample-vc2010.vcxproj", "{7AD289AA-1C88-4EF2-B095-3234C613A08D}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "socketClientExample", "socketClientExample-vc2010.vcxproj", "{5571A55D-018E-485E-802E-D3F200D587DC}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "armExample", "armExample-vc2010.vcxproj", "{731EC481-379F-4041-BEBD-358C26ACE117}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "auxSerialExample", "auxSerialExample-vc2010.vcxproj", "{77DBE5F8-13CD-49FB-A4D9-35E360EC8992}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "directMotionExample", "directMotionExample-vc2010.vcxproj", "{BD31FF37-DDBD-4BBD-9ABC-5DE439735DBF}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dpptuExample", "dpptuExample-vc2010.vcxproj", "{EE1BFE24-2F7E-475C-A2F9-B11065EB6F5C}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "functorExample", "functorExample-vc2010.vcxproj", "{4AD6E4D3-7C44-4697-8794-BFBA43BFE13D}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gotoActionExample", "gotoActionExample-vc2010.vcxproj", "{FAD55BE4-E1C6-436D-BC7D-B0674FB8C067}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gripperExample", "gripperExample-vc2010.vcxproj", "{8DB12A26-FF33-46BE-800E-2CBB06774473}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "joydriveActionExample", "joydriveActionExample-vc2010.vcxproj", "{7E142B72-A049-4AB6-AB31-AEA652955B02}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "netServerExample", "netServerExample-vc2010.vcxproj", "{806CF3BE-8A4D-4C32-8574-58F3E85CA08C}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "robotSyncTaskExample", "robotSyncTaskExample-vc2010.vcxproj", "{69571F42-5098-41FB-B8A8-19ECCCDB9BB3}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "soundsQueueExample", "soundsQueueExample-vc2010.vcxproj", "{2F512A11-402E-496D-B20C-806414BDFE9F}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "teleopActionsExample", "teleopActionsExample-vc2010.vcxproj", "{9E2494B2-5359-47C8-9122-549EDD467615}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vcc4CameraExample", "vcc4CameraExample-vc2010.vcxproj", "{F1757D78-5C7C-468D-AB53-7571B3F48975}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gpsExample", "gpsExample-vc2010.vcxproj", "{39B4C09E-E4E3-457F-B96C-B85D03C93B55}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "simpleConnect", "simpleConnect-vc2010.vcxproj", "{D6C8A2A9-C3E1-4F70-924D-BDEA60B4C667}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AriaStatic", "..\src\AriaStatic-vc2010.vcxproj", "{527BBF7C-631F-486B-8E4F-EA594299A71A}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "actsColorFollowingExample", "actsColorFollowingExample-vc2010.vcxproj", "{E17D0EDD-D945-4DC4-9C7C-FA21E2933FB0}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "threadExample", "threadExample-vc2010.vcxproj", "{4BB4D8FF-F83B-406A-85AF-C7DF75ABCF59}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {2B257343-C6CC-4017-87B6-959D447DA735}.Debug|Win32.ActiveCfg = Debug|Win32 + {2B257343-C6CC-4017-87B6-959D447DA735}.Debug|Win32.Build.0 = Debug|Win32 + {2B257343-C6CC-4017-87B6-959D447DA735}.Release|Win32.ActiveCfg = Release|Win32 + {2B257343-C6CC-4017-87B6-959D447DA735}.Release|Win32.Build.0 = Release|Win32 + {E1137892-32C1-4250-8784-8D48A6BEE2DD}.Debug|Win32.ActiveCfg = Debug|Win32 + {E1137892-32C1-4250-8784-8D48A6BEE2DD}.Debug|Win32.Build.0 = Debug|Win32 + {E1137892-32C1-4250-8784-8D48A6BEE2DD}.Release|Win32.ActiveCfg = Release|Win32 + {E1137892-32C1-4250-8784-8D48A6BEE2DD}.Release|Win32.Build.0 = Release|Win32 + {1A8C458C-0086-4788-AF12-F1DFA5EBAD53}.Debug|Win32.ActiveCfg = Debug|Win32 + {1A8C458C-0086-4788-AF12-F1DFA5EBAD53}.Debug|Win32.Build.0 = Debug|Win32 + {1A8C458C-0086-4788-AF12-F1DFA5EBAD53}.Release|Win32.ActiveCfg = Release|Win32 + {1A8C458C-0086-4788-AF12-F1DFA5EBAD53}.Release|Win32.Build.0 = Release|Win32 + {B0CD9146-122F-49FD-A12A-7A970514DFB1}.Debug|Win32.ActiveCfg = Debug|Win32 + {B0CD9146-122F-49FD-A12A-7A970514DFB1}.Debug|Win32.Build.0 = Debug|Win32 + {B0CD9146-122F-49FD-A12A-7A970514DFB1}.Release|Win32.ActiveCfg = Release|Win32 + {B0CD9146-122F-49FD-A12A-7A970514DFB1}.Release|Win32.Build.0 = Release|Win32 + {B6C39214-2167-4B3D-8C01-2D98A5642F8E}.Debug|Win32.ActiveCfg = Debug|Win32 + {B6C39214-2167-4B3D-8C01-2D98A5642F8E}.Debug|Win32.Build.0 = Debug|Win32 + {B6C39214-2167-4B3D-8C01-2D98A5642F8E}.Release|Win32.ActiveCfg = Release|Win32 + {B6C39214-2167-4B3D-8C01-2D98A5642F8E}.Release|Win32.Build.0 = Release|Win32 + {F2F3B4A0-9CDF-494F-B7B8-9442EBB6BA5F}.Debug|Win32.ActiveCfg = Debug|Win32 + {F2F3B4A0-9CDF-494F-B7B8-9442EBB6BA5F}.Debug|Win32.Build.0 = Debug|Win32 + {F2F3B4A0-9CDF-494F-B7B8-9442EBB6BA5F}.Release|Win32.ActiveCfg = Release|Win32 + {F2F3B4A0-9CDF-494F-B7B8-9442EBB6BA5F}.Release|Win32.Build.0 = Release|Win32 + {5239B513-8B95-4EDB-9FBA-63CB8D7CDEA3}.Debug|Win32.ActiveCfg = Debug|Win32 + {5239B513-8B95-4EDB-9FBA-63CB8D7CDEA3}.Debug|Win32.Build.0 = Debug|Win32 + {5239B513-8B95-4EDB-9FBA-63CB8D7CDEA3}.Release|Win32.ActiveCfg = Release|Win32 + {5239B513-8B95-4EDB-9FBA-63CB8D7CDEA3}.Release|Win32.Build.0 = Release|Win32 + {606257AE-E882-4C66-84C0-72331642D09F}.Debug|Win32.ActiveCfg = Debug|Win32 + {606257AE-E882-4C66-84C0-72331642D09F}.Debug|Win32.Build.0 = Debug|Win32 + {606257AE-E882-4C66-84C0-72331642D09F}.Release|Win32.ActiveCfg = Release|Win32 + {606257AE-E882-4C66-84C0-72331642D09F}.Release|Win32.Build.0 = Release|Win32 + {06616FA8-EBC6-4B23-B70C-E332A19160F1}.Debug|Win32.ActiveCfg = Debug|Win32 + {06616FA8-EBC6-4B23-B70C-E332A19160F1}.Debug|Win32.Build.0 = Debug|Win32 + {06616FA8-EBC6-4B23-B70C-E332A19160F1}.Release|Win32.ActiveCfg = Release|Win32 + {06616FA8-EBC6-4B23-B70C-E332A19160F1}.Release|Win32.Build.0 = Release|Win32 + {7AD289AA-1C88-4EF2-B095-3234C613A08D}.Debug|Win32.ActiveCfg = Debug|Win32 + {7AD289AA-1C88-4EF2-B095-3234C613A08D}.Debug|Win32.Build.0 = Debug|Win32 + {7AD289AA-1C88-4EF2-B095-3234C613A08D}.Release|Win32.ActiveCfg = Release|Win32 + {7AD289AA-1C88-4EF2-B095-3234C613A08D}.Release|Win32.Build.0 = Release|Win32 + {5571A55D-018E-485E-802E-D3F200D587DC}.Debug|Win32.ActiveCfg = Debug|Win32 + {5571A55D-018E-485E-802E-D3F200D587DC}.Debug|Win32.Build.0 = Debug|Win32 + {5571A55D-018E-485E-802E-D3F200D587DC}.Release|Win32.ActiveCfg = Release|Win32 + {5571A55D-018E-485E-802E-D3F200D587DC}.Release|Win32.Build.0 = Release|Win32 + {731EC481-379F-4041-BEBD-358C26ACE117}.Debug|Win32.ActiveCfg = Debug|Win32 + {731EC481-379F-4041-BEBD-358C26ACE117}.Debug|Win32.Build.0 = Debug|Win32 + {731EC481-379F-4041-BEBD-358C26ACE117}.Release|Win32.ActiveCfg = Release|Win32 + {731EC481-379F-4041-BEBD-358C26ACE117}.Release|Win32.Build.0 = Release|Win32 + {77DBE5F8-13CD-49FB-A4D9-35E360EC8992}.Debug|Win32.ActiveCfg = Debug|Win32 + {77DBE5F8-13CD-49FB-A4D9-35E360EC8992}.Debug|Win32.Build.0 = Debug|Win32 + {77DBE5F8-13CD-49FB-A4D9-35E360EC8992}.Release|Win32.ActiveCfg = Release|Win32 + {77DBE5F8-13CD-49FB-A4D9-35E360EC8992}.Release|Win32.Build.0 = Release|Win32 + {BD31FF37-DDBD-4BBD-9ABC-5DE439735DBF}.Debug|Win32.ActiveCfg = Debug|Win32 + {BD31FF37-DDBD-4BBD-9ABC-5DE439735DBF}.Debug|Win32.Build.0 = Debug|Win32 + {BD31FF37-DDBD-4BBD-9ABC-5DE439735DBF}.Release|Win32.ActiveCfg = Release|Win32 + {BD31FF37-DDBD-4BBD-9ABC-5DE439735DBF}.Release|Win32.Build.0 = Release|Win32 + {EE1BFE24-2F7E-475C-A2F9-B11065EB6F5C}.Debug|Win32.ActiveCfg = Debug|Win32 + {EE1BFE24-2F7E-475C-A2F9-B11065EB6F5C}.Debug|Win32.Build.0 = Debug|Win32 + {EE1BFE24-2F7E-475C-A2F9-B11065EB6F5C}.Release|Win32.ActiveCfg = Release|Win32 + {EE1BFE24-2F7E-475C-A2F9-B11065EB6F5C}.Release|Win32.Build.0 = Release|Win32 + {4AD6E4D3-7C44-4697-8794-BFBA43BFE13D}.Debug|Win32.ActiveCfg = Debug|Win32 + {4AD6E4D3-7C44-4697-8794-BFBA43BFE13D}.Debug|Win32.Build.0 = Debug|Win32 + {4AD6E4D3-7C44-4697-8794-BFBA43BFE13D}.Release|Win32.ActiveCfg = Release|Win32 + {4AD6E4D3-7C44-4697-8794-BFBA43BFE13D}.Release|Win32.Build.0 = Release|Win32 + {FAD55BE4-E1C6-436D-BC7D-B0674FB8C067}.Debug|Win32.ActiveCfg = Debug|Win32 + {FAD55BE4-E1C6-436D-BC7D-B0674FB8C067}.Debug|Win32.Build.0 = Debug|Win32 + {FAD55BE4-E1C6-436D-BC7D-B0674FB8C067}.Release|Win32.ActiveCfg = Release|Win32 + {FAD55BE4-E1C6-436D-BC7D-B0674FB8C067}.Release|Win32.Build.0 = Release|Win32 + {8DB12A26-FF33-46BE-800E-2CBB06774473}.Debug|Win32.ActiveCfg = Debug|Win32 + {8DB12A26-FF33-46BE-800E-2CBB06774473}.Debug|Win32.Build.0 = Debug|Win32 + {8DB12A26-FF33-46BE-800E-2CBB06774473}.Release|Win32.ActiveCfg = Release|Win32 + {8DB12A26-FF33-46BE-800E-2CBB06774473}.Release|Win32.Build.0 = Release|Win32 + {7E142B72-A049-4AB6-AB31-AEA652955B02}.Debug|Win32.ActiveCfg = Debug|Win32 + {7E142B72-A049-4AB6-AB31-AEA652955B02}.Debug|Win32.Build.0 = Debug|Win32 + {7E142B72-A049-4AB6-AB31-AEA652955B02}.Release|Win32.ActiveCfg = Release|Win32 + {7E142B72-A049-4AB6-AB31-AEA652955B02}.Release|Win32.Build.0 = Release|Win32 + {806CF3BE-8A4D-4C32-8574-58F3E85CA08C}.Debug|Win32.ActiveCfg = Debug|Win32 + {806CF3BE-8A4D-4C32-8574-58F3E85CA08C}.Debug|Win32.Build.0 = Debug|Win32 + {806CF3BE-8A4D-4C32-8574-58F3E85CA08C}.Release|Win32.ActiveCfg = Release|Win32 + {806CF3BE-8A4D-4C32-8574-58F3E85CA08C}.Release|Win32.Build.0 = Release|Win32 + {69571F42-5098-41FB-B8A8-19ECCCDB9BB3}.Debug|Win32.ActiveCfg = Debug|Win32 + {69571F42-5098-41FB-B8A8-19ECCCDB9BB3}.Debug|Win32.Build.0 = Debug|Win32 + {69571F42-5098-41FB-B8A8-19ECCCDB9BB3}.Release|Win32.ActiveCfg = Release|Win32 + {69571F42-5098-41FB-B8A8-19ECCCDB9BB3}.Release|Win32.Build.0 = Release|Win32 + {2F512A11-402E-496D-B20C-806414BDFE9F}.Debug|Win32.ActiveCfg = Debug|Win32 + {2F512A11-402E-496D-B20C-806414BDFE9F}.Debug|Win32.Build.0 = Debug|Win32 + {2F512A11-402E-496D-B20C-806414BDFE9F}.Release|Win32.ActiveCfg = Release|Win32 + {2F512A11-402E-496D-B20C-806414BDFE9F}.Release|Win32.Build.0 = Release|Win32 + {9E2494B2-5359-47C8-9122-549EDD467615}.Debug|Win32.ActiveCfg = Debug|Win32 + {9E2494B2-5359-47C8-9122-549EDD467615}.Debug|Win32.Build.0 = Debug|Win32 + {9E2494B2-5359-47C8-9122-549EDD467615}.Release|Win32.ActiveCfg = Release|Win32 + {9E2494B2-5359-47C8-9122-549EDD467615}.Release|Win32.Build.0 = Release|Win32 + {F1757D78-5C7C-468D-AB53-7571B3F48975}.Debug|Win32.ActiveCfg = Debug|Win32 + {F1757D78-5C7C-468D-AB53-7571B3F48975}.Debug|Win32.Build.0 = Debug|Win32 + {F1757D78-5C7C-468D-AB53-7571B3F48975}.Release|Win32.ActiveCfg = Release|Win32 + {F1757D78-5C7C-468D-AB53-7571B3F48975}.Release|Win32.Build.0 = Release|Win32 + {39B4C09E-E4E3-457F-B96C-B85D03C93B55}.Debug|Win32.ActiveCfg = Debug|Win32 + {39B4C09E-E4E3-457F-B96C-B85D03C93B55}.Debug|Win32.Build.0 = Debug|Win32 + {39B4C09E-E4E3-457F-B96C-B85D03C93B55}.Release|Win32.ActiveCfg = Release|Win32 + {39B4C09E-E4E3-457F-B96C-B85D03C93B55}.Release|Win32.Build.0 = Release|Win32 + {D6C8A2A9-C3E1-4F70-924D-BDEA60B4C667}.Debug|Win32.ActiveCfg = Debug|Win32 + {D6C8A2A9-C3E1-4F70-924D-BDEA60B4C667}.Debug|Win32.Build.0 = Debug|Win32 + {D6C8A2A9-C3E1-4F70-924D-BDEA60B4C667}.Release|Win32.ActiveCfg = Release|Win32 + {D6C8A2A9-C3E1-4F70-924D-BDEA60B4C667}.Release|Win32.Build.0 = Release|Win32 + {527BBF7C-631F-486B-8E4F-EA594299A71A}.Debug|Win32.ActiveCfg = Debug|Win32 + {527BBF7C-631F-486B-8E4F-EA594299A71A}.Debug|Win32.Build.0 = Debug|Win32 + {527BBF7C-631F-486B-8E4F-EA594299A71A}.Release|Win32.ActiveCfg = Release|Win32 + {527BBF7C-631F-486B-8E4F-EA594299A71A}.Release|Win32.Build.0 = Release|Win32 + {E17D0EDD-D945-4DC4-9C7C-FA21E2933FB0}.Debug|Win32.ActiveCfg = Debug|Win32 + {E17D0EDD-D945-4DC4-9C7C-FA21E2933FB0}.Debug|Win32.Build.0 = Debug|Win32 + {E17D0EDD-D945-4DC4-9C7C-FA21E2933FB0}.Release|Win32.ActiveCfg = Release|Win32 + {E17D0EDD-D945-4DC4-9C7C-FA21E2933FB0}.Release|Win32.Build.0 = Release|Win32 + {4BB4D8FF-F83B-406A-85AF-C7DF75ABCF59}.Debug|Win32.ActiveCfg = Debug|Win32 + {4BB4D8FF-F83B-406A-85AF-C7DF75ABCF59}.Debug|Win32.Build.0 = Debug|Win32 + {4BB4D8FF-F83B-406A-85AF-C7DF75ABCF59}.Release|Win32.ActiveCfg = Release|Win32 + {4BB4D8FF-F83B-406A-85AF-C7DF75ABCF59}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Legacy/Aria/examples/Makefile b/Legacy/Aria/examples/Makefile new file mode 100644 index 0000000..496ce27 --- /dev/null +++ b/Legacy/Aria/examples/Makefile @@ -0,0 +1,30 @@ +# A simple $(MAKE)file to cause make to go look in the top directory. A simple +# convenience. + +all: lib + $(MAKE) -C .. examples + +lib: + $(MAKE) -C .. lib/libAria.so + +%.so: ../lib/libAria.so %.cpp + $(MAKE) -C .. examples/$@ + +%: ../lib/libAria.so %.cpp + $(MAKE) -C .. examples/$@ + +%Static: ../lib/libAria.a %.cpp + $(MAKE) -C .. examples/$@ + +clean: + $(MAKE) -C .. cleanExamples + +../lib/libAria.so: FORCE + $(MAKE) -C .. dirs lib/libAria.so + +../lib/libAria.a: FORCE + $(MAKE) -C .. dirs lib/libAria.a + +FORCE: + +.PHONY: all FORCE clean lib diff --git a/Legacy/Aria/examples/README.txt b/Legacy/Aria/examples/README.txt new file mode 100644 index 0000000..26fe309 --- /dev/null +++ b/Legacy/Aria/examples/README.txt @@ -0,0 +1,104 @@ +This directory has various example pieces of code and Microsoft VC++ +project files. + +The two most useful example programs are teleopActionsExample and +wander. TeleopActionsExample does guarded teleoperation, so you +can drive the robot around without running into walls. +Wander just has the robot wander, ie drive forward until there is +an obstacle, avoid it, then keep driving. lasers shows how to +connect to laser rangefinder(s) and use the data from them. + +The smallest, simplest example program is simpleConnect. It just +connects to the robot, prints some information, then disconnects +and exits. + + +Partial list of examples: +------------------------------------------------------------------------------- + + +demo - Uses "Modes" defined in ARIA to provide keyboard control of many +different robot features. Use this utility to experiment and test the robot's +hardware. + +simpleConnect - The smallest example program. It just connects to the robot. + +simpleUserTask - Demonstrates how to make a simple user task + +robotSyncTaskExample - simple example of ArRobot synchronized task callbacks + +lasers - Demonstrates how to connect to one or more laser rangefinder devices +as defined in robot and program parameters, and obtain data from them. + +directMotionDemo - Drives the robot around using the basic direct +motion commands (no ArActions or obstacle avoidance). it also runs the +robot in its own thread, and has examples of connection handler callbacks. + +actionExample - Defines a couple of custom ArAction classes, and uses them. + +actionGroup - Program that uses action groups to switch back and forth +between wander and teleop mode + +cameraPTZExample - Connect to PTZ camera or PTU (depending on robot parameter +file configuration or command line arguments). + +dpptuExample - A program to control the Directed Perception PTU with the keyboard. + +functor - An example program on the basic use of functors. + +gotoActionExample - An example of how to use ArActionGoto to go to many different +points and not just one + +gpsExample - An example showing how to get data from a GPS + +gripperDemo - Program that moves the robot and controls the gripper with the +joystick, note this doesn't do obstacle avoidance + +actsColorFolowingExample - A simple program that uses ACTS and a VC-C4 camera to move the +robot toward a color blob. + +joydriveActionExample - Uses an action that reads the robot to drive the joystick, +does not do obstacle avoidance + +joydriveThreaded - Program to drive the robot with a joystick. This one +uses its own ArASyncTask to drive the joystick handler. This is a good +example to look at to see how threading works. This does not do obstacle +avoidance, this also has a connection handler + +joydriveUserTask - Program to drive the robot with a joystick. This one +uses a user task to drive the joystick handler, does not do obstacle avoidance + +getAuxExample - An example program that uses the getAux command and +talks about how to use the getAux to do actual work + +moduleExample - Tests the loadable modules in a simple way + +socketClientExample - This program works with socketServerExample to +demonstrate ArSockets + +socketServerExample - A program to demonstrate ArSocket, works with +socketClientExample + +sickLineFinderSimple - An example of using the laser sensor line finding +class and lets you save the lines + +threadExample - Demonstrates ARIA's threading tools + +soundsQueueExamples - Demonstrates use of the ArSoundsQueue sound/speech queue + +teleopActionsExample - This uses ARIA's powerful Actions system to drive +the robot around using input from the keyboard or a joystick, but does +obstacle avoidance so the robot won't run into things (if it can sense +them with sonar or laser). + +wander - Makes the robot wander around, turning to avoid any sensed obstacles. +Uses sonar and laser (if available) to detect obstacles. + +wanderAndLogData - similar to wander, but prints out all kinds of runtime +information about the robot + +(others) - there are several other example programs in this directory not +listed here. Some are for older or less common hardware, or show some +advanced features of ARIA that only some users will need. Browse them +and read their descriptions (in comments at the top of source files) +for more information. diff --git a/Legacy/Aria/examples/actionExample-vc2003.vcproj b/Legacy/Aria/examples/actionExample-vc2003.vcproj new file mode 100644 index 0000000..363267f --- /dev/null +++ b/Legacy/Aria/examples/actionExample-vc2003.vcproj @@ -0,0 +1,179 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/examples/actionExample-vc2008.vcproj b/Legacy/Aria/examples/actionExample-vc2008.vcproj new file mode 100644 index 0000000..2ca5ab2 --- /dev/null +++ b/Legacy/Aria/examples/actionExample-vc2008.vcproj @@ -0,0 +1,236 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/examples/actionExample-vc2010.vcxproj b/Legacy/Aria/examples/actionExample-vc2010.vcxproj new file mode 100644 index 0000000..94049f4 --- /dev/null +++ b/Legacy/Aria/examples/actionExample-vc2010.vcxproj @@ -0,0 +1,155 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + actionExample + {2B257343-C6CC-4017-87B6-959D447DA735} + + + + Application + false + MultiByte + + + Application + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + .\../bin\ + ../obj/$(ProjectName)-$(Configuration)-VC10/ + false + .\../bin\ + ../obj/$(ProjectName)-$(Configuration)-VC10/ + false + $(ProjectName).DebugVC10 + + + + $(IntDir)$(ProjectName)-$(Configuration)-BuildLog.htm + + + .\../bin/actionExample.tlb + + + + + Disabled + ..\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + true + true + + + true + Level3 + true + + + Default + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + /verbose:lib %(AdditionalOptions) + AriaDebugVC10.lib + 1.0 + true + ..\lib;%(AdditionalLibraryDirectories) + OLDNAMES.lib;%(IgnoreSpecificDefaultLibraries) + false + Console + false + + + MachineX86 + + + + + $(IntDir)$(ProjectName)-$(Configuration)-BuildLog.htm + + + .\../bin/actionExample.tlb + + + + + MaxSpeed + OnlyExplicitInline + ..\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + true + true + + + Level3 + true + + + Default + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + AriaVC10.lib + 1.0 + true + ..\lib;%(AdditionalLibraryDirectories) + false + Console + false + + + MachineX86 + + + + + Disabled + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + EnableFastChecks + true + MaxSpeed + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + + + + \ No newline at end of file diff --git a/Legacy/Aria/examples/actionExample.cpp b/Legacy/Aria/examples/actionExample.cpp new file mode 100644 index 0000000..15da600 --- /dev/null +++ b/Legacy/Aria/examples/actionExample.cpp @@ -0,0 +1,337 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#include "Aria.h" + +/** +@example actionExample.cpp An example program demonstrating how to make and use new actions. + +This example program creates two new actions, Go and Turn. Go will drive the robot forward safely, +while Turn will avoid obstacles detected by the sonar by turning. +This program also adds a predefined +action from Aria which tries to recover from stalls (hit something and +can't move forward) by backing and turning. + +Each of these actions have the normal constructor and destructor, note that +the constructors use constructor chaining to create their ArAction part +correctly. Each action then also implements the essential virtual method, +fire(). This fire function is called by the action resolver, and +returns values that, in combination with other actions' desired behavior, +determine the driving commands sent to the robot. + +Also note that each of these actions override the setRobot function; these +implementations obtain the sonar device from the robot in addition to doing the +needed caching of the robot pointer. This is what you should do if you +care about the presence or absence of a particular sensor. If you don't +care about any particular sensor you could just use one of the checkRangeDevice... +methods in ArRobot (there are four of them). +Also note that these are very naive actions, they are simply an example +of how to use actions. + +See the @ref actions Actions section of the Aria reference manual overview for more details about actions. + +Note that actions must take a small amount of time to execute, to avoid +delaying the robot synchronization cycle. + +*/ + + +/* + * Action that drives the robot forward, but stops if obstacles are + * detected by sonar. + */ +class ActionGo : public ArAction +{ +public: + // constructor, sets myMaxSpeed and myStopDistance + ActionGo(double maxSpeed, double stopDistance); + // destructor. does not need to do anything + virtual ~ActionGo(void) {}; + // called by the action resolver to obtain this action's requested behavior + virtual ArActionDesired *fire(ArActionDesired currentDesired); + // store the robot pointer, and it's ArSonarDevice object, or deactivate this action if there is no sonar. + virtual void setRobot(ArRobot *robot); +protected: + // the sonar device object obtained from the robot by setRobot() + ArRangeDevice *mySonar; + + + /* Our current desired action: fire() modifies this object and returns + to the action resolver a pointer to this object. + This object is kept as a class member so that it persists after fire() + returns (otherwise fire() would have to create a new object each invocation, + but would never be able to delete that object). + */ + ArActionDesired myDesired; + + double myMaxSpeed; + double myStopDistance; +}; + + +/* Action that turns the robot away from obstacles detected by the + * sonar. */ +class ActionTurn : public ArAction +{ +public: + // constructor, sets the turnThreshold, and turnAmount + ActionTurn(double turnThreshold, double turnAmount); + // destructor, its just empty, we don't need to do anything + virtual ~ActionTurn(void) {}; + // fire, this is what the resolver calls to figure out what this action wants + virtual ArActionDesired *fire(ArActionDesired currentDesired); + // sets the robot pointer, also gets the sonar device, or deactivates this action if there is no sonar. + virtual void setRobot(ArRobot *robot); +protected: + // this is to hold the sonar device form the robot + ArRangeDevice *mySonar; + // what the action wants to do; used by the action resover after fire() + ArActionDesired myDesired; + // distance at which to start turning + double myTurnThreshold; + // amount to turn when turning is needed + double myTurnAmount; + // remember which turn direction we requested, to help keep turns smooth + int myTurning; // -1 == left, 1 == right, 0 == none +}; + +/* + Note the use of constructor chaining with + ArAction(actionName). Also note how it uses setNextArgument, which makes it so that + other parts of the program could find out what parameters this action has, and possibly modify them. +*/ +ActionGo::ActionGo(double maxSpeed, double stopDistance) : + ArAction("Go") +{ + mySonar = NULL; + myMaxSpeed = maxSpeed; + myStopDistance = stopDistance; + setNextArgument(ArArg("maximum speed", &myMaxSpeed, "Maximum speed to go.")); + setNextArgument(ArArg("stop distance", &myStopDistance, "Distance at which to stop.")); +} + +/* + Override ArAction::setRobot() to get the sonar device from the robot, or deactivate this action if it is missing. + You must also call ArAction::setRobot() to properly store + the ArRobot pointer in the ArAction base class. +*/ +void ActionGo::setRobot(ArRobot *robot) +{ + ArAction::setRobot(robot); + mySonar = robot->findRangeDevice("sonar"); + if (robot == NULL) + { + ArLog::log(ArLog::Terse, "actionExample: ActionGo: Warning: I found no sonar, deactivating."); + deactivate(); + } +} + +/* + This fire is the whole point of the action. + currentDesired is the combined desired action from other actions + previously processed by the action resolver. In this case, we're + not interested in that, we will set our desired + forward velocity in the myDesired member, and return it. + + Note that myDesired must be a class member, since this method + will return a pointer to myDesired to the caller. If we had + declared the desired action as a local variable in this method, + the pointer we returned would be invalid after this method + returned. +*/ +ArActionDesired *ActionGo::fire(ArActionDesired currentDesired) +{ + double range; + double speed; + + // reset the actionDesired (must be done), to clear + // its previous values. + myDesired.reset(); + + // if the sonar is null we can't do anything, so deactivate + if (mySonar == NULL) + { + deactivate(); + return NULL; + } + // get the range of the sonar + range = mySonar->currentReadingPolar(-70, 70) - myRobot->getRobotRadius(); + // if the range is greater than the stop distance, find some speed to go + if (range > myStopDistance) + { + // just an arbitrary speed based on the range + speed = range * .3; + // if that speed is greater than our max, cap it + if (speed > myMaxSpeed) + speed = myMaxSpeed; + // now set the velocity + myDesired.setVel(speed); + } + // the range was less than the stop distance, so request stop + else + { + myDesired.setVel(0); + } + // return a pointer to the actionDesired to the resolver to make our request + return &myDesired; +} + + +/* + This is the ActionTurn constructor, note the use of constructor chaining + with the ArAction. also note how it uses setNextArgument, which makes + it so that other things can see what parameters this action has, and + set them. It also initializes the classes variables. +*/ +ActionTurn::ActionTurn(double turnThreshold, double turnAmount) : + ArAction("Turn") +{ + myTurnThreshold = turnThreshold; + myTurnAmount = turnAmount; + setNextArgument(ArArg("turn threshold (mm)", &myTurnThreshold, "The number of mm away from obstacle to begin turnning.")); + setNextArgument(ArArg("turn amount (deg)", &myTurnAmount, "The number of degress to turn if turning.")); + myTurning = 0; +} + +/* + Sets the myRobot pointer (all setRobot overloaded functions must do this), + finds the sonar device from the robot, and if the sonar isn't there, + then it deactivates itself. +*/ +void ActionTurn::setRobot(ArRobot *robot) +{ + ArAction::setRobot(robot); + mySonar = robot->findRangeDevice("sonar"); + if (mySonar == NULL) + { + ArLog::log(ArLog::Terse, "actionExample: ActionTurn: Warning: I found no sonar, deactivating."); + deactivate(); + } +} + +/* + This is the guts of the Turn action. +*/ +ArActionDesired *ActionTurn::fire(ArActionDesired currentDesired) +{ + double leftRange, rightRange; + // reset the actionDesired (must be done) + myDesired.reset(); + // if the sonar is null we can't do anything, so deactivate + if (mySonar == NULL) + { + deactivate(); + return NULL; + } + // Get the left readings and right readings off of the sonar + leftRange = (mySonar->currentReadingPolar(0, 100) - + myRobot->getRobotRadius()); + rightRange = (mySonar->currentReadingPolar(-100, 0) - + myRobot->getRobotRadius()); + // if neither left nor right range is within the turn threshold, + // reset the turning variable and don't turn + if (leftRange > myTurnThreshold && rightRange > myTurnThreshold) + { + myTurning = 0; + myDesired.setDeltaHeading(0); + } + // if we're already turning some direction, keep turning that direction + else if (myTurning) + { + myDesired.setDeltaHeading(myTurnAmount * myTurning); + } + // if we're not turning already, but need to, and left is closer, turn right + // and set the turning variable so we turn the same direction for as long as + // we need to + else if (leftRange < rightRange) + { + myTurning = -1; + myDesired.setDeltaHeading(myTurnAmount * myTurning); + } + // if we're not turning already, but need to, and right is closer, turn left + // and set the turning variable so we turn the same direction for as long as + // we need to + else + { + myTurning = 1; + myDesired.setDeltaHeading(myTurnAmount * myTurning); + } + // return a pointer to the actionDesired, so resolver knows what to do + return &myDesired; +} + + + +int main(int argc, char** argv) +{ + Aria::init(); + + ArSimpleConnector conn(&argc, argv); + ArRobot robot; + ArSonarDevice sonar; + + // Create instances of the actions defined above, plus ArActionStallRecover, + // a predefined action from Aria. + ActionGo go(500, 350); + ActionTurn turn(400, 10); + ArActionStallRecover recover; + + + // Parse all command-line arguments + if(!Aria::parseArgs()) + { + Aria::logOptions(); + return 1; + } + + // Connect to the robot + if(!conn.connectRobot(&robot)) + { + ArLog::log(ArLog::Terse, "actionExample: Could not connect to robot! Exiting."); + return 2; + } + + // Add the range device to the robot. You should add all the range + // devices and such before you add actions + robot.addRangeDevice(&sonar); + + + // Add our actions in order. The second argument is the priority, + // with higher priority actions going first, and possibly pre-empting lower + // priority actions. + robot.addAction(&recover, 100); + robot.addAction(&go, 50); + robot.addAction(&turn, 49); + + // Enable the motors, disable amigobot sounds + robot.enableMotors(); + + // Run the robot processing cycle. + // 'true' means to return if it loses connection, + // after which we exit the program. + robot.run(true); + + Aria::exit(0); +} diff --git a/Legacy/Aria/examples/actionExample.vcproj b/Legacy/Aria/examples/actionExample.vcproj new file mode 100644 index 0000000..755a3b8 --- /dev/null +++ b/Legacy/Aria/examples/actionExample.vcproj @@ -0,0 +1,167 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/examples/actionGroupExample-vc2003.vcproj b/Legacy/Aria/examples/actionGroupExample-vc2003.vcproj new file mode 100644 index 0000000..1adbdfb --- /dev/null +++ b/Legacy/Aria/examples/actionGroupExample-vc2003.vcproj @@ -0,0 +1,151 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/examples/actionGroupExample-vc2008.vcproj b/Legacy/Aria/examples/actionGroupExample-vc2008.vcproj new file mode 100644 index 0000000..2e0c47d --- /dev/null +++ b/Legacy/Aria/examples/actionGroupExample-vc2008.vcproj @@ -0,0 +1,211 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/examples/actionGroupExample-vc2010.vcxproj b/Legacy/Aria/examples/actionGroupExample-vc2010.vcxproj new file mode 100644 index 0000000..2289d6c --- /dev/null +++ b/Legacy/Aria/examples/actionGroupExample-vc2010.vcxproj @@ -0,0 +1,143 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + actionGroupExample + {7AD289AA-1C88-4EF2-B095-3234C613A08D} + + + + Application + false + MultiByte + + + Application + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + .\../bin\ + ../obj/$(ProjectName)-$(Configuration)-VC10/ + false + .\../bin\ + ../obj/$(ProjectName)-$(Configuration)-VC10/ + false + $(ProjectName).DebugVC10 + + + + $(IntDir)$(ProjectName)-$(Configuration)-BuildLog.htm + + + .\../bin/actionGroup.tlb + + + + + Disabled + ..\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + true + true + + + Level3 + true + + + Default + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + AriaDebugVC10.lib + true + ..\lib;%(AdditionalLibraryDirectories) + false + .\../bin/actionGroup.pdb + Console + false + + + MachineX86 + + + + + $(IntDir)$(ProjectName)-$(Configuration)-BuildLog.htm + + + .\../bin/actionGroup.tlb + + + + + MaxSpeed + OnlyExplicitInline + ..\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + true + true + + + Level3 + true + + + Default + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + AriaVC10.lib + true + ..\lib;%(AdditionalLibraryDirectories) + false + .\../bin/actionGroup.pdb + Console + false + + + MachineX86 + + + + + + + + + \ No newline at end of file diff --git a/Legacy/Aria/examples/actionGroupExample.cpp b/Legacy/Aria/examples/actionGroupExample.cpp new file mode 100644 index 0000000..a975e62 --- /dev/null +++ b/Legacy/Aria/examples/actionGroupExample.cpp @@ -0,0 +1,173 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#include "Aria.h" + +/** @example actionGroupExample.cpp Example of using ArActionGroup objects to switch + * between two different kinds of behavior. + * + * This program creates two action groups, a teleoperation + * group and a wander group. Each group contains actions + * that together effect the desired behavior: in teleoperation + * mode, input actions allow the robot to be driven by keyboard + * or joystick, and higher-priority limiter actions help avoid obstacles. + * In wander mode, a constant-velocity action drives the robot + * forward, but higher-priority avoidance actions make the robot + * turn away from obstacles, or back up if an obstacle is hit or + * the motors stall. Keyboard commands (the T and W keys) are + * used to switch between the two modes, by activating the + * action group for the chosen mode. + * + * @see ArActionGroup + * @see @ref actions overview + * @see actionExample.cpp + */ + +ArActionGroup *teleop; +ArActionGroup *wander; + +// Activate the teleop action group. activateExlcusive() causes +// all other active action groups to be deactivated. +void teleopMode(void) +{ + teleop->activateExclusive(); + printf("\n== Teleoperation Mode ==\n"); + printf(" Use the arrow keys to drive, and the spacebar to stop.\n For joystick control hold the trigger button.\n Press 'w' to switch to wander mode.\n Press escape to exit.\n"); +} + +// Activate the wander action group. activateExlcusive() causes +// all other active action groups to be deactivated. +void wanderMode(void) +{ + wander->activateExclusive(); + printf("\n== Wander Mode ==\n"); + printf(" The robot will now just wander around avoiding things.\n Press 't' to switch to teleop mode.\n Press escape to exit.\n"); +} + + +int main(int argc, char** argv) +{ + Aria::init(); + ArArgumentParser argParser(&argc, argv); + ArSimpleConnector con(&argParser); + ArRobot robot; + ArSonarDevice sonar; + + argParser.loadDefaultArguments(); + if(!Aria::parseArgs() || !argParser.checkHelpAndWarnUnparsed()) + { + Aria::logOptions(); + return 1; + } + + /* - the action group for teleoperation actions: */ + teleop = new ArActionGroup(&robot); + + // don't hit any tables (if the robot has IR table sensors) + teleop->addAction(new ArActionLimiterTableSensor, 100); + + // limiter for close obstacles + teleop->addAction(new ArActionLimiterForwards("speed limiter near", + 300, 600, 250), 95); + + // limiter for far away obstacles + teleop->addAction(new ArActionLimiterForwards("speed limiter far", + 300, 1100, 400), 90); + + // limiter so we don't bump things backwards + teleop->addAction(new ArActionLimiterBackwards, 85); + + // the joydrive action (drive from joystick) + ArActionJoydrive joydriveAct("joydrive", 400, 15); + teleop->addAction(&joydriveAct, 50); + + // the keydrive action (drive from keyboard) + teleop->addAction(new ArActionKeydrive, 45); + + + + /* - the action group for wander actions: */ + wander = new ArActionGroup(&robot); + + // if we're stalled we want to back up and recover + wander->addAction(new ArActionStallRecover, 100); + + // react to bumpers + wander->addAction(new ArActionBumpers, 75); + + // turn to avoid things closer to us + wander->addAction(new ArActionAvoidFront("Avoid Front Near", 225, 0), 50); + + // turn avoid things further away + wander->addAction(new ArActionAvoidFront, 45); + + // keep moving + wander->addAction(new ArActionConstantVelocity("Constant Velocity", 400), 25); + + + + /* - use key commands to switch modes, and use keyboard + * and joystick as inputs for teleoperation actions. */ + + // create key handler if Aria does not already have one + ArKeyHandler *keyHandler = Aria::getKeyHandler(); + if (keyHandler == NULL) + { + keyHandler = new ArKeyHandler; + Aria::setKeyHandler(keyHandler); + robot.attachKeyHandler(keyHandler); + } + + // set the callbacks + ArGlobalFunctor teleopCB(&teleopMode); + ArGlobalFunctor wanderCB(&wanderMode); + keyHandler->addKeyHandler('w', &wanderCB); + keyHandler->addKeyHandler('W', &wanderCB); + keyHandler->addKeyHandler('t', &teleopCB); + keyHandler->addKeyHandler('T', &teleopCB); + + // if we don't have a joystick, let 'em know + if (!joydriveAct.joystickInited()) + printf("Note: Do not have a joystick, only the arrow keys on the keyboard will work.\n"); + + // set the joystick so it won't do anything if the button isn't pressed + joydriveAct.setStopIfNoButtonPressed(false); + + + /* - connect to the robot, then enter teleoperation mode. */ + + robot.addRangeDevice(&sonar); + if(!con.connectRobot(&robot)) + { + ArLog::log(ArLog::Terse, "actionGroupExample: Could not connect to the robot."); + Aria::exit(1); + } + + robot.enableMotors(); + teleopMode(); + robot.run(true); + + Aria::exit(0); +} diff --git a/Legacy/Aria/examples/actionGroupExample.vcproj b/Legacy/Aria/examples/actionGroupExample.vcproj new file mode 100644 index 0000000..979ad01 --- /dev/null +++ b/Legacy/Aria/examples/actionGroupExample.vcproj @@ -0,0 +1,147 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/examples/actsColorFollowingExample-vc2003.vcproj b/Legacy/Aria/examples/actsColorFollowingExample-vc2003.vcproj new file mode 100644 index 0000000..d889c17 --- /dev/null +++ b/Legacy/Aria/examples/actsColorFollowingExample-vc2003.vcproj @@ -0,0 +1,258 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/examples/actsColorFollowingExample-vc2008.vcproj b/Legacy/Aria/examples/actsColorFollowingExample-vc2008.vcproj new file mode 100644 index 0000000..8ac73d2 --- /dev/null +++ b/Legacy/Aria/examples/actsColorFollowingExample-vc2008.vcproj @@ -0,0 +1,346 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/examples/actsColorFollowingExample-vc2010.vcxproj b/Legacy/Aria/examples/actsColorFollowingExample-vc2010.vcxproj new file mode 100644 index 0000000..888edb7 --- /dev/null +++ b/Legacy/Aria/examples/actsColorFollowingExample-vc2010.vcxproj @@ -0,0 +1,224 @@ + + + + + CLR Debug + Win32 + + + Debug + Win32 + + + Release + Win32 + + + + actsColorFollowingExample + {E17D0EDD-D945-4DC4-9C7C-FA21E2933FB0} + + + + Application + false + MultiByte + false + + + Application + false + MultiByte + false + + + Application + false + MultiByte + false + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + ../bin + ../obj/$(ProjectName)-$(Configuration)-VC10/ + false + ../bin + ../obj/$(ProjectName)-$(Configuration)-VC10/ + false + ../bin + ../obj/$(ProjectName)-$(Configuration)-VC10/ + false + $(ProjectName).DebugVC10 + + + + $(IntDir)$(ProjectName)-$(Configuration)-BuildLog.htm + + + .\../bin/actsColorFollowingExample.tlb + + + + + MaxSpeed + OnlyExplicitInline + ..\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + false + Default + MultiThreadedDLL + false + false + true + + + Level3 + true + + + Default + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + AriaVC10.lib + 1.0 + true + ..\lib;%(AdditionalLibraryDirectories) + false + Console + false + + + MachineX86 + + + + + $(IntDir)$(ProjectName)-$(Configuration)-BuildLog.htm + + + .\../bin/actsColorFollowingExample.tlb + + + + + Disabled + ..\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + false + false + true + + + true + Level3 + true + ProgramDatabase + Default + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + AriaDebugVC10.lib + 1.0 + true + ..\lib;%(AdditionalLibraryDirectories) + true + true + Console + false + + + MachineX86 + + + + + $(IntDir)$(ProjectName)-$(Configuration)-BuildLog.htm + + + .\../bin/actsColorFollowingExample.tlb + + + + + Disabled + ..\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + false + false + true + + + true + Level3 + true + ProgramDatabase + Default + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;winmm.lib;AriaDebugVC9.lib;%(AdditionalDependencies) + 1.0 + true + ..\lib;%(AdditionalLibraryDirectories) + true + true + Console + false + + + MachineX86 + + + + + Disabled + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + EnableFastChecks + true + Disabled + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + EnableFastChecks + true + MaxSpeed + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + + + + \ No newline at end of file diff --git a/Legacy/Aria/examples/actsColorFollowingExample.cpp b/Legacy/Aria/examples/actsColorFollowingExample.cpp new file mode 100644 index 0000000..39817a9 --- /dev/null +++ b/Legacy/Aria/examples/actsColorFollowingExample.cpp @@ -0,0 +1,335 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ + +/** @example actsColorFollowingExample.cpp Connects to the ACTS program, and + * uses an ArAction subclass to drive the robot towards the largest detected + * blob. + */ + +#include "Aria.h" + + + +// Chase is an action that moves the robot toward the largest blob that +// appears in it's current field of view. +class Chase : public ArAction +{ + +public: + + // The state of the chase action + enum State { + NO_TARGET, // There is no target in view + TARGET, // This is a target in view + }; + + // Constructor + Chase(ArACTS_1_2 *acts, ArVCC4 *camera); + + // Destructor + ~Chase(void); + + // The action + ArActionDesired *fire(ArActionDesired currentDesired); + + // Set the ACTS channel that we want to get blob info from + bool setChannel(int channel); + + // Return the current state of this action + State getState(void) { return myState; } + + // Height and width of pixels from frame-grabber + enum { + WIDTH = 160, + HEIGHT = 120 + }; + +protected: + ArActionDesired myDesired; + ArACTS_1_2 *myActs; + ArVCC4 *myCamera; + ArTime myLastSeen; + State myState; + int myChannel; + int myMaxTime; +}; + + +// Constructor: Initialize the chase action +Chase::Chase(ArACTS_1_2 *acts, ArVCC4 *camera) : + ArAction("Chase", "Chases the largest blob.") +{ + myActs = acts; + myCamera = camera; + myChannel = 0; + myState = NO_TARGET; + setChannel(1); + myLastSeen.setToNow(); + myMaxTime = 1000; +} + +// Destructor +Chase::~Chase(void) {} + + +// The chase action +ArActionDesired *Chase::fire(ArActionDesired currentDesired) +{ + ArACTSBlob blob; + ArACTSBlob largestBlob; + + bool flag = false; + + int numberOfBlobs; + int blobArea = 10; + + double xRel, yRel; + + // Reset the desired action + myDesired.reset(); + + numberOfBlobs = myActs->getNumBlobs(myChannel); + + // If there are blobs to be seen, set the time to now + if(numberOfBlobs != 0) + { + for(int i = 0; i < numberOfBlobs; i++) + { + myActs->getBlob(myChannel, i + 1, &blob); + if(blob.getArea() > blobArea) + { + flag = true; + blobArea = blob.getArea(); + largestBlob = blob; + } + } + + myLastSeen.setToNow(); + } + + // If we have not seen a blob in a while... + if (myLastSeen.mSecSince() > myMaxTime) + { + if(myState != NO_TARGET) ArLog::log(ArLog::Normal, "Target Lost"); + myState = NO_TARGET; + } + else + { + // If we see a blob and haven't seen one before.. + if(myState != TARGET) { + ArLog::log(ArLog::Normal, "Target Aquired"); + ArLog::log(ArLog::Normal, "(Using channel %d with %d blobs)", myChannel, numberOfBlobs); + } + myState = TARGET; + } + + if(myState == TARGET && flag == true) + { + // Determine where the largest blob's center of gravity + // is relative to the center of the camera + xRel = (double)(largestBlob.getXCG() - WIDTH/2.0) / (double)WIDTH; + yRel = (double)(largestBlob.getYCG() - HEIGHT/2.0) / (double)HEIGHT; + + // Tilt the camera toward the blob + if(!(ArMath::fabs(yRel) < .20)) + { + if (-yRel > 0) + myCamera->tiltRel(1); + else + myCamera->tiltRel(-1); + } + + // Set the heading and velocity for the robot + if (ArMath::fabs(xRel) < .10) + { + myDesired.setDeltaHeading(0); + } + else + { + if (ArMath::fabs(-xRel * 10) <= 10) + myDesired.setDeltaHeading(-xRel * 10); + else if (-xRel > 0) + myDesired.setDeltaHeading(10); + else + myDesired.setDeltaHeading(-10); + + } + + myDesired.setVel(200); + return &myDesired; + } + + // If we have no target, then don't set any action and let lower priority + // actions (e.g. stop) control the robot. + return &myDesired; +} + +// Set the channel that the blob info will be obtained from +bool Chase::setChannel(int channel) +{ + if (channel >= 1 && channel <= ArACTS_1_2::NUM_CHANNELS) + { + myChannel = channel; + return true; + } + else + return false; +} + + + + +// Callback to enable/disable the keyboard driving action +void toggleAction(ArAction* action) +{ + if(action->isActive()) { + action->deactivate(); + ArLog::log(ArLog::Normal, "%s action is now deactivated.", action->getName()); + } + else { + action->activate(); + ArLog::log(ArLog::Normal, "%s action is now activated.", action->getName()); + } +} + + + +// Main function +int main(int argc, char** argv) +{ + Aria::init(); + + // The robot + ArRobot robot; + + // A key handler to take input from keyboard + ArKeyHandler keyHandler; + Aria::setKeyHandler(&keyHandler); + + // Sonar for basic obstacle avoidance + ArSonarDevice sonar; + + // The camera (Cannon VC-C4) + ArVCC4 vcc4 (&robot); + + // ACTS, for tracking blobs of color + ArACTS_1_2 acts; + + // command line arguments + ArArgumentParser argParser(&argc, argv); + argParser.loadDefaultArguments(); + + // The simple way to connect to things (takes arguments from argParser) + ArSimpleConnector simpleConnector(&argParser); + + // Parse the arguments + if (!Aria::parseArgs()) + { + Aria::logOptions(); + keyHandler.restore(); + Aria::exit(1); + return 1; + } + + // Robot motion limiter actions (if obstacles are detected by sonar) + ArActionLimiterForwards limiter("speed limiter near", 350, 800, 200); + ArActionLimiterForwards limiterFar("speed limiter far", 400, 1250, 300); + ArActionLimiterBackwards backwardsLimiter; + ArActionConstantVelocity stop("stop", 0); + //ArActionConstantVelocity backup("backup", -200); + + + // The color following action, defined above + Chase chase(&acts, &vcc4); + + // Keyboard teleoperation action + ArActionKeydrive keydriveAction; + + // Use the "a" key to activate/deactivate keydrive mode + keyHandler.addKeyHandler('a', new ArGlobalFunctor1(&toggleAction, &keydriveAction)); + + // Let Aria know about the key handler + Aria::setKeyHandler(&keyHandler); + + // Add the key handler to the robot + robot.attachKeyHandler(&keyHandler); + + // Add the sonar to the robot + robot.addRangeDevice(&sonar); + + // Connect to the robot + if (!simpleConnector.connectRobot(&robot)) + { + ArLog::log(ArLog::Terse, "Error: Could not connect to robot... exiting\n"); + keyHandler.restore(); + Aria::exit(1); + } + + // Open a connection to ACTS + if(!acts.openPort(&robot)) + { + ArLog::log(ArLog::Terse, "Error: Could not connect to ACTS... exiting."); + keyHandler.restore(); + Aria::exit(2); + } + + // Initialize the camera + vcc4.init(); + + // Wait a second..... + ArUtil::sleep(1000); + + // Artificially keep the robot from going too fast + robot.setAbsoluteMaxTransVel(400); + + // Enable the motors + robot.comInt(ArCommands::ENABLE, 1); + + // Turn off the amigobot sounds + robot.comInt(ArCommands::SOUNDTOG, 0); + + // Wait.... + ArUtil::sleep(200); + + // Add the actions to the robot in descending order of importance. + robot.addAction(&limiter, 7); + robot.addAction(&limiterFar, 6); + robot.addAction(&backwardsLimiter, 5); + robot.addAction(&keydriveAction, 4); + robot.addAction(&chase, 3); + robot.addAction(&stop, 1); + + // Start with keydrive action disabled. Use the 'a' key to turn it on. + keydriveAction.deactivate(); + + // Run the robot processing cycle until the connection is lost + ArLog::log(ArLog::Normal, "Running. Train ACTS to detect a color to drive towards an object, or use 'a' key to switch to keyboard driving mode."); + robot.run(true); + + Aria::exit(0); + return 0; +} + diff --git a/Legacy/Aria/examples/armExample-vc2003.vcproj b/Legacy/Aria/examples/armExample-vc2003.vcproj new file mode 100644 index 0000000..7e783b6 --- /dev/null +++ b/Legacy/Aria/examples/armExample-vc2003.vcproj @@ -0,0 +1,149 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/examples/armExample-vc2008.vcproj b/Legacy/Aria/examples/armExample-vc2008.vcproj new file mode 100644 index 0000000..1f253a6 --- /dev/null +++ b/Legacy/Aria/examples/armExample-vc2008.vcproj @@ -0,0 +1,211 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/examples/armExample-vc2010.vcxproj b/Legacy/Aria/examples/armExample-vc2010.vcxproj new file mode 100644 index 0000000..3febe2e --- /dev/null +++ b/Legacy/Aria/examples/armExample-vc2010.vcxproj @@ -0,0 +1,143 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + armExample + {731EC481-379F-4041-BEBD-358C26ACE117} + + + + Application + false + MultiByte + + + Application + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + .\../bin\ + ../obj/$(ProjectName)-$(Configuration)-VC10/ + false + .\../bin\ + ../obj/$(ProjectName)-$(Configuration)-VC10/ + false + $(ProjectName).DebugVC10 + + + + $(IntDir)$(ProjectName)-$(Configuration)-BuildLog.htm + + + .\Release/P2ArmSimple.tlb + + + + + MaxSpeed + OnlyExplicitInline + ..\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + true + true + + + Level3 + true + + + Default + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + AriaVC10.lib + true + ..\lib;%(AdditionalLibraryDirectories) + false + .\Release/P2ArmSimple.pdb + Console + false + + + MachineX86 + + + + + $(IntDir)$(ProjectName)-$(Configuration)-BuildLog.htm + + + .\Debug/P2ArmSimple.tlb + + + + + Disabled + ..\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + true + true + + + Level3 + true + + + Default + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + AriaDebugVC10.lib + true + ..\lib;%(AdditionalLibraryDirectories) + false + .\Debug/P2ArmSimple.pdb + Console + false + + + MachineX86 + + + + + + + + + \ No newline at end of file diff --git a/Legacy/Aria/examples/armExample.cpp b/Legacy/Aria/examples/armExample.cpp new file mode 100644 index 0000000..7028d82 --- /dev/null +++ b/Legacy/Aria/examples/armExample.cpp @@ -0,0 +1,162 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#include "Aria.h" + +/** @example armExample.cpp Example program showing use of the original 5DOF P2 arm accessory. + * + * Demonstrates how to connect with the Pioneer 2 controller + * and set up the P2Arm class, including the ARMpac handler. + * It simply queries and prints the status of the arm, moving it to a position, then exits. + * Note, The P2Arm class is only for use with the microcontroller-integrated original 5DOF + * Pioneer 2 arm (Robotica arm). The newer Energid Cyton 7DOF arm is accessed through + * separate cyton libraries. + * +*/ + +int main(int argc, char **argv) +{ + Aria::init(); + ArSimpleConnector con(&argc, argv); + ArRobot robot; + ArP2Arm arm; + + + if(!Aria::parseArgs()) + { + Aria::logOptions(); + Aria::exit(1); + return 1; + } + + ArLog::log(ArLog::Normal, "armExample: Connecting to the robot."); + if(!con.connectRobot(&robot)) + { + ArLog::log(ArLog::Terse, "armExample: Could not connect to the robot. Exiting."); + Aria::exit(1); + return 1; + } + robot.runAsync(true); + + // turn off sonar + robot.comInt(28, 0); + + // Set up and initialize the arm + arm.setRobot(&robot); + if (arm.init() != ArP2Arm::SUCCESS) + { + ArLog::log(ArLog::Terse, "armExample: Error initializing the P2 Arm!"); + return 1; + } + + // Print out some of the settings + P2ArmJoint *joint; + printf("Current joint info:\nJoint Vel Home Center\n"); + for (int i=1; i<=ArP2Arm::NumJoints; i++) + { + joint = arm.getJoint(i); + printf(" %2i: %5i %5i %5i\n", i, joint->myVel, joint->myHome, joint->myCenter); + } + printf("\n"); + + // Put the arm to work + printf("Powering on (takes a couple seconds to stabilize)\n"); + arm.powerOn(); + + // Request one status packet and print out the arm's status + printf("Current arm status:\n"); + arm.requestStatus(ArP2Arm::StatusSingle); + ArUtil::sleep(200); // Give time to get the packet + printf("Arm Status: "); + if (arm.getStatus() & ArP2Arm::ArmGood) + printf("Good=1 "); + else + printf("Good=0 "); + if (arm.getStatus() & ArP2Arm::ArmInited) + printf("Inited=1 "); + else + printf("Inited=0 "); + if (arm.getStatus() & ArP2Arm::ArmPower) + printf("Power=1 "); + else + printf("Power=0 "); + if (arm.getStatus() & ArP2Arm::ArmHoming) + printf("Homing=1 "); + else + printf("Homing=0 "); + printf("\n\n"); + + // Move the arm joints to specific positions + printf("Moving Arm...\n"); + int deploy_offset[] = {0, -100, 10, 40, 80, -55, 20}; + for (int i=1; i<=ArP2Arm::NumJoints; i++) + { + joint = arm.getJoint(i); + arm.moveToTicks(i, joint->myCenter + deploy_offset[i]); + } + + // Wait for arm to achieve new position, printing joint positions and M for + // moving, NM for not moving. + arm.requestStatus(ArP2Arm::StatusContinuous); + ArUtil::sleep(300); // wait a moment for arm status packet update with joints moving + bool moving = true; + while (moving) + { + moving = false; + printf("Joints: "); + for (int i=1; i<=ArP2Arm::NumJoints; i++) + { + printf("[%d] %.0f, ", i, arm.getJointPos(i)); + if (arm.getMoving(i)) + { + printf("M; "); + moving = true; + } + else + { + printf("NM; "); + } + } + printf("\r"); + } + printf("\n\n"); + + // Return arm to park, wait, and disconnect. (Though the arm will automatically park + // on client disconnect) + printf("Parking arm.\n"); + arm.park(); + + // Wait 5 seconds or until arm shuts off + for(int i = 5; (i > 0) && (arm.getStatus() & ArP2Arm::ArmPower); i--) + { + ArUtil::sleep(1000); + } + + // Disconnect from robot, etc., and exit. + printf("Shutting down ARIA and exiting.\n"); + Aria::exit(0); + return(0); +} + diff --git a/Legacy/Aria/examples/auxSerialExample-vc2003.vcproj b/Legacy/Aria/examples/auxSerialExample-vc2003.vcproj new file mode 100644 index 0000000..90967e6 --- /dev/null +++ b/Legacy/Aria/examples/auxSerialExample-vc2003.vcproj @@ -0,0 +1,156 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/examples/auxSerialExample-vc2008.vcproj b/Legacy/Aria/examples/auxSerialExample-vc2008.vcproj new file mode 100644 index 0000000..6fdb3d0 --- /dev/null +++ b/Legacy/Aria/examples/auxSerialExample-vc2008.vcproj @@ -0,0 +1,212 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/examples/auxSerialExample-vc2010.vcxproj b/Legacy/Aria/examples/auxSerialExample-vc2010.vcxproj new file mode 100644 index 0000000..392ad2e --- /dev/null +++ b/Legacy/Aria/examples/auxSerialExample-vc2010.vcxproj @@ -0,0 +1,144 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + auxSerialExample + {77DBE5F8-13CD-49FB-A4D9-35E360EC8992} + + + + Application + false + MultiByte + + + Application + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + .\../bin\ + ../obj/$(ProjectName)-$(Configuration)-VC10/ + false + .\../bin\ + ../obj/$(ProjectName)-$(Configuration)-VC10/ + false + $(ProjectName).DebugVC10 + + + + $(IntDir)$(ProjectName)-$(Configuration)-BuildLog.htm + + + .\../bin/getAuxExample.tlb + + + + + MaxSpeed + OnlyExplicitInline + ..\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + true + true + + + Level3 + true + + + Default + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + AriaVC10.lib + 1.0 + true + ..\lib;%(AdditionalLibraryDirectories) + false + Console + false + + + MachineX86 + + + + + $(IntDir)$(ProjectName)-$(Configuration)-BuildLog.htm + + + .\../bin/getAuxExample.tlb + + + + + Disabled + ..\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + true + true + + + true + Level3 + true + + + Default + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + AriaDebugVC10.lib + 1.0 + true + ..\lib;%(AdditionalLibraryDirectories) + false + Console + false + + + MachineX86 + + + + + + + + + \ No newline at end of file diff --git a/Legacy/Aria/examples/auxSerialExample.cpp b/Legacy/Aria/examples/auxSerialExample.cpp new file mode 100644 index 0000000..8c7fe14 --- /dev/null +++ b/Legacy/Aria/examples/auxSerialExample.cpp @@ -0,0 +1,152 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#include "Aria.h" + +/** @example auxSerialExample.cpp + * Demonstrates the use of a robot packet handler to recieve data from a device + * attached to the robot microcontroller's auxilliary serial port. + + This example shows how to use the GETAUX command and how to recieve SERAUX + serial port data. + To use this example, you must have the auxilliary serial port AUX1 on the + microcontroller (inside the robot) connected to a device that is sending text data. + + You can connect AUX1 to a computer through an RS-232 cable with a NULL modem adapter, + and run a program such as minicom (Linux) or HyperTerminal (Windows). Then just + type to send data to the AUX1 port. Configure minicom or HyperTerminal to have + the following serial port settings: + 9600 baud + 8 data bits, 1 stop bit, no parity + No flow control (not hardware, not software)! + + This program creates a packet handler function (getAuxPrinter) + and adds it to the ArRobot object. All packets recieved from the robot + are passed to all packet handlers. getAuxPrinter() checks whether the packet + is an SERAUX packet, and if so, prints out the data contained within the packet. + If a newline or carriage return character is recieved, then it sends a command + to send data back out through the AUX serial port. The packet handler then sends + a GETAUX command to the robot to request more data. +*/ + +// our robot object +ArRobot *robot; + +/** + Packet handler that simply prints out each byte of a packet as a + character, then sends another request for more data (using GETAUX command). + When it receives a newline or carriage return, it also replies + using the TTY2 command with a string ("Hello, world!\n\r"). +*/ +bool getAuxPrinter(ArRobotPacket *packet) +{ + char c; + + // If this is not an aux. serial data packet, then return false to allow other + // packet handlers to recieve the packet. The packet type ID numbers are found + // in the description of the GETAUX commands in the robot manual. + if (packet->getID() != 0xb0) // 0xB0 is SERAUXpac. SERAUX2pac is 0xB8, SERAUX3pac is 0xC8. + return false; + + // Get bytes out of the packet buffer and print them. + while (packet->getReadLength () < packet->getLength() - 2) + { + c = packet->bufToUByte(); + if (c == '\r' || c == '\n') + { + putchar('\n'); + + // How to send data to the serial port. See robot manual + // (but note that TTY2 is for the AUX1 port, TTY3 for AUX2, etc.) + robot->comStr(ArCommands::TTY2, "Hello, World!\n\r"); + } + else + putchar(c); + fflush(stdout); + } + + + // Request more data: + robot->comInt(ArCommands::GETAUX, 1); + + // To request 12 bytes at a time, specify that instead: + //robot->comInt(ArCommands::GETAUX, 12); + + // If you wanted to recieve information from the second aux. serial port, use + // the GETAUX2 command instead; but the packet returned will also have a + // different type ID. + //robot->comInt(ArCommands::GETAUX2, 1); + + + // Return true to indicate to ArRobot that we have handled this packet. + return true; +} + + +int main(int argc, char **argv) +{ + Aria::init(); + + ArArgumentParser argParser(&argc, argv); + ArSimpleConnector conn(&argParser); + argParser.loadDefaultArguments(); + if(!Aria::parseArgs() || !argParser.checkHelpAndWarnUnparsed()) + { + Aria::logOptions(); + return 1; + } + + // This is a global pointer so the global functions can use it. + robot = new ArRobot; + + // functor for the packet handler + ArGlobalRetFunctor1 getAuxCB(&getAuxPrinter); + // add our packet handler as the first one in the list + robot->addPacketHandler(&getAuxCB, ArListPos::FIRST); + + // Connect to the robot + if(!conn.connectRobot(robot)) + { + ArLog::log(ArLog::Terse, "getAuxExample: Error connecting to the robot."); + return 2; + } + + ArLog::log(ArLog::Normal, "getAuxExample: Connected to the robot. Sending command to change AUX1 baud rate to 9600..."); + robot->comInt(ArCommands::AUX1BAUD, 0); // See robot manual + + // Send the first GETAUX request + robot->comInt(ArCommands::GETAUX, 1); + + // If you wanted to recieve information from the second aux. serial port, use + // the GETAUX2 command instead; but the packet returned will also have a + // different type ID. + //robot->comInt(ArCommands::GETAUX2, 1); + + // run the robot until disconnect, then shutdown and exit. + robot->run(true); + Aria::exit(0); + return 0; +} + diff --git a/Legacy/Aria/examples/cameraPTZExample.cpp b/Legacy/Aria/examples/cameraPTZExample.cpp new file mode 100644 index 0000000..6413f62 --- /dev/null +++ b/Legacy/Aria/examples/cameraPTZExample.cpp @@ -0,0 +1,167 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#include "Aria.h" +//#include "ArVideo.h" + +/** @example cameraPTZExample.cpp This is an example showing how to connect to + * and use a camera's PTZ control (or DPPTU) + * + * This program can control PTZ cameras with support built in to the ARIA + * library: Canon VCC 4/5, Sony PTZ, RVision, and DPPTU. To control the Axis + * network cameras, see example programs in the ArVideo library instead. + * + * PTZ type and connection parameters are read from robot parameter file if + * available, or use command-line arguments to override the robot parameter + * file. Run with --help for a complete list of command-line options available. + * + * For example, to connect to Canon VCC on robot auxilliary serial port, use: + * ./cameraPTZExample -ptzType vcc4 + * + * To connect to Canon VCC on serial port COM4, use: + * ./cameraPTZExample -ptzType vcc4 -ptzSerialPort COM4 + * or on Linux this works too: + * ./cameraPTZExample -ptzType vcc4 -ptzSerialPort /dev/ttyS3 + * + * To connect to RVision camera, use: + * ./cameraPTZExample -ptzType rvision + * + * To connect to DPPTU use: + * ./cameraPTZExample -ptzType dpptu + * + * Canon VCC defaults to use the microcontroller port Aux1. Use + * -ptzRobotAuxSerialPort or -ptzSerialPort arguments to change. + */ + + +int main(int argc, char **argv) +{ + Aria::init(); + //ArVideo::init(); +// ArLog::init(ArLog::StdOut, ArLog::Verbose); + ArArgumentParser parser(&argc, argv); + parser.loadDefaultArguments(); + ArRobot robot; + ArRobotConnector robotConnector(&parser, &robot); + + // This is used to create and configure the PTZ interface object based on the + // robot's parameter file and this program's command line options (run with + // -help for list). Must be created before calling Aria::parseArgs(). + ArPTZConnector ptzConnector(&parser, &robot); + + if(!robotConnector.connectRobot()) + { + ArLog::log(ArLog::Terse, "cameraPTZExample: Warning, Could not connect to the robot. Won't use robot parameter file for defaults"); + } + + if (!Aria::parseArgs() || !parser.checkHelpAndWarnUnparsed()) + { + Aria::logOptions(); + Aria::exit(1); + } + + ArLog::log(ArLog::Normal, "cameraPTZExample: Connected."); + + robot.runAsync(true); + + // Create and connect to all PTZs given in robot parameter file and command + // line. + const int PauseTime = 3500; // ms + ptzConnector.connect(); + ArUtil::sleep(PauseTime*2); + for(size_t i = 0; i < ptzConnector.getNumPTZs(); ++i) + { + ArLog::log(ArLog::Normal, "cameraPTZExample: [getPTZ(%d)..]", i); + + ArPTZ *ptz = ptzConnector.getPTZ(i); + if(!ptz) + { + ArLog::log(ArLog::Normal, "cameraPTZExample: there is no PTZ %d.", i+1); + continue; + } + + ArLog::log(ArLog::Normal, "cameraPTZExample: ===== PTZ #%d is a %s =====", i+1, ptz->getTypeName()); + + ArLog::log(ArLog::Normal, "cameraPTZExample: Pan left -90.."); + ptz->pan(-90); + ArUtil::sleep(PauseTime); + ArLog::log(ArLog::Normal, "cameraPTZExample: Pan position is now %f (%s).", ptz->getPan(), (ptz->canGetRealPanTilt()?"real position from camera":"last command sent")); + if(!ArMath::compareFloats(ptz->getPan(), -90, 1)) + ArLog::log(ArLog::Normal, "cameraPTZExample: Warning: pan position is more than one degree different from command -90."); + + ArLog::log(ArLog::Normal, "cameraPTZExample: Pan right 90.."); + ptz->pan(90); + ArUtil::sleep(PauseTime); + ArLog::log(ArLog::Normal, "cameraPTZExample: Pan position is now %f. (%s)", ptz->getPan(), (ptz->canGetRealPanTilt()?"real position from camera":"last command sent")); + if(!ArMath::compareFloats(ptz->getPan(), 90, 1)) + ArLog::log(ArLog::Normal, "cameraPTZExample: Warning: pan position is more than one degree different from command 90."); + + ArLog::log(ArLog::Normal, "cameraPTZExample: Pan center 0.."); + ptz->pan(0); + ArUtil::sleep(PauseTime); + ArLog::log(ArLog::Normal, "cameraPTZExample: Pan position is now %f (%s).", ptz->getPan(), (ptz->canGetRealPanTilt()?"real position from camera":"last command sent")); + if(!ArMath::compareFloats(ptz->getPan(), 0, 1)) + ArLog::log(ArLog::Normal, "cameraPTZExample: Warning: pan position is more than one degree different from command 0."); + + ArLog::log(ArLog::Normal, "cameraPTZExample: Tilt up 90.."); + ptz->tilt(90); + ArUtil::sleep(PauseTime); + ArLog::log(ArLog::Normal, "cameraPTZExample: Tilt position is now %f(%s).", ptz->getTilt(), (ptz->canGetRealPanTilt()?"real position from camera":"last command sent")); + if(!ArMath::compareFloats(ptz->getTilt(), 90, 1)) + ArLog::log(ArLog::Normal, "cameraPTZExample: Warning: tilt position is more than one degree different from command 90."); + + ArLog::log(ArLog::Normal, "cameraPTZExample: Tilt down -20.."); + ptz->tilt(-20); + ArUtil::sleep(PauseTime); + ArLog::log(ArLog::Normal, "cameraPTZExample: Tilt position is now %f(%s).", ptz->getTilt(), (ptz->canGetRealPanTilt()?"real position from camera":"last command sent")); + if(!ArMath::compareFloats(ptz->getTilt(), -20, 1)) + ArLog::log(ArLog::Normal, "cameraPTZExample: Warning: tilt position is more than one degree different from command -20."); + + ArLog::log(ArLog::Normal, "cameraPTZExample: Tilt center 0.."); + ptz->tilt(0); + ArUtil::sleep(PauseTime); + ArLog::log(ArLog::Normal, "cameraPTZExample: Tilt position is now %f (%s).", ptz->getTilt(), (ptz->canGetRealPanTilt()?"real position from camera":"last command sent")); + if(!ArMath::compareFloats(ptz->getTilt(), 0, 1)) + ArLog::log(ArLog::Normal, "cameraPTZExample: Warning: tilt position is more than one degree different from command 0."); + + ArLog::log(ArLog::Normal, "cameraPTZExample: Reset.."); + ptz->reset(); + ArLog::log(ArLog::Normal, "cameraPTZExample: Pan position is now %f (%s).", ptz->getPan(), (ptz->canGetRealPanTilt()?"real position from camera":"last command sent")); + ArLog::log(ArLog::Normal, "cameraPTZExample: Tilt position is now %f (%s).", ptz->getTilt(), (ptz->canGetRealPanTilt()?"real position from camera":"last command sent")); + ArUtil::sleep(PauseTime); + } + + ArLog::log(ArLog::Normal, "cameraPTZExample: Ending robot thread.."); + robot.stopRunning(); + + // wait for the thread to stop + robot.waitForRunExit(); + + // exit + ArLog::log(ArLog::Normal, "cameraPTZExample: Exiting."); + Aria::exit(0); + return 0; +} + diff --git a/Legacy/Aria/examples/cameraPTZExample.vcxproj b/Legacy/Aria/examples/cameraPTZExample.vcxproj new file mode 100644 index 0000000..bc488a3 --- /dev/null +++ b/Legacy/Aria/examples/cameraPTZExample.vcxproj @@ -0,0 +1,154 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {D641D2B7-3B96-437A-96F9-7F7B2B1FDC2F} + cameraPTZExample + cameraPTZExample + + + + Application + true + MultiByte + + + Application + true + MultiByte + Windows7.1SDK + + + Application + false + true + MultiByte + + + Application + false + true + MultiByte + Windows7.1SDK + + + + + + + + + + + + + + + + + + + ../../bin/ + + + ../../bin64/ + + + ../obj/$(ProjectName)-$(Configuration)-VC10/ + $(ProjectName)_d + + + ../obj64/$(ProjectName)-$(Configuration)-VC10/ + + + ../../bin/ + + + ../../bin64/ + + + ../obj/$(ProjectName)-$(Configuration)-VC10/ + + + ../obj64/$(ProjectName)-$(Configuration)-VC10/ + + + + Level3 + Disabled + ../include;../../include;../../ArNetworking/include + + + true + AriaDebugVC10.lib;ArNetworkingDebugVC10.lib;ws2_32.lib;winmm.lib + ../../lib + + + + + Level3 + Disabled + ../include;../../include;../../ArNetworking/include + + + true + AriaDebugVC10.lib;ArNetworkingDebugVC10.lib;ws2_32.lib;winmm.lib + ../../lib + + + + + Level3 + MaxSpeed + true + true + ../include;../../include;../../ArNetworking/include + + + true + true + true + AriaVC10.lib;ArNetworkingVC10.lib;ws2_32.lib;winmm.lib + ../../lib + + + + + Level3 + MaxSpeed + true + true + ../include;../../include;../../ArNetworking/include + + + true + true + true + AriaVC10.lib;ArNetworkingVC10.lib;ws2_32.lib;winmm.lib + ../../lib + + + + + + + + + diff --git a/Legacy/Aria/examples/configExample.cpp b/Legacy/Aria/examples/configExample.cpp new file mode 100644 index 0000000..18c9125 --- /dev/null +++ b/Legacy/Aria/examples/configExample.cpp @@ -0,0 +1,155 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#include "Aria.h" + +/** @example configExample.cpp Example program demonstrating the use of ArConfig + * + * This program shows how to use ArConfig to store configuration parameters + * and load/save them from a file. + * + * The ArNetworking library includes server classes that will let you + * use a remote client such as MobileEyes to view and change the configuration. + * See ArNetworking documentation and examples. + */ + +class ConfigExample +{ + ArConfig* myConfig; + int myIntParam; + double myDoubleParam; + bool myBoolParam; + char myStringParam[256]; + ArRetFunctorC myProcessConfigCB; + +public: + ConfigExample(): + myIntParam(0), + myDoubleParam(0.5), + myBoolParam(false), + myProcessConfigCB(this, &ConfigExample::processConfigFile) + { + // The global Aria class contains an ArConfig object. You can create + // other instances of ArConfig, but this is how you can share one ArConfig + // among various program modules. + // If you want to store a config parameter in ArConfig, first you must add + // it to the ArConfig object. Parameters are stored in sections, and + // they affect a variable via a pointer provided in an ArConfigArg + // object: + ArConfig* config = Aria::getConfig(); + config->setSectionComment("Example Section", "Contains parameters created by the configExample"); + + // Add an integer which ranges from -10 to 10: + config->addParam( ArConfigArg("ExampleIntegerParameter", &myIntParam, "Example parameter integer.", -10, 10), "Example Section", ArPriority::NORMAL); + + // Add a floating point number which ranges from 0.0 to 1.0: + config->addParam( ArConfigArg("ExampleDoubleParameter", &myDoubleParam, "Example double precision floating point number.", 0.0, 1.0), "Example Section", ArPriority::NORMAL); + + // Essential parameters can be placed in the "Important" priority level: + config->addParam( ArConfigArg("ExampleBoolParameter", &myBoolParam, "Example boolean parameter."), "Example Section", ArPriority::IMPORTANT); + + // Unimportant parameters can be placed in the "Trivial" priority level: + myStringParam[0] = '\0'; // make string empty + config->addParam( ArConfigArg("ExampleStringParameter", myStringParam, "Example string parameter.", 256), "Example Section", ArPriority::TRIVIAL); + + // You can set a callback to be invoked when the configuration changes, in + // case you need to respond to any changes in the parameter values: + config->addProcessFileCB(&myProcessConfigCB, 0); + } + + + // Method called by config process callback when a new file is loaded. + // It can return false to indicate an error, or true to indicate no error. + bool processConfigFile() + { + ArLog::log(ArLog::Normal, "configExample: Config changed. New values: int=%d, float=%f, bool=%s, string=\"%s\".", myIntParam, myDoubleParam, myBoolParam?"true":"false", myStringParam); + return true; + } +}; + +int main(int argc, char **argv) +{ + Aria::init(); + ArArgumentParser argParser(&argc, argv); + argParser.loadDefaultArguments(); + if (argc < 2 || !Aria::parseArgs() || argParser.checkArgument("-help")) + { + ArLog::log(ArLog::Terse, "configExample usage: configExample .\nFor example, \"configExample examples/configExample.cfg\"."); + Aria::logOptions(); + Aria::exit(1); + return 1; + } + + // Object containing config parameters, and responding to changes: + ConfigExample configExample; + + // Load a config file given on the command line into the global + // ArConfig object kept by Aria. Normally ArConfig expects config + // files to be in the main ARIA directory (i.e. /usr/local/Aria or + // a directory specified by the $ARIA environment variable). + char error[512]; + const char* filename = argParser.getArg(1); + ArConfig* config = Aria::getConfig(); + ArLog::log(ArLog::Normal, "configExample: loading configuration file \"%s\"...", filename); + if (! config->parseFile(filename, true, false, error, 512) ) + { + ArLog::log(ArLog::Terse, "configExample: Error loading configuration file \"%s\" %s. Try \"examples/configExample.cfg\".", filename, error); + Aria::exit(-1); + return -1; + } + + ArLog::log(ArLog::Normal, "configExample: Loaded configuration file \"%s\".", filename); + + // After changing a config value, you should invoke the callbacks: + ArConfigSection* section = config->findSection("Example Section"); + if (section) + { + ArConfigArg* arg = section->findParam("ExampleBoolParameter"); + if (arg) + { + arg->setBool(!arg->getBool()); + if (! config->callProcessFileCallBacks(false, error, 512) ) + { + ArLog::log(ArLog::Terse, "configExample: Error processing modified config: %s.", error); + } + else + { + ArLog::log(ArLog::Normal, "configExample: Successfully modified config and invoked callbacks."); + } + } + } + + // You can save the configuration as well: + ArLog::log(ArLog::Normal, "configExample: Saving configuration..."); + if(!config->writeFile(filename)) + { + ArLog::log(ArLog::Terse, "configExample: Error saving configuration to file \"%s\"!", filename); + } + + // end of program. + ArLog::log(ArLog::Normal, "configExample: end of program."); + Aria::exit(0); + return 0; +} diff --git a/Legacy/Aria/examples/demo b/Legacy/Aria/examples/demo new file mode 100755 index 0000000000000000000000000000000000000000..aefbb29337543db252612e56680a81d242d81a36 GIT binary patch literal 19160 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 Xp^KzTRkp|x?|WtWAL*oKr|AC%Os+qG literal 0 HcmV?d00001 diff --git a/Legacy/Aria/examples/demo-vc2003.vcproj b/Legacy/Aria/examples/demo-vc2003.vcproj new file mode 100644 index 0000000..0f7dc21 --- /dev/null +++ b/Legacy/Aria/examples/demo-vc2003.vcproj @@ -0,0 +1,178 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/examples/demo-vc2008.vcproj b/Legacy/Aria/examples/demo-vc2008.vcproj new file mode 100644 index 0000000..265c526 --- /dev/null +++ b/Legacy/Aria/examples/demo-vc2008.vcproj @@ -0,0 +1,242 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/examples/demo-vc2010.vcxproj b/Legacy/Aria/examples/demo-vc2010.vcxproj new file mode 100644 index 0000000..12796cb --- /dev/null +++ b/Legacy/Aria/examples/demo-vc2010.vcxproj @@ -0,0 +1,164 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + demo + {E1137892-32C1-4250-8784-8D48A6BEE2DD} + + + + Application + false + MultiByte + false + v100 + + + Application + false + MultiByte + false + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + ../bin/ + ../obj/$(ProjectName)-$(Configuration)-VC10/ + false + ../bin/ + ../obj/$(ProjectName)-$(Configuration)-VC10/ + false + $(ProjectName)Debug + $(ProjectName) + + + + $(IntDir)$(ProjectName)-$(Configuration)-BuildLog.htm + + + .\../bin/demo.tlb + + + + + MaxSpeed + AnySuitable + true + ..\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + false + Default + MultiThreadedDLL + false + false + true + + + Level3 + true + + + Default + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + AriaVC10.lib + $(OutDir)$(TargetFileName) + 1.0 + true + ..\lib;%(AdditionalLibraryDirectories) + false + Console + false + + + MachineX86 + + + + + $(IntDir)$(ProjectName)-$(Configuration)-BuildLog.htm + + + .\../bin/demo.tlb + + + + + Disabled + ..\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + false + false + true + + + true + Level3 + true + ProgramDatabase + Default + true + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + AriaDebugVC10.lib + $(OutDir)$(TargetFileName) + 1.0 + true + ..\lib;%(AdditionalLibraryDirectories) + true + true + Console + false + + + MachineX86 + + + + + Disabled + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + EnableFastChecks + true + MaxSpeed + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + + + + \ No newline at end of file diff --git a/Legacy/Aria/examples/demo.cpp b/Legacy/Aria/examples/demo.cpp new file mode 100644 index 0000000..4829f27 --- /dev/null +++ b/Legacy/Aria/examples/demo.cpp @@ -0,0 +1,214 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#include "Aria.h" + + +/** @example demo.cpp General purpose testing and demo program, using ArMode + * classes to provide keyboard control of various robot functions. + * + * demo uses ArMode subclasses from ARIA. These modes + * provide keyboard control of various aspects and accessories of + * the robot, and can be re-used in your programs if you wish. + * The ArMode classes are defined in %ArModes.cpp. + * + * "demo" is a useful program for testing out the operation of the robot + * for diagnostic or demonstration purposes. Other example programs + * focus on individual areas. + */ + +int main(int argc, char** argv) +{ + // Initialize some global data + Aria::init(); + + // If you want ArLog to print "Verbose" level messages uncomment this: + //ArLog::init(ArLog::StdOut, ArLog::Verbose); + + // This object parses program options from the command line + ArArgumentParser parser(&argc, argv); + + // Load some default values for command line arguments from /etc/Aria.args + // (Linux) or the ARIAARGS environment variable. + parser.loadDefaultArguments(); + + // Central object that is an interface to the robot and its integrated + // devices, and which manages control of the robot by the rest of the program. + ArRobot robot; + + // Object that connects to the robot or simulator using program options + ArRobotConnector robotConnector(&parser, &robot); + + // If the robot has an Analog Gyro, this object will activate it, and + // if the robot does not automatically use the gyro to correct heading, + // this object reads data from it and corrects the pose in ArRobot + ArAnalogGyro gyro(&robot); + + // Connect to the robot, get some initial data from it such as type and name, + // and then load parameter files for this robot. + if (!robotConnector.connectRobot()) + { + // Error connecting: + // if the user gave the -help argumentp, then just print out what happened, + // and continue so options can be displayed later. + if (!parser.checkHelpAndWarnUnparsed()) + { + ArLog::log(ArLog::Terse, "Could not connect to robot, will not have parameter file so options displayed later may not include everything"); + } + // otherwise abort + else + { + ArLog::log(ArLog::Terse, "Error, could not connect to robot."); + Aria::logOptions(); + Aria::exit(1); + } + } + + if(!robot.isConnected()) + { + ArLog::log(ArLog::Terse, "Internal error: robot connector succeeded but ArRobot::isConnected() is false!"); + } + + // Connector for laser rangefinders + ArLaserConnector laserConnector(&parser, &robot, &robotConnector); + + // Connector for compasses + ArCompassConnector compassConnector(&parser); + + // Parse the command line options. Fail and print the help message if the parsing fails + // or if the help was requested with the -help option + if (!Aria::parseArgs() || !parser.checkHelpAndWarnUnparsed()) + { + Aria::logOptions(); + Aria::exit(1); + return 1; + } + + // Used to access and process sonar range data + ArSonarDevice sonarDev; + + // Used to perform actions when keyboard keys are pressed + ArKeyHandler keyHandler; + Aria::setKeyHandler(&keyHandler); + + // ArRobot contains an exit action for the Escape key. It also + // stores a pointer to the keyhandler so that other parts of the program can + // use the same keyhandler. + robot.attachKeyHandler(&keyHandler); + printf("You may press escape to exit\n"); + + // Attach sonarDev to the robot so it gets data from it. + robot.addRangeDevice(&sonarDev); + + + // Start the robot task loop running in a new background thread. The 'true' argument means if it loses + // connection the task loop stops and the thread exits. + robot.runAsync(true); + + // Connect to the laser(s) if lasers were configured in this robot's parameter + // file or on the command line, and run laser processing thread if applicable + // for that laser class. For the purposes of this demo, add all + // possible lasers to ArRobot's list rather than just the ones that were + // connected by this call so when you enter laser mode, you + // can then interactively choose which laser to use from that list of all + // lasers mentioned in robot parameters and on command line. Normally, + // only connected lasers are put in ArRobot's list. + if (!laserConnector.connectLasers( + false, // continue after connection failures + false, // add only connected lasers to ArRobot + true // add all lasers to ArRobot + )) + { + printf("Could not connect to lasers... exiting\n"); + Aria::exit(2); + } + +/* not needed, robot connector will do it by default + if (!sonarConnector.connectSonars( + false, // continue after connection failures + false, // add only connected lasers to ArRobot + true // add all lasers to ArRobot + )) + { + printf("Could not connect to sonars... exiting\n"); + Aria::exit(2); + } +*/ + + // Create and connect to the compass if the robot has one. + ArTCM2 *compass = compassConnector.create(&robot); + if(compass && !compass->blockingConnect()) { + compass = NULL; + } + + // Sleep for a second so some messages from the initial responses + // from robots and cameras and such can catch up + ArUtil::sleep(1000); + + // We need to lock the robot since we'll be setting up these modes + // while the robot task loop thread is already running, and they + // need to access some shared data in ArRobot. + robot.lock(); + + // now add all the modes for this demo + // these classes are defined in ArModes.cpp in ARIA's source code. + + if(robot.getOrigRobotConfig()->getHasGripper()) + new ArModeGripper(&robot, "gripper", 'g', 'G'); + else + ArLog::log(ArLog::Normal, "Robot does not indicate that it has a gripper."); + ArModeActs actsMode(&robot, "acts", 'a', 'A'); + ArModeTCM2 tcm2(&robot, "tcm2", 'm', 'M', compass); + ArModeIO io(&robot, "io", 'i', 'I'); + ArModeConfig cfg(&robot, "report robot config", 'o' , 'O'); + ArModeCommand command(&robot, "command", 'd', 'D'); + ArModeCamera camera(&robot, "camera", 'c', 'C'); + ArModePosition position(&robot, "position", 'p', 'P', &gyro); + ArModeSonar sonar(&robot, "sonar", 's', 'S'); + ArModeBumps bumps(&robot, "bumps", 'b', 'B'); + ArModeLaser laser(&robot, "laser", 'l', 'L'); + ArModeWander wander(&robot, "wander", 'w', 'W'); + ArModeUnguardedTeleop unguardedTeleop(&robot, "unguarded teleop", 'u', 'U'); + ArModeTeleop teleop(&robot, "teleop", 't', 'T'); + + + // activate the default mode + teleop.activate(); + + // turn on the motors + robot.comInt(ArCommands::ENABLE, 1); + + robot.unlock(); + + // Block execution of the main thread here and wait for the robot's task loop + // thread to exit (e.g. by robot disconnecting, escape key pressed, or OS + // signal) + robot.waitForRunExit(); + + Aria::exit(0); + return 0; + +} + diff --git a/Legacy/Aria/examples/demoStatic-vc2003.vcproj b/Legacy/Aria/examples/demoStatic-vc2003.vcproj new file mode 100644 index 0000000..97ce029 --- /dev/null +++ b/Legacy/Aria/examples/demoStatic-vc2003.vcproj @@ -0,0 +1,141 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/examples/demoStatic-vc2008.vcproj b/Legacy/Aria/examples/demoStatic-vc2008.vcproj new file mode 100644 index 0000000..0f167d3 --- /dev/null +++ b/Legacy/Aria/examples/demoStatic-vc2008.vcproj @@ -0,0 +1,213 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/examples/demoStatic-vc2010.vcxproj b/Legacy/Aria/examples/demoStatic-vc2010.vcxproj new file mode 100644 index 0000000..2ffe391 --- /dev/null +++ b/Legacy/Aria/examples/demoStatic-vc2010.vcxproj @@ -0,0 +1,143 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + demoStatic + {B7623346-D762-4325-BC88-B85E84E78D19} + demoStatic + ManagedCProj + + + + Application + MultiByte + false + + + Application + MultiByte + false + v100 + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + ..\bin\ + ../obj/$(ProjectName)-$(Configuration)-VC10/ + true + ..\bin\ + ../obj/$(ProjectName)-$(Configuration)-VC10/ + false + demoStaticDebug + $(ProjectName) + + + + $(IntDir)$(ProjectName)BuildLog.htm + + + Disabled + ..\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;ARIA_STATIC;%(PreprocessorDefinitions) + false + Default + MultiThreadedDebug + false + + + Level3 + ProgramDatabase + true + + + false + + + AriaStaticDebugVC10.lib;ws2_32.lib;winmm.lib;advapi32.lib;%(AdditionalDependencies) + $(OutDir)$(TargetFileName) + true + ..\lib;%(AdditionalLibraryDirectories) + %(IgnoreSpecificDefaultLibraries) + true + true + false + + + NotSet + + + + + $(IntDir)$(ProjectName)BuildLog.htm + + + AnySuitable + true + ..\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;ARIA_STATIC;%(PreprocessorDefinitions) + false + MultiThreaded + false + true + + + Level3 + ProgramDatabase + true + + + AriaStaticVC10.lib;winmm.lib;ws2_32.lib;%(AdditionalDependencies) + $(OutDir)$(TargetFileName) + true + ..\lib;%(AdditionalLibraryDirectories) + %(IgnoreSpecificDefaultLibraries) + false + false + + + + + NotSet + + + + + true + true + + + true + true + + + true + true + + + + + + + + + \ No newline at end of file diff --git a/Legacy/Aria/examples/directMotionExample-vc2003.vcproj b/Legacy/Aria/examples/directMotionExample-vc2003.vcproj new file mode 100644 index 0000000..b11d44e --- /dev/null +++ b/Legacy/Aria/examples/directMotionExample-vc2003.vcproj @@ -0,0 +1,156 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/examples/directMotionExample-vc2008.vcproj b/Legacy/Aria/examples/directMotionExample-vc2008.vcproj new file mode 100644 index 0000000..a2ca73b --- /dev/null +++ b/Legacy/Aria/examples/directMotionExample-vc2008.vcproj @@ -0,0 +1,212 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/examples/directMotionExample-vc2010.vcxproj b/Legacy/Aria/examples/directMotionExample-vc2010.vcxproj new file mode 100644 index 0000000..e435c19 --- /dev/null +++ b/Legacy/Aria/examples/directMotionExample-vc2010.vcxproj @@ -0,0 +1,144 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + directMotionExample + {BD31FF37-DDBD-4BBD-9ABC-5DE439735DBF} + + + + Application + false + MultiByte + + + Application + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + .\../bin\ + ../obj/$(ProjectName)-$(Configuration)-VC10/ + false + .\../bin\ + ../obj/$(ProjectName)-$(Configuration)-VC10/ + false + $(ProjectName).DebugVC10 + + + + $(IntDir)$(ProjectName)-$(Configuration)-BuildLog.htm + + + .\../bin/directMotionDemo.tlb + + + + + Disabled + ..\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + true + true + + + true + Level3 + true + + + Default + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + AriaDebugVC10.lib + 1.0 + true + ..\lib;%(AdditionalLibraryDirectories) + false + Console + false + + + MachineX86 + + + + + $(IntDir)$(ProjectName)-$(Configuration)-BuildLog.htm + + + .\../bin/directMotionDemo.tlb + + + + + MaxSpeed + OnlyExplicitInline + ..\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + true + true + + + Level3 + true + + + Default + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + AriaVC10.lib + 1.0 + true + ..\lib;%(AdditionalLibraryDirectories) + false + Console + false + + + MachineX86 + + + + + + + + + \ No newline at end of file diff --git a/Legacy/Aria/examples/directMotionExample.cpp b/Legacy/Aria/examples/directMotionExample.cpp new file mode 100644 index 0000000..6ce7bdd --- /dev/null +++ b/Legacy/Aria/examples/directMotionExample.cpp @@ -0,0 +1,338 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#include "Aria.h" + +/** @example directMotionExample.cpp Sends a sequence of motion commands directly + * to the robot using ArRobot's direct motion command methods. + + This demo starts up the robot in its own thread, then calls a series of the + motion commands methods in ArRobot to simply send commands directly + to the robot (rather than using e.g. ArAction objects.) + + Note that if you want to stop direct motion + commands and let ArActions take over, you must call ArRobot::clearDirectMotion() (otherwise ArRobot may continue sending motion commands that conflict + with the requests of the action resolver). + See the section on motion commands and actions for details. +*/ + +/* + This is a connection handler class, to demonstrate how to run code in + response to events such as the program connecting an disconnecting + from the robot. +*/ +class ConnHandler +{ +public: + // Constructor + ConnHandler(ArRobot *robot); + // Destructor, its just empty + ~ConnHandler(void) {} + // to be called if the connection was made + void connected(void); + // to call if the connection failed + void connFail(void); + // to be called if the connection was lost + void disconnected(void); +protected: + // robot pointer + ArRobot *myRobot; + // the functor callbacks + ArFunctorC myConnectedCB; + ArFunctorC myConnFailCB; + ArFunctorC myDisconnectedCB; +}; + +ConnHandler::ConnHandler(ArRobot *robot) : + myConnectedCB(this, &ConnHandler::connected), + myConnFailCB(this, &ConnHandler::connFail), + myDisconnectedCB(this, &ConnHandler::disconnected) + +{ + myRobot = robot; + myRobot->addConnectCB(&myConnectedCB, ArListPos::FIRST); + myRobot->addFailedConnectCB(&myConnFailCB, ArListPos::FIRST); + myRobot->addDisconnectNormallyCB(&myDisconnectedCB, ArListPos::FIRST); + myRobot->addDisconnectOnErrorCB(&myDisconnectedCB, ArListPos::FIRST); +} + +// just exit if the connection failed +void ConnHandler::connFail(void) +{ + printf("directMotionDemo connection handler: Failed to connect.\n"); + myRobot->stopRunning(); + Aria::exit(1); + return; +} + +// turn on motors, and off sonar, and off amigobot sounds, when connected +void ConnHandler::connected(void) +{ + printf("directMotionDemo connection handler: Connected\n"); + myRobot->comInt(ArCommands::SONAR, 0); + myRobot->comInt(ArCommands::ENABLE, 1); + myRobot->comInt(ArCommands::SOUNDTOG, 0); +} + +// lost connection, so just exit +void ConnHandler::disconnected(void) +{ + printf("directMotionDemo connection handler: Lost connection, exiting program.\n"); + Aria::exit(0); +} + + + +int main(int argc, char **argv) +{ + Aria::init(); + + ArArgumentParser argParser(&argc, argv); + argParser.loadDefaultArguments(); + + + ArRobot robot; + ArRobotConnector con(&argParser, &robot); + + // the connection handler from above + ConnHandler ch(&robot); + + if(!Aria::parseArgs()) + { + Aria::logOptions(); + Aria::exit(1); + return 1; + } + + if(!con.connectRobot()) + { + ArLog::log(ArLog::Normal, "directMotionExample: Could not connect to the robot. Exiting."); + + if(argParser.checkHelpAndWarnUnparsed()) + { + Aria::logOptions(); + } + Aria::exit(1); + return 1; + } + + ArLog::log(ArLog::Normal, "directMotionExample: Connected."); + + if(!Aria::parseArgs() || !argParser.checkHelpAndWarnUnparsed()) + { + Aria::logOptions(); + Aria::exit(1); + } + + // Run the robot processing cycle in its own thread. Note that after starting this + // thread, we must lock and unlock the ArRobot object before and after + // accessing it. + robot.runAsync(false); + + + // Send the robot a series of motion commands directly, sleeping for a + // few seconds afterwards to give the robot time to execute them. + printf("directMotionExample: Setting rot velocity to 100 deg/sec then sleeping 3 seconds\n"); + robot.lock(); + robot.setRotVel(100); + robot.unlock(); + ArUtil::sleep(3*1000); + printf("Stopping\n"); + robot.lock(); + robot.setRotVel(0); + robot.unlock(); + ArUtil::sleep(200); + + printf("directMotionExample: Telling the robot to go 300 mm on left wheel and 100 mm on right wheel for 5 seconds\n"); + robot.lock(); + robot.setVel2(300, 100); + robot.unlock(); + ArTime start; + start.setToNow(); + while (1) + { + robot.lock(); + if (start.mSecSince() > 5000) + { + robot.unlock(); + break; + } + robot.unlock(); + ArUtil::sleep(50); + } + + printf("directMotionExample: Telling the robot to move forwards one meter, then sleeping 5 seconds\n"); + robot.lock(); + robot.move(1000); + robot.unlock(); + start.setToNow(); + while (1) + { + robot.lock(); + if (robot.isMoveDone()) + { + printf("directMotionExample: Finished distance\n"); + robot.unlock(); + break; + } + if (start.mSecSince() > 5000) + { + printf("directMotionExample: Distance timed out\n"); + robot.unlock(); + break; + } + robot.unlock(); + ArUtil::sleep(50); + } + printf("directMotionExample: Telling the robot to move backwards one meter, then sleeping 5 seconds\n"); + robot.lock(); + robot.move(-1000); + robot.unlock(); + start.setToNow(); + while (1) + { + robot.lock(); + if (robot.isMoveDone()) + { + printf("directMotionExample: Finished distance\n"); + robot.unlock(); + break; + } + if (start.mSecSince() > 10000) + { + printf("directMotionExample: Distance timed out\n"); + robot.unlock(); + break; + } + robot.unlock(); + ArUtil::sleep(50); + } + printf("directMotionExample: Telling the robot to turn to 180, then sleeping 4 seconds\n"); + robot.lock(); + robot.setHeading(180); + robot.unlock(); + start.setToNow(); + while (1) + { + robot.lock(); + if (robot.isHeadingDone(5)) + { + printf("directMotionExample: Finished turn\n"); + robot.unlock(); + break; + } + if (start.mSecSince() > 5000) + { + printf("directMotionExample: Turn timed out\n"); + robot.unlock(); + break; + } + robot.unlock(); + ArUtil::sleep(100); + } + printf("directMotionExample: Telling the robot to turn to 90, then sleeping 2 seconds\n"); + robot.lock(); + robot.setHeading(90); + robot.unlock(); + start.setToNow(); + while (1) + { + robot.lock(); + if (robot.isHeadingDone(5)) + { + printf("directMotionExample: Finished turn\n"); + robot.unlock(); + break; + } + if (start.mSecSince() > 5000) + { + printf("directMotionExample: turn timed out\n"); + robot.unlock(); + break; + } + robot.unlock(); + ArUtil::sleep(100); + } + printf("directMotionExample: Setting vel2 to 200 mm/sec on both wheels, then sleeping 3 seconds\n"); + robot.lock(); + robot.setVel2(200, 200); + robot.unlock(); + ArUtil::sleep(3000); + printf("directMotionExample: Stopping the robot, then sleeping for 2 seconds\n"); + robot.lock(); + robot.stop(); + robot.unlock(); + ArUtil::sleep(2000); + printf("directMotionExample: Setting velocity to 200 mm/sec then sleeping 3 seconds\n"); + robot.lock(); + robot.setVel(200); + robot.unlock(); + ArUtil::sleep(3000); + printf("directMotionExample: Stopping the robot, then sleeping for 2 seconds\n"); + robot.lock(); + robot.stop(); + robot.unlock(); + ArUtil::sleep(2000); + printf("directMotionExample: Setting vel2 with 0 on left wheel, 200 mm/sec on right, then sleeping 5 seconds\n"); + robot.lock(); + robot.setVel2(0, 200); + robot.unlock(); + ArUtil::sleep(5000); + printf("directMotionExample: Telling the robot to rotate at 50 deg/sec then sleeping 5 seconds\n"); + robot.lock(); + robot.setRotVel(50); + robot.unlock(); + ArUtil::sleep(5000); + printf("directMotionExample: Telling the robot to rotate at -50 deg/sec then sleeping 5 seconds\n"); + robot.lock(); + robot.setRotVel(-50); + robot.unlock(); + ArUtil::sleep(5000); + printf("directMotionExample: Setting vel2 with 0 on both wheels, then sleeping 3 seconds\n"); + robot.lock(); + robot.setVel2(0, 0); + robot.unlock(); + ArUtil::sleep(3000); + printf("directMotionExample: Now having the robot change heading by -125 degrees, then sleeping for 6 seconds\n"); + robot.lock(); + robot.setDeltaHeading(-125); + robot.unlock(); + ArUtil::sleep(6000); + printf("directMotionExample: Now having the robot change heading by 45 degrees, then sleeping for 6 seconds\n"); + robot.lock(); + robot.setDeltaHeading(45); + robot.unlock(); + ArUtil::sleep(6000); + printf("directMotionExample: Setting vel2 with 200 on left wheel, 0 on right wheel, then sleeping 5 seconds\n"); + robot.lock(); + robot.setVel2(200, 0); + robot.unlock(); + ArUtil::sleep(5000); + + printf("directMotionExample: Done, exiting.\n"); + Aria::exit(0); + return 0; +} + diff --git a/Legacy/Aria/examples/dpptuExample-vc2003.vcproj b/Legacy/Aria/examples/dpptuExample-vc2003.vcproj new file mode 100644 index 0000000..9ad20c0 --- /dev/null +++ b/Legacy/Aria/examples/dpptuExample-vc2003.vcproj @@ -0,0 +1,156 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/examples/dpptuExample-vc2008.vcproj b/Legacy/Aria/examples/dpptuExample-vc2008.vcproj new file mode 100644 index 0000000..41ebd1d --- /dev/null +++ b/Legacy/Aria/examples/dpptuExample-vc2008.vcproj @@ -0,0 +1,212 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/examples/dpptuExample-vc2010.vcxproj b/Legacy/Aria/examples/dpptuExample-vc2010.vcxproj new file mode 100644 index 0000000..40c629a --- /dev/null +++ b/Legacy/Aria/examples/dpptuExample-vc2010.vcxproj @@ -0,0 +1,144 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + dpptuExample + {EE1BFE24-2F7E-475C-A2F9-B11065EB6F5C} + + + + Application + false + MultiByte + + + Application + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + .\../bin\ + ../obj/$(ProjectName)-$(Configuration)-VC10/ + false + .\../bin\ + ../obj/$(ProjectName)-$(Configuration)-VC10/ + false + $(ProjectName).DebugVC10 + + + + $(IntDir)$(ProjectName)-$(Configuration)-BuildLog.htm + + + .\../bin/dpptuDemo.tlb + + + + + MaxSpeed + OnlyExplicitInline + ..\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + true + true + + + Level3 + true + + + Default + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + AriaVC10.lib + 1.0 + true + ..\lib;%(AdditionalLibraryDirectories) + false + Console + false + + + MachineX86 + + + + + $(IntDir)$(ProjectName)-$(Configuration)-BuildLog.htm + + + .\../bin/dpptuDemo.tlb + + + + + Disabled + ..\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + true + true + + + true + Level3 + true + + + Default + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + AriaDebugVC10.lib + 1.0 + true + ..\lib;%(AdditionalLibraryDirectories) + false + Console + false + + + MachineX86 + + + + + + + + + \ No newline at end of file diff --git a/Legacy/Aria/examples/dpptuExample.cpp b/Legacy/Aria/examples/dpptuExample.cpp new file mode 100644 index 0000000..1d9cc0b --- /dev/null +++ b/Legacy/Aria/examples/dpptuExample.cpp @@ -0,0 +1,600 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#include "Aria.h" + +/** @example dpptuExample.cpp Shows how to control the Directed Perception + * pan-tilt unit using ArDPPTU class directly. + * + * This program lets you use the keyboard to control the DPPTU. It uses the same acceleration and slew rates for the pan and tilt axes. + * + * It is also possible to specify the type of PTU in program configuration + * (in the ARIA robot parameter files or program command-line arguments) + * instead. For an example of that, see cameraPTZExample.cpp instead. + +Commands: +_________________ + +UP,DOWN -- tilt up/down by one positional increment +LEFT,RIGHT -- pan left/right by one positional increment +SPACE -- perform reset calibration +I -- initialize PTU to default settings +<,> -- increase/decrease the posIncrement by 0.5 degree ++,- -- increase/decrease the speed by 1 degree/sec +A -- awaits the completion of last issued positional command +R -- change pan/tilt movements to relative or absolute movements +Z -- move pan and tilt axes to zero +1 -- move to stored position 1 (-90, 0) +2 -- move to stored position 2 (90, 0) +3 -- move to stored position 3 (0, -45) +4 -- move to stored position 4 (0, 30) +M -- Enter or Exit monitor (continuous scan) mode +H -- Halt all motion +S -- print current variable values +ESC -- quit +*/ + +// If defined, use this computer serial port. If not defined, use first robot +// aux. serial port. Most robots have the DPPTU on COM2 if on Linux and COM4 on +// Windows, if not equipped with other accessories which might require those +// ports (e.g. GPS or Laser). +#define SERIAL_PORT ArUtil::COM4 + + +// Determines type of DPPTU to set internal conversion factors. See enum of +// types in ArDPPTU class for possible values. +//#define PTU_TYPE ArDPPTU::PANTILT_PTUD46 + +// by how much the < and > keys change the position command increment in this +// example +#define POS_INC_ADJUSTMENT 1 + +/* + This class is the core of this demo, it adds itself to the robot given + as a user task, and contains key handler callbacks to control the PTU. +*/ +class KeyPTU +{ +public: + // constructor + KeyPTU(ArRobot *robot); + ~KeyPTU(void); + + void up(void); + void down(void); + void left(void); + void right(void); + void space(void); + void i(void); + void plus(void); + void minus(void); + void greater(void); + void less(void); + void question(void); + void status(void); + void a(void); + void m(void); + void h(void); + void r(void); + void gotoPos(double p, double t); + + // the callback function + void drive(void); + +protected: + int myPanValPTU; + int myTiltValPTU; + + int myDesiredPanPos; + int myDesiredTiltPos; + int mySlew; + int myPosIncrement; + int mySlewIncrement; + + int POS_INCREMENT_ADJUSTMENT; + + bool myMonitor; + bool myReset; + bool myInit; + bool myAbsolute; + + ArFunctorC myUpCB; + ArFunctorC myDownCB; + ArFunctorC myLeftCB; + ArFunctorC myRightCB; + ArFunctorC mySpaceCB; + ArFunctorC myICB; + ArFunctorC myPlusCB; + ArFunctorC myMinusCB; + ArFunctorC myGreaterCB; + ArFunctorC myLessCB; + ArFunctorC myQuestionCB; + ArFunctorC mySCB; + ArFunctorC myACB; + ArFunctorC myMCB; + ArFunctorC myHCB; + ArFunctorC myRCB; + ArFunctor2C myPos0CB; + ArFunctor2C myPos1CB; + ArFunctor2C myPos2CB; + ArFunctor2C myPos3CB; + ArFunctor2C myPos4CB; + + + // the PTU + ArDPPTU myPTU; + + + // whether the PTU has been inited or not + bool myPTUInited; + // pointer to the robot + ArRobot *myRobot; + // callback for the drive function + ArFunctorC myDriveCB; + + ArSerialConnection *mySerialConnection; +}; + +/* + Constructor, sets the robot pointer, and some initial values, also note the + use of constructor chaining on myPTU and myDriveCB. +*/ +KeyPTU::KeyPTU(ArRobot *robot) : + myUpCB(this, &KeyPTU::up), + myDownCB(this, &KeyPTU::down), + myLeftCB(this, &KeyPTU::left), + myRightCB(this, &KeyPTU::right), + mySpaceCB(this, &KeyPTU::space), + myICB(this, &KeyPTU::i), + myPlusCB(this, &KeyPTU::plus), + myMinusCB(this, &KeyPTU::minus), + myGreaterCB(this, &KeyPTU::greater), + myLessCB(this, &KeyPTU::less), + myQuestionCB(this, &KeyPTU::question), + mySCB(this, &KeyPTU::status), + myACB(this, &KeyPTU::a), + myMCB(this, &KeyPTU::m), + myHCB(this, &KeyPTU::h), + myRCB(this, &KeyPTU::r), + myPos0CB(this, &KeyPTU::gotoPos, 0, 0), + myPos1CB(this, &KeyPTU::gotoPos, -90.0, 0.0), + myPos2CB(this, &KeyPTU::gotoPos, 90.0, 0.0), + myPos3CB(this, &KeyPTU::gotoPos, 0.0, -45.0), + myPos4CB(this, &KeyPTU::gotoPos, 0.0, 30.0), + myPTU(robot), + myDriveCB(this, &KeyPTU::drive), + mySerialConnection(NULL) +{ +#ifdef SERIAL_PORT + mySerialConnection = new ArSerialConnection; + ArLog::log(ArLog::Normal, "dpptuExample: connecting to DPPTU over computer serial port %s.", SERIAL_PORT); + if(mySerialConnection->open(SERIAL_PORT) != 0) + { + ArLog::log(ArLog::Terse, "dpptuExample: Error: Could not open computer serial port %s for DPPTU!", SERIAL_PORT); + Aria::exit(5); + } + myPTU.setDeviceConnection(mySerialConnection); +#endif + + // set the robot pointer and add the KeyPTU as user task + ArKeyHandler *keyHandler; + myRobot = robot; + myRobot->addSensorInterpTask("KeyPTU", 50, &myDriveCB); + + if ((keyHandler = Aria::getKeyHandler()) == NULL) + { + keyHandler = new ArKeyHandler; + Aria::setKeyHandler(keyHandler); + myRobot->attachKeyHandler(keyHandler); + } + + if (!keyHandler->addKeyHandler(ArKeyHandler::UP, &myUpCB)) + ArLog::log(ArLog::Terse, "The key handler already has a key for up, keydrive will not work correctly."); + if (!keyHandler->addKeyHandler(ArKeyHandler::DOWN, &myDownCB)) + ArLog::log(ArLog::Terse, "The key handler already has a key for down, keydrive will not work correctly."); + if (!keyHandler->addKeyHandler(ArKeyHandler::LEFT, &myLeftCB)) + ArLog::log(ArLog::Terse, +"The key handler already has a key for left, keydrive will not work correctly."); + if (!keyHandler->addKeyHandler(ArKeyHandler::RIGHT, &myRightCB)) + ArLog::log(ArLog::Terse, +"The key handler already has a key for right, keydrive will not work correctly."); + if (!keyHandler->addKeyHandler(ArKeyHandler::SPACE, &mySpaceCB)) + ArLog::log(ArLog::Terse, +"The key handler already has a key for space, keydrive will not work correctly."); + if (!keyHandler->addKeyHandler('i', &myICB)) + ArLog::log(ArLog::Terse, +"The key handler already has a key for 'i', keydrive will not work correctly."); + if (!keyHandler->addKeyHandler('+', &myPlusCB)) + ArLog::log(ArLog::Terse, +"The key handler already has a key for '+', keydrive will not work correctly."); + if (!keyHandler->addKeyHandler('-', &myMinusCB)) + ArLog::log(ArLog::Terse, +"The key handler already has a key for '-', keydrive will not work correctly."); + if (!keyHandler->addKeyHandler('>', &myGreaterCB)) + ArLog::log(ArLog::Terse, +"The key handler already has a key for '>', keydrive will not work correctly."); + if (!keyHandler->addKeyHandler('<', &myLessCB)) + ArLog::log(ArLog::Terse, +"The key handler already has a key for '<', keydrive will not work correctly."); + if (!keyHandler->addKeyHandler('?', &myQuestionCB)) + ArLog::log(ArLog::Terse, +"The key handler already has a key for '?', keydrive will not work correctly."); + if (!keyHandler->addKeyHandler('s', &mySCB)) + ArLog::log(ArLog::Terse, +"The key handler already has a key for 'S', keydrive will not work correctly."); + if (!keyHandler->addKeyHandler('a', &myACB)) + ArLog::log(ArLog::Terse, +"The key handler already has a key for 'A', keydrive will not work correctly."); + if (!keyHandler->addKeyHandler('z', &myPos0CB)) + ArLog::log(ArLog::Terse, +"The key handler already has a key for 'Z', keydrive will not work correctly."); + if (!keyHandler->addKeyHandler('m', &myMCB)) + ArLog::log(ArLog::Terse, +"The key handler already has a key for 'M', keydrive will not work correctly."); + if (!keyHandler->addKeyHandler('h', &myHCB)) + ArLog::log(ArLog::Terse, +"The key handler already has a key for 'H', keydrive will not work correctly."); + if (!keyHandler->addKeyHandler('r', &myRCB)) + ArLog::log(ArLog::Terse, +"The key handler already has a key for 'R', keydrive will not work correctly."); + + + if(!keyHandler->addKeyHandler('Z', &myPos0CB)) + ArLog::log(ArLog::Terse, +"The key handler already has a key for 'Z', keydrive will not work correctly."); + + if(!keyHandler->addKeyHandler('1', &myPos1CB)) + ArLog::log(ArLog::Terse, +"The key handler already has a key for '1', keydrive will not work correctly."); + + if(!keyHandler->addKeyHandler('2', &myPos2CB)) + ArLog::log(ArLog::Terse, +"The key handler already has a key for '2', keydrive will not work correctly."); + + if(!keyHandler->addKeyHandler('3', &myPos3CB)) + ArLog::log(ArLog::Terse, +"The key handler already has a key for '3', keydrive will not work correctly."); + + if(!keyHandler->addKeyHandler('4', &myPos4CB)) + ArLog::log(ArLog::Terse, +"The key handler already has a key for '4', keydrive will not work correctly."); + + // initialize some variables + myReset = false; + myInit = true; + myDesiredPanPos = 0; + myDesiredTiltPos = 0; + myPosIncrement = 1; + mySlewIncrement = 1; + myPTUInited = false; + myMonitor = false; + +} + +KeyPTU::~KeyPTU() +{ + if(mySerialConnection) + { + myPTU.setDeviceConnection(NULL); + delete mySerialConnection; + } +} + + + +void KeyPTU::left(void) +{ + myDesiredPanPos += myPosIncrement; + + if (myDesiredPanPos > myPTU.getMaxPosPan()) + myDesiredPanPos = myPTU.getMaxPosPan(); +} + +void KeyPTU::right(void) +{ + myDesiredPanPos -= myPosIncrement; + + if (myDesiredPanPos < myPTU.getMaxNegPan()) + myDesiredPanPos = myPTU.getMaxNegPan(); +} + +void KeyPTU::up(void) +{ + myDesiredTiltPos += myPosIncrement; + + if (myDesiredTiltPos > myPTU.getMaxPosTilt()) + myDesiredTiltPos = myPTU.getMaxPosTilt(); +} + +void KeyPTU::down(void) +{ + myDesiredTiltPos -= myPosIncrement; + + if (myDesiredTiltPos < myPTU.getMaxNegTilt()) + myDesiredTiltPos = myPTU.getMaxNegTilt(); +} + +void KeyPTU::space(void) +{ + myReset = true; +} + +void KeyPTU::i(void) +{ + myInit = true; +} + +void KeyPTU::plus(void) +{ + mySlew += mySlewIncrement; + + if (mySlew > myPTU.getMaxPanSlew()) + mySlew = myPTU.getMaxPanSlew(); + + status(); +} + +void KeyPTU::minus(void) +{ + mySlew -= mySlewIncrement; + + if (mySlew < myPTU.getMinPanSlew()) + mySlew = myPTU.getMinPanSlew(); + + status(); +} + +void KeyPTU::greater(void) +{ + myPosIncrement += POS_INCREMENT_ADJUSTMENT; + + if (myPosIncrement > myPTU.getMaxPosPan()) + myPosIncrement = myPTU.getMaxPosPan(); + + status(); +} + +void KeyPTU::less(void) +{ + myPosIncrement -= POS_INCREMENT_ADJUSTMENT; + + if (myPosIncrement < 0) + myPosIncrement = 0; + + status(); +} + +void KeyPTU::a(void) +{ + myPTU.awaitExec(); + ArLog::log(ArLog::Normal, "AwaitExecution command sent"); +} + +void KeyPTU::gotoPos(double p, double t) +{ + myDesiredPanPos = p; + myDesiredTiltPos = t; + status(); +} + +void KeyPTU::question(void) +{ + ArLog::log(ArLog::Normal, "\r\nCommands:\r\n_________________\r\n"); + ArLog::log(ArLog::Normal, "UP,DOWN -- tilt up/down by one positional increment"); + ArLog::log(ArLog::Normal, "LEFT,RIGHT -- pan left/right by one positional increment"); + ArLog::log(ArLog::Normal, "SPACE -- perform reset calibration"); + ArLog::log(ArLog::Normal, "I -- initialize PTU to default settings"); + ArLog::log(ArLog::Normal, "<,> -- increase/decrease the posIncrement by %f degree(s)", POS_INC_ADJUSTMENT); + ArLog::log(ArLog::Normal, "+,- -- increase/decrease the speed by 1 degree/sec"); + ArLog::log(ArLog::Normal, "A -- awaits the completion of last issued positional command"); + ArLog::log(ArLog::Normal, "R -- change pan/tilt movements to relative or absolute movements"); + ArLog::log(ArLog::Normal, "Z -- move pan and tilt axes to zero"); + ArLog::log(ArLog::Normal, "1 -- move to stored position 1 (-90, 0)"); + ArLog::log(ArLog::Normal, "2 -- move to stored position 2 (90, 0)"); + ArLog::log(ArLog::Normal, "3 -- move to stored position 3 (0, -45)"); + ArLog::log(ArLog::Normal, "4 -- move to stored position 4 (0, 30)"); + ArLog::log(ArLog::Normal, "M -- Enter or Exit monitor (continuous scan) mode"); + ArLog::log(ArLog::Normal, "H -- Halt all motion"); + ArLog::log(ArLog::Normal, "S -- print current variable values"); + ArLog::log(ArLog::Normal, "ESC -- exit program"); + ArLog::log(ArLog::Normal, "\r\n"); +} + +void KeyPTU::status(void) +{ + ArLog::log(ArLog::Normal, "\r\nStatus:\r\n_________________\r\n"); + ArLog::log(ArLog::Normal, "Last Pan Command = %.1f deg", myPTU.getLastPanRequest()); + ArLog::log(ArLog::Normal, "Last Tilt Command = %.1f deg", myPTU.getLastTiltRequest()); + ArLog::log(ArLog::Normal, "Current Pan Position = %.1f deg", myPTU.getPan()); + ArLog::log(ArLog::Normal, "Current Tilt Position = %.1f deg", myPTU.getTilt()); + ArLog::log(ArLog::Normal, "Pan Slew Rate = %d deg/sec", myPTU.getPanSlew()); + ArLog::log(ArLog::Normal, "Tilt Slew Rate = %d deg/sec", myPTU.getTiltSlew()); + ArLog::log(ArLog::Normal, "Position Increment = %d deg", myPosIncrement); + if (myAbsolute) + ArLog::log(ArLog::Normal, "Positional-movements using absolute commands"); + else + ArLog::log(ArLog::Normal, "Positional-movements using relative commands"); + ArLog::log(ArLog::Normal, "\r\n"); +} + +void KeyPTU::m(void) +{ + if (!myMonitor) + { + ArLog::log(ArLog::Normal, "Entering Monitor mode - hit 'M' to disable"); + myMonitor = true; + myPTU.initMon(-60,60,30,-30); + } + else + { + myPTU.blank(); //Blank packet exits monitor mode + myMonitor = false; + } +} + +void KeyPTU::h(void) +{ + myPTU.haltAll(); +} + +void KeyPTU::r(void) +{ + if (!myAbsolute) + { + myAbsolute = true; + } + else + { + myAbsolute = false; + } + status(); +} + + +// the important function +void KeyPTU::drive(void) +{ + + // if the PTU isn't initialized, initialize it here... it has to be + // done here instead of above because it needs to be done when the + // robot is connected + if (!myPTUInited && myRobot->isConnected()) + { + ArLog::log(ArLog::Normal, "Initializing ArDPPTU..."); + myPTU.init(); + ArLog::log(ArLog::Normal, "Resetting PTU and performing self-calibration..."); + myPTU.resetCalib(); + myPTU.awaitExec(); // DPPTU will wait for self-calibration to end before executing the following commands (though they will still be sent) + mySlew = myPTU.getPanSlew(); //uses only pan slew rate + myPTU.awaitExec(); + myPTUInited = true; + myInit = false; + myAbsolute = true; + } + + if (myInit == true) // User hit initialization key + { + ArLog::log(ArLog::Normal, "Initializing PTU..."); + myPTU.init(); + myInit = false; + myDesiredPanPos = myPTU.getPan(); + myDesiredTiltPos = myPTU.getTilt(); + mySlew = myPTU.getPanSlew(); //uses only pan slew rate + myReset = false; + } + + if (myReset == true) // User hit reset key + { + ArLog::log(ArLog::Normal, "Resetting PTU and performing self-calibration..."); + myPTU.resetCalib(); + myPTU.awaitExec(); + myDesiredPanPos = myPTU.getPan(); + myDesiredTiltPos = myPTU.getTilt(); + myReset = false; + } + else // User did nothing, or hit a key that changed myDesiredPanPos, myDesiredTiltPos, or mySlew (so request PTU to move if those changed since last request) + { + + // Some PTUs can determine their current position (with encoders, etc) and return that. + // canGetRealPanTilt() will return true in this case, and getPan() and + // getTilt() will return those received values. Otherwise, getPan() and + // getTilt() return the last commanded values. getLastPanRequest() and + // getLastTiltRequest() will always return the last commanded values sent by + // ArDPPTU (so in the case that canGetRealPanTilt() is false, getPan() and + // getTilt() return the same pair of values as getLastPanRequest() and + // getLastTiltRequest(). ArDPPTU::canGetRealPanTilt() is initialally false, + // but once the first set of pan and tilt positions is read back from the + // PTU device, it becomes true. + if(myPTU.canGetRealPanTilt()) + printf("Position (%.1f deg, %.1f deg) [Incr. %d deg] Press ? for help \r", myPTU.getPan(), myPTU.getTilt(), myPosIncrement); + else + printf("Requested (%.1f deg, %.1f deg) [Incr. %d deg] Press ? for help \r", myPTU.getPan(), myPTU.getTilt(), myPosIncrement); + + if (myDesiredPanPos != myPTU.getLastPanRequest()) + { + if (myAbsolute) + myPTU.pan(myDesiredPanPos); + else + myPTU.panRel(myDesiredPanPos - myPTU.getPan()); + } + + if (myDesiredTiltPos != myPTU.getLastTiltRequest()) + { + if (myAbsolute) + myPTU.tilt(myDesiredTiltPos); + else + myPTU.tiltRel(myDesiredTiltPos - myPTU.getTilt()); + } + + if (mySlew != myPTU.getPanSlew()) + { + myPTU.panSlew(mySlew); + myPTU.tiltSlew(mySlew); + } + + } + +} + +int main(int argc, char **argv) +{ + Aria::init(); + ArArgumentParser parser(&argc, argv); + parser.loadDefaultArguments(); + ArRobot robot; + ArRobotConnector robotConnector(&parser, &robot); + if(!robotConnector.connectRobot()) + { + ArLog::log(ArLog::Terse, "dpptuExample: Could not connect to the robot."); + if(parser.checkHelpAndWarnUnparsed()) + { + Aria::logOptions(); + Aria::exit(1); + } + } + if (!Aria::parseArgs() || !parser.checkHelpAndWarnUnparsed()) + { + Aria::logOptions(); + Aria::exit(1); + } + ArLog::log(ArLog::Normal, "dpptuExample: Connected to robot."); + + robot.runAsync(true); + + // an object for keyboard control, class defined above, this also adds itself as a user task + KeyPTU ptu(&robot); + + + // turn off the sonar + robot.comInt(ArCommands::SONAR, 0); + + printf("Press '?' for available commands\r\n"); + + // run, if we lose connection to the robot, exit + robot.waitForRunExit(); + + Aria::exit(0); +} + diff --git a/Legacy/Aria/examples/functorExample-vc2003.vcproj b/Legacy/Aria/examples/functorExample-vc2003.vcproj new file mode 100644 index 0000000..7351782 --- /dev/null +++ b/Legacy/Aria/examples/functorExample-vc2003.vcproj @@ -0,0 +1,156 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/examples/functorExample-vc2008.vcproj b/Legacy/Aria/examples/functorExample-vc2008.vcproj new file mode 100644 index 0000000..fcbac63 --- /dev/null +++ b/Legacy/Aria/examples/functorExample-vc2008.vcproj @@ -0,0 +1,212 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/examples/functorExample-vc2010.vcxproj b/Legacy/Aria/examples/functorExample-vc2010.vcxproj new file mode 100644 index 0000000..5220523 --- /dev/null +++ b/Legacy/Aria/examples/functorExample-vc2010.vcxproj @@ -0,0 +1,144 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + functorExample + {4AD6E4D3-7C44-4697-8794-BFBA43BFE13D} + + + + Application + false + MultiByte + + + Application + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + .\../bin\ + ../obj/$(ProjectName)-$(Configuration)-VC10/ + false + .\../bin\ + ../obj/$(ProjectName)-$(Configuration)-VC10/ + false + $(ProjectName).DebugVC10 + + + + $(IntDir)$(ProjectName)-$(Configuration)-BuildLog.htm + + + .\../bin/functor.tlb + + + + + Disabled + ..\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + true + true + + + true + Level3 + true + + + Default + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + AriaDebugVC10.lib + 1.0 + true + ..\lib;%(AdditionalLibraryDirectories) + false + Console + false + + + MachineX86 + + + + + $(IntDir)$(ProjectName)-$(Configuration)-BuildLog.htm + + + .\../bin/functor.tlb + + + + + MaxSpeed + OnlyExplicitInline + ..\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + true + true + + + Level3 + true + + + Default + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + AriaVC10.lib + 1.0 + true + ..\lib;%(AdditionalLibraryDirectories) + false + Console + false + + + MachineX86 + + + + + + + + + \ No newline at end of file diff --git a/Legacy/Aria/examples/functorExample.cpp b/Legacy/Aria/examples/functorExample.cpp new file mode 100644 index 0000000..0130532 --- /dev/null +++ b/Legacy/Aria/examples/functorExample.cpp @@ -0,0 +1,162 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ + + +#include +#include "Aria.h" + + +/** @example functorExample.cpp Illustrates the use of functors + * + * @sa @ref functors in the ARIA overview + */ + +/* + This is a class that has some callback methods. Functors which refer to these + callbacks will be passed to the DriverClass. +*/ +class CallbackContainer +{ +public: + + void callback1(); + void callback2(int i); + bool callback3(const char *str); +}; + +void CallbackContainer::callback1() +{ + printf("CallbackContainer::callback1 called.\n"); +} + +void CallbackContainer::callback2(int i) +{ + printf("CallbackContainer::callback2 called with argument of '%d'\n", i); +} + +bool CallbackContainer::callback3(const char *str) +{ + printf("CallbackContainer::callback3 called with argument of '%s'.\n", str); + return(true); +} + +/* + * Functors can also invoke global functions. + */ + +void globalCallback() +{ + printf("globalCallback() called.\n"); +} + + +/* + This is a "driver" class. It takes three functors of different types and + will invoke the three functors. This is a typical use of + functors: to pass information or event notifications between loosely + coupled objects. +*/ +class DriverClass +{ +public: + + void invokeFunctors(); + + void setCallback1(ArFunctor *func) {myFunc1=func;} + void setCallback2(ArFunctor1 *func) {myFunc2=func;} + void setCallback3(ArRetFunctor1 *func) {myFunc3=func;} + + +protected: + + ArFunctor *myFunc1; + ArFunctor1 *myFunc2; + ArRetFunctor1 *myFunc3; +}; + +void DriverClass::invokeFunctors() +{ + bool ret; + + printf("Invoking functor1... "); + myFunc1->invoke(); + + printf("Invoking functor2... "); + myFunc2->invoke(23); + + + /* + For functors with return values, use invorkeR() instead of invoke() + to get the return value. The invoke() function can also be used to invoke + the functor, but the return value is lost. (And is a possible source + of memory leaks if you were supposed to free a pointer returned.) + */ + printf("Invoking functor3... "); + ret=myFunc3->invokeR("This is a string argument"); + if (ret) + printf("\t-> functor3 returned 'true'\n"); + else + printf("\t-> functor3 returned 'false'\n"); +} + +int main() +{ + CallbackContainer cb; + DriverClass driver; + + ArFunctorC functor1(cb, &CallbackContainer::callback1); + ArFunctor1C functor2(cb, &CallbackContainer::callback2); + ArRetFunctor1C + functor3(cb, &CallbackContainer::callback3); + + driver.setCallback1(&functor1); + driver.setCallback2(&functor2); + driver.setCallback3(&functor3); + + driver.invokeFunctors(); + + /* You can make functors that target global functions too. */ + ArGlobalFunctor globalFunctor(&globalCallback); + printf("Invoking globalFunctor... "); + globalFunctor.invoke(); + + /* You can also include the values of arguments in an ArFunctor object, if you + * want to use the same value in every invocation of the functor. + */ + ArFunctor1C functor4(cb, &CallbackContainer::callback2, 42); + printf("Invoking functor with constant argument... "); + functor4.invoke(); + + /* Functors can be downcast to parent interface classes, as long as their invocation + * does not require arguments. + */ + ArFunctor* baseFunctor = &functor4; + printf("Invoking downcast functor... "); + baseFunctor->invoke(); + + + return(0); +} diff --git a/Legacy/Aria/examples/gotoActionExample-vc2003.vcproj b/Legacy/Aria/examples/gotoActionExample-vc2003.vcproj new file mode 100644 index 0000000..56e335e --- /dev/null +++ b/Legacy/Aria/examples/gotoActionExample-vc2003.vcproj @@ -0,0 +1,156 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/examples/gotoActionExample-vc2008.vcproj b/Legacy/Aria/examples/gotoActionExample-vc2008.vcproj new file mode 100644 index 0000000..9785eb7 --- /dev/null +++ b/Legacy/Aria/examples/gotoActionExample-vc2008.vcproj @@ -0,0 +1,212 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/examples/gotoActionExample-vc2010.vcxproj b/Legacy/Aria/examples/gotoActionExample-vc2010.vcxproj new file mode 100644 index 0000000..aa04c41 --- /dev/null +++ b/Legacy/Aria/examples/gotoActionExample-vc2010.vcxproj @@ -0,0 +1,144 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + gotoActionExample + {FAD55BE4-E1C6-436D-BC7D-B0674FB8C067} + + + + Application + false + MultiByte + + + Application + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + .\../bin\ + ../obj/$(ProjectName)-$(Configuration)-VC10/ + false + .\../bin\ + ../obj/$(ProjectName)-$(Configuration)-VC10/ + false + $(ProjectName).DebugVC10 + + + + $(IntDir)$(ProjectName)-$(Configuration)-BuildLog.htm + + + .\../bin/goto.tlb + + + + + MaxSpeed + OnlyExplicitInline + ..\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + true + true + + + Level3 + true + + + Default + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + AriaVC10.lib + 1.0 + true + ..\lib;%(AdditionalLibraryDirectories) + false + Console + false + + + MachineX86 + + + + + $(IntDir)$(ProjectName)-$(Configuration)-BuildLog.htm + + + .\../bin/goto.tlb + + + + + Disabled + ..\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + true + true + + + true + Level3 + true + + + Default + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + AriaDebugVC10.lib + 1.0 + true + ..\lib;%(AdditionalLibraryDirectories) + true + Console + false + + + MachineX86 + + + + + + + + + \ No newline at end of file diff --git a/Legacy/Aria/examples/gotoActionExample.cpp b/Legacy/Aria/examples/gotoActionExample.cpp new file mode 100644 index 0000000..532a295 --- /dev/null +++ b/Legacy/Aria/examples/gotoActionExample.cpp @@ -0,0 +1,143 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#include "Aria.h" + +/** @example gotoActionExample.cpp Uses ArActionGoto to drive the robot in a square + + This program will make the robot drive in a 2.5x2.5 meter square by + setting each corner in turn as the goal for an ArActionGoto action. + It also uses speed limiting actions to avoid collisions. After some + time, it cancels the goal (and the robot stops due to a stopping action) + and exits. + + Press escape to shut down Aria and exit. +*/ + +int main(int argc, char **argv) +{ + Aria::init(); + ArArgumentParser parser(&argc, argv); + parser.loadDefaultArguments(); + ArSimpleConnector simpleConnector(&parser); + ArRobot robot; + ArSonarDevice sonar; + ArAnalogGyro gyro(&robot); + robot.addRangeDevice(&sonar); + + // Make a key handler, so that escape will shut down the program + // cleanly + ArKeyHandler keyHandler; + Aria::setKeyHandler(&keyHandler); + robot.attachKeyHandler(&keyHandler); + printf("You may press escape to exit\n"); + + // Collision avoidance actions at higher priority + ArActionLimiterForwards limiterAction("speed limiter near", 300, 600, 250); + ArActionLimiterForwards limiterFarAction("speed limiter far", 300, 1100, 400); + ArActionLimiterTableSensor tableLimiterAction; + robot.addAction(&tableLimiterAction, 100); + robot.addAction(&limiterAction, 95); + robot.addAction(&limiterFarAction, 90); + + // Goto action at lower priority + ArActionGoto gotoPoseAction("goto"); + robot.addAction(&gotoPoseAction, 50); + + // Stop action at lower priority, so the robot stops if it has no goal + ArActionStop stopAction("stop"); + robot.addAction(&stopAction, 40); + + // Parse all command line arguments + if (!Aria::parseArgs() || !parser.checkHelpAndWarnUnparsed()) + { + Aria::logOptions(); + Aria::exit(1); + return 1; + } + + // Connect to the robot + if (!simpleConnector.connectRobot(&robot)) + { + printf("Could not connect to robot... exiting\n"); + Aria::exit(1); + return 1; + } + robot.runAsync(true); + + // turn on the motors, turn off amigobot sounds + robot.enableMotors(); + robot.comInt(ArCommands::SOUNDTOG, 0); + + const int duration = 30000; //msec + ArLog::log(ArLog::Normal, "Going to four goals in turn for %d seconds, then cancelling goal and exiting.", duration/1000); + + bool first = true; + int goalNum = 0; + ArTime start; + start.setToNow(); + while (Aria::getRunning()) + { + robot.lock(); + + // Choose a new goal if this is the first loop iteration, or if we + // achieved the previous goal. + if (first || gotoPoseAction.haveAchievedGoal()) + { + first = false; + goalNum++; + if (goalNum > 4) + goalNum = 1; // start again at goal #1 + + // set our positions for the different goals + if (goalNum == 1) + gotoPoseAction.setGoal(ArPose(2500, 0)); + else if (goalNum == 2) + gotoPoseAction.setGoal(ArPose(2500, 2500)); + else if (goalNum == 3) + gotoPoseAction.setGoal(ArPose(0, 2500)); + else if (goalNum == 4) + gotoPoseAction.setGoal(ArPose(0, 0)); + + ArLog::log(ArLog::Normal, "Going to next goal at %.0f %.0f", + gotoPoseAction.getGoal().getX(), gotoPoseAction.getGoal().getY()); + } + + if(start.mSecSince() >= duration) { + ArLog::log(ArLog::Normal, "%d seconds have elapsed. Cancelling current goal, waiting 3 seconds, and exiting.", duration/1000); + gotoPoseAction.cancelGoal(); + robot.unlock(); + ArUtil::sleep(3000); + break; + } + + robot.unlock(); + ArUtil::sleep(100); + } + + // Robot disconnected or time elapsed, shut down + Aria::exit(0); + return 0; +} diff --git a/Legacy/Aria/examples/gpsExample-vc2003.vcproj b/Legacy/Aria/examples/gpsExample-vc2003.vcproj new file mode 100644 index 0000000..3b5a40f --- /dev/null +++ b/Legacy/Aria/examples/gpsExample-vc2003.vcproj @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/examples/gpsExample-vc2008.vcproj b/Legacy/Aria/examples/gpsExample-vc2008.vcproj new file mode 100644 index 0000000..b5a0fb0 --- /dev/null +++ b/Legacy/Aria/examples/gpsExample-vc2008.vcproj @@ -0,0 +1,184 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/examples/gpsExample-vc2010.vcxproj b/Legacy/Aria/examples/gpsExample-vc2010.vcxproj new file mode 100644 index 0000000..29d4047 --- /dev/null +++ b/Legacy/Aria/examples/gpsExample-vc2010.vcxproj @@ -0,0 +1,106 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + gpsExample + {39B4C09E-E4E3-457F-B96C-B85D03C93B55} + gpsExample + ManagedCProj + + + + Application + MultiByte + false + + + Application + MultiByte + false + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + ../bin\ + ../obj/$(ProjectName)-$(Configuration)-VC10/ + true + ../bin\ + ../obj/$(ProjectName)-$(Configuration)-VC10/ + false + $(ProjectName).DebugVC10 + + + + $(IntDir)$(ProjectName)-$(Configuration)-BuildLog.htm + + + Disabled + ..\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;%(PreprocessorDefinitions) + false + Default + MultiThreadedDebugDLL + true + Level3 + ProgramDatabase + + + AriaDebugVC10.lib + $(OutDir)$(ProjectName).exe + ..\lib;%(AdditionalLibraryDirectories) + true + true + false + + + + + + + $(IntDir)$(ProjectName)-$(Configuration)-BuildLog.htm + + + ..\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;%(PreprocessorDefinitions) + false + MultiThreaded + Level3 + ProgramDatabase + + + $(OutDir)$(ProjectName).exe + true + false + + + AriaVC10.lib + ..\lib;%(AdditionalLibraryDirectories) + + + + + + + + + \ No newline at end of file diff --git a/Legacy/Aria/examples/gpsExample.cpp b/Legacy/Aria/examples/gpsExample.cpp new file mode 100644 index 0000000..810a3d3 --- /dev/null +++ b/Legacy/Aria/examples/gpsExample.cpp @@ -0,0 +1,136 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ + +/** @example gpsExample.cpp Example program to connect to a GPS and read and + * display data on the terminal. + * Also tries to connect to a TCM compass through the computer serial port, and + * use that to set the ArGPS compass data. + */ + +#include "Aria.h" +#include "ArGPS.h" +#include "ArGPSConnector.h" +#include "ArTrimbleGPS.h" +#include "ArTCMCompassDirect.h" +#include + +int main(int argc, char** argv) +{ + Aria::init(); + ArLog::init(ArLog::StdErr, ArLog::Normal); + + ArArgumentParser argParser(&argc, argv); + argParser.loadDefaultArguments(); + ArSimpleConnector connector(&argParser); + ArGPSConnector gpsConnector(&argParser); + + if(!Aria::parseArgs() || !argParser.checkHelpAndWarnUnparsed()) + { + Aria::logOptions(); + ArLog::log(ArLog::Terse, "gpsExample options:\n -printTable Print data to standard output in regular columns rather than a refreshing terminal display, and print more digits of precision"); + return 1; + } + + // Try connecting to robot + ArRobot robot; + if(!connector.connectRobot(&robot)) + { + ArLog::log(ArLog::Terse, "gpsExample: Warning: Could not connect to robot. Will not be able to switch GPS power on, or load GPS options from this robot's parameter file."); + } + else + { + ArLog::log(ArLog::Normal, "gpsExample: Connected to robot."); + robot.runAsync(true); + } + + // check command line arguments for -printTable + bool printTable = argParser.checkArgument("printTable"); + + // On the Seekur, power to the GPS receiver is switched on by this command. + // (A third argument of 0 would turn it off). On other robots this command is + // ignored. + robot.com2Bytes(116, 6, 1); + + // Try connecting to a GPS. We pass the robot pointetr to the connector so it + // can check the robot parameters for this robot type for default values for + // GPS device connection information (receiver type, serial port, etc.) + ArLog::log(ArLog::Normal, "gpsExample: Connecting to GPS, it may take a few seconds..."); + ArGPS *gps = gpsConnector.createGPS(&robot); + if(!gps || !gps->connect()) + { + ArLog::log(ArLog::Terse, "gpsExample: Error connecting to GPS device. Try -gpsType, -gpsPort, and/or -gpsBaud command-line arguments. Use -help for help."); + return -1; + } + + if(gpsConnector.getGPSType() == ArGPSConnector::Simulator) + { + ArLog::log(ArLog::Normal, "gpsExample: GPS is a simulator. Setting dummy position."); + (dynamic_cast(gps))->setDummyPosition(42.80709, -71.579047, 100); + } + + + ArLog::log(ArLog::Normal, "gpsExample: Reading data..."); + ArTime lastReadTime; + if(printTable) + gps->printDataLabelsHeader(); + while(true) + { + int r = gps->read(); + if(r & ArGPS::ReadError) + { + ArLog::log(ArLog::Terse, "gpsExample: Warning: error reading GPS data."); + ArUtil::sleep(1000); + continue; + } + + + if(r & ArGPS::ReadUpdated) + { + if(printTable) + { + gps->printData(false); + printf("\n"); + } + else + { + gps->printData(); + printf("\r"); + } + fflush(stdout); + ArUtil::sleep(500); + lastReadTime.setToNow(); + continue; + } else { + if(lastReadTime.secSince() >= 5) { + ArLog::log(ArLog::Terse, "gpsExample: Warning: haven't recieved any data from GPS for more than 5 seconds!"); + } + ArUtil::sleep(1000); + continue; + } + + } + return 0; +} diff --git a/Legacy/Aria/examples/gpsRobotTaskExample.cpp b/Legacy/Aria/examples/gpsRobotTaskExample.cpp new file mode 100644 index 0000000..94fe59f --- /dev/null +++ b/Legacy/Aria/examples/gpsRobotTaskExample.cpp @@ -0,0 +1,199 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ + + +#include "Aria.h" +#include "ArGPS.h" +#include "ArGPSConnector.h" + +#include + + +/** @example gpsRobotTaskExample.cpp Connects to both robot and GPS, allows + * teleoperation, and prints robot position and GPS data. + */ + + +/* + * This class encapsulates an ArRobot sensor interpretation task that prints the + * last set of GPS data along with a local timestamp and current robot pose to + * standard output. + * + * This class also contains a mutex, which it locks during the task (while + * accessing the ArGPS object). If another thread is also accessing the GPS, + * you can lock this mutex. + */ +class GPSLogTask { + +public: + GPSLogTask(ArRobot *robot, ArGPS *gps, ArJoyHandler *joy = NULL) : + myRobot(robot), + myGPS(gps), + myTaskFunctor(this, &GPSLogTask::doTask), + myJoyHandler(joy), + myButtonDown(false) + { + myRobot->addSensorInterpTask("GPS", ArListPos::LAST, &myTaskFunctor); + puts("RobotX\tRobotY\tRobotTh\tRobotVel\tRobotRotVel\tRobotLatVel\tLatitude\tLongitude\tAltitude\tSpeed\tGPSTimeSec\tGPSTimeMSec\tFixType\tNumSats\tPDOP\tHDOP\tVDOP\tGPSDataReceived"); + } + + void lock() { myMutex.lock(); } + void unlock() { myMutex.unlock(); } + +protected: + + void doTask() + { + // print a mark if a joystick button is pressed (other than 1, which is + // needed to drive) + if(myJoyHandler) + { + for(unsigned int b = 2; b <= myJoyHandler->getNumButtons(); ++b) + if(myJoyHandler->getButton(b)) { + if(!myButtonDown) + printf("--------------- Joystick button %d pressed.\n", b); + myButtonDown = true; + } + else + myButtonDown = false; + } + + lock(); + int f = myGPS->read(50); + printf("%.4f\t%.4f\t%.4f\t%.4f\t%.4f\t%.4f" + "\t%2.8f\t%2.8f\t%4.4f\t%4.4f" + "\t%lu\t%lu\t%s" + "\t%u\t%2.4f\t%2.4f\t%2.4f" + "\t%s\n", + myRobot->getX(), myRobot->getY(), myRobot->getTh(), myRobot->getVel(), myRobot->getRotVel(), (myRobot->hasLatVel())?(myRobot->getLatVel()):0, + myGPS->getLatitude(), myGPS->getLongitude(), myGPS->getAltitude(), myGPS->getSpeed(), + myGPS->getGPSPositionTimestamp().getSec(), myGPS->getGPSPositionTimestamp().getMSec(), myGPS->getFixTypeName(), + myGPS->getNumSatellitesTracked(), myGPS->getPDOP(), myGPS->getHDOP(), myGPS->getVDOP(), + ((f&ArGPS::ReadUpdated)?"yes":"no") + ); + unlock(); + } + +private: + ArRobot *myRobot; + ArGPS *myGPS; + ArFunctorC myTaskFunctor; + ArMutex myMutex; + ArJoyHandler *myJoyHandler; + bool myButtonDown; +}; + + + +int main(int argc, char** argv) +{ + Aria::init(); + ArLog::init(ArLog::StdErr, ArLog::Normal); + + ArArgumentParser argParser(&argc, argv); + ArSimpleConnector connector(&argParser); + ArGPSConnector gpsConnector(&argParser); + ArRobot robot; + + ArActionLimiterForwards nearLimitAction("limit near", 300, 600, 250); + ArActionLimiterForwards farLimitAction("limit far", 300, 1100, 400); + ArActionLimiterBackwards limitBackwardsAction; + ArActionJoydrive joydriveAction; + ArActionKeydrive keydriveAction; + + ArSonarDevice sonar; + ArSick laser; + + argParser.loadDefaultArguments(); + if(!Aria::parseArgs() || !argParser.checkHelpAndWarnUnparsed()) + { + Aria::logOptions(); + return -1; + } + + robot.addRangeDevice(&sonar); + robot.addRangeDevice(&laser); + + ArLog::log(ArLog::Normal, "gpsRobotTaskExample: Connecting to robot..."); + if(!connector.connectRobot(&robot)) + { + ArLog::log(ArLog::Terse, "gpsRobotTaskExample: Could not connect to the robot. Exiting."); + return -2; + } + ArLog::log(ArLog::Normal, "gpsRobotTaskExample: Connected to the robot."); + + + // Connect to GPS + ArLog::log(ArLog::Normal, "gpsRobotTaskExample: Connecting to GPS, it may take a few seconds..."); + ArGPS *gps = gpsConnector.createGPS(&robot); + assert(gps); + if(!gps || !(gps->connect())) + { + ArLog::log(ArLog::Terse, "gpsRobotTaskExample: Error connecting to GPS device. Try -gpsType, -gpsPort, and/or -gpsBaud command-line arguments. Use -help for help. Exiting."); + return -3; + } + + + // Create an GPSLogTask which will register a task with the robot. + GPSLogTask gpsTask(&robot, gps, joydriveAction.getJoyHandler()->haveJoystick() ? joydriveAction.getJoyHandler() : NULL); + + + // Add actions + robot.addAction(&nearLimitAction, 100); + robot.addAction(&farLimitAction, 90); + robot.addAction(&limitBackwardsAction, 80); + robot.addAction(&joydriveAction, 50); + robot.addAction(&keydriveAction, 40); + + // allow keydrive action to drive robot even if joystick button isn't pressed + joydriveAction.setStopIfNoButtonPressed(false); + + // Start the robot running + robot.runAsync(true); + + // Connect to the laser + connector.setupLaser(&laser); + laser.runAsync(); + if(!laser.blockingConnect()) + ArLog::log(ArLog::Normal, "gpsRobotTaskExample: Warning, could not connect to SICK laser, will not use it."); + + robot.lock(); + + robot.enableMotors(); + robot.comInt(47, 1); // enable joystick driving on some robots + + // Add exit callback to reset/unwrap steering wheels on seekur (critical if the robot doesn't have sliprings); does nothing for other robots + Aria::addExitCallback(new ArRetFunctor1C(&robot, &ArRobot::com, (unsigned char)120)); + Aria::addExitCallback(new ArRetFunctor1C(&robot, &ArRobot::com, (unsigned char)120)); + + robot.unlock(); + + ArLog::log(ArLog::Normal, "gpsRobotTaskExample: Running... (drive robot with joystick or arrow keys)"); + robot.waitForRunExit(); + + + return 0; +} diff --git a/Legacy/Aria/examples/gripperExample-vc2003.vcproj b/Legacy/Aria/examples/gripperExample-vc2003.vcproj new file mode 100644 index 0000000..d5c2534 --- /dev/null +++ b/Legacy/Aria/examples/gripperExample-vc2003.vcproj @@ -0,0 +1,156 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/examples/gripperExample-vc2008.vcproj b/Legacy/Aria/examples/gripperExample-vc2008.vcproj new file mode 100644 index 0000000..1b5f38f --- /dev/null +++ b/Legacy/Aria/examples/gripperExample-vc2008.vcproj @@ -0,0 +1,212 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/examples/gripperExample-vc2010.vcxproj b/Legacy/Aria/examples/gripperExample-vc2010.vcxproj new file mode 100644 index 0000000..c9fc891 --- /dev/null +++ b/Legacy/Aria/examples/gripperExample-vc2010.vcxproj @@ -0,0 +1,144 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + gripperExample + {8DB12A26-FF33-46BE-800E-2CBB06774473} + + + + Application + false + MultiByte + + + Application + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + .\../bin\ + ../obj/$(ProjectName)-$(Configuration)-VC10/ + false + .\../bin\ + ../obj/$(ProjectName)-$(Configuration)-VC10/ + false + $(ProjectName).DebugVC10 + + + + $(IntDir)$(ProjectName)-$(Configuration)-BuildLog.htm + + + .\../bin/gripperDemo.tlb + + + + + Disabled + ..\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + true + true + + + true + Level3 + true + + + Default + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + AriaDebugVC10.lib + 1.0 + true + ..\lib;%(AdditionalLibraryDirectories) + false + Console + false + + + MachineX86 + + + + + $(IntDir)$(ProjectName)-$(Configuration)-BuildLog.htm + + + .\../bin/gripperDemo.tlb + + + + + MaxSpeed + OnlyExplicitInline + ..\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + true + true + + + Level3 + true + + + Default + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + AriaVC10.lib + 1.0 + true + ..\lib;%(AdditionalLibraryDirectories) + false + Console + false + + + MachineX86 + + + + + + + + + \ No newline at end of file diff --git a/Legacy/Aria/examples/gripperExample.cpp b/Legacy/Aria/examples/gripperExample.cpp new file mode 100644 index 0000000..93dd91e --- /dev/null +++ b/Legacy/Aria/examples/gripperExample.cpp @@ -0,0 +1,208 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ + +/** @example gripperExample.cpp Example program demonstrating use of the Pioneer gripper. + * + * Shows how to control the Pioneer 2DOF gripper accessory. + * In addition to the arrow keys to teleoperate the robot, + * Use the following keyboard keys to control it: + * u Lift the gripper up + * d Lift the gripper down + * o Open the gripper + * c Close the gripper + * s Stop gripper movement. + * + * + * @sa ArModeGripper (the gripper control mode used in the "demo" program) + * +*/ + +#include "Aria.h" + +// Adds robot callback to print gripper status. +class PrintGripStatus +{ + ArGripper* myGripper; + ArFunctorC myPrintCB; +public: + PrintGripStatus(ArGripper* gripper) : + myGripper(gripper), + myPrintCB(this, &PrintGripStatus::printStatus) + { + } + + void addRobotTask(ArRobot* robot) + { + robot->addUserTask("PrintGripStatus", 10, &myPrintCB); + } + + void printStatus() + { + myGripper->logState(); + } +}; + +// Adds key handler callbacks for controlling the gripper +class GripperControlHandler +{ + ArGripper* myGripper; + ArFunctorC myUpCB; + ArFunctorC myDownCB; + ArFunctorC myOpenCB; + ArFunctorC myCloseCB; + ArFunctorC myStopCB; +public: + GripperControlHandler(ArGripper* gripper) : + myGripper(gripper), + myUpCB(this, &GripperControlHandler::liftUp), + myDownCB(this, &GripperControlHandler::liftDown), + myOpenCB(this, &GripperControlHandler::open), + myCloseCB(this, &GripperControlHandler::close), + myStopCB(this, &GripperControlHandler::stop) + { + } + + void addKeyHandlers(ArRobot *robot) + { + ArKeyHandler *keyHandler = Aria::getKeyHandler(); + if(keyHandler == NULL) + { + keyHandler = new ArKeyHandler(); + Aria::setKeyHandler(keyHandler); + robot->attachKeyHandler(keyHandler); + } + keyHandler->addKeyHandler(ArKeyHandler::PAGEUP, &myUpCB); + keyHandler->addKeyHandler('u', &myUpCB); + keyHandler->addKeyHandler(ArKeyHandler::PAGEDOWN, &myDownCB); + keyHandler->addKeyHandler('d', &myDownCB); + keyHandler->addKeyHandler('o', &myOpenCB); + keyHandler->addKeyHandler('c', &myCloseCB); + keyHandler->addKeyHandler('s', &myStopCB); + } + + void liftUp() + { + ArLog::log(ArLog::Normal, "Moving gripper lift up..."); + myGripper->liftUp(); + } + + void liftDown() + { + ArLog::log(ArLog::Normal, "Moving gripper lift down..."); + myGripper->liftDown(); + } + + void stop() + { + ArLog::log(ArLog::Normal, "Stopping gripper..."); + myGripper->gripperHalt(); // stops both lift an grip + //myGripper->liftStop(); // stops just the lift + //myGripper->gripStop(); // stops just the gripper + } + + void close() + { + ArLog::log(ArLog::Normal, "Closing gripper..."); + myGripper->gripClose(); + } + + void open() + { + ArLog::log(ArLog::Normal, "Opening gripper..."); + myGripper->gripOpen(); + } + +}; + +int main(int argc, char **argv) +{ + + Aria::init(); + ArRobot robot; + ArArgumentParser argParser(&argc, argv); + ArSimpleConnector connector(&argParser); + ArGripper gripper(&robot); + ArSonarDevice sonar; + robot.addRangeDevice(&sonar); + + argParser.loadDefaultArguments(); + + if (!Aria::parseArgs() || !argParser.checkHelpAndWarnUnparsed()) + { + Aria::logOptions(); + Aria::exit(1); + return 1; + } + + if (!connector.connectRobot(&robot)) + { + ArLog::log(ArLog::Terse, "gripperExample: Could not connect to robot... exiting"); + Aria::exit(2); + return 2; + } + ArLog::log(ArLog::Normal, "gripperExample: Connected to robot."); + + ArLog::log(ArLog::Normal, "gripperExample: GripperType=%d", gripper.getType()); + gripper.logState(); + if(gripper.getType() == ArGripper::NOGRIPPER) + { + ArLog::log(ArLog::Terse, "gripperExample: Error: Robot does not have a gripper. Exiting."); + Aria::exit(-1); + return -1; + } + + // Teleoperation actions with obstacle-collision avoidance + ArActionLimiterTableSensor tableLimit; + robot.addAction(&tableLimit, 110); + ArActionLimiterForwards limitNearAction("near", 300, 600, 250); + robot.addAction(&limitNearAction, 100); + ArActionLimiterForwards limitFarAction("far", 300, 1100, 400); + robot.addAction(&limitFarAction, 90); + ArActionLimiterBackwards limitBackAction; + robot.addAction(&limitBackAction, 50); + ArActionJoydrive joydriveAction("joydrive", 400, 15); + robot.addAction(&joydriveAction, 40); + joydriveAction.setStopIfNoButtonPressed(false); + ArActionKeydrive keydriveAction; + robot.addAction(&keydriveAction, 30); + + + // Handlers to control the gripper and print out info (classes defined above) + PrintGripStatus printStatus(&gripper); + GripperControlHandler gripControl(&gripper); + printStatus.addRobotTask(&robot); + gripControl.addKeyHandlers(&robot); + + // enable motors and run (if we lose connection to the robot, exit) + ArLog::log(ArLog::Normal, "You may now operate the robot with arrow keys or joystick. Operate the gripper with the u, d, o, c, and page up/page down keys."); + robot.enableMotors(); + robot.run(true); + + Aria::exit(0); + return 0; +} + + diff --git a/Legacy/Aria/examples/gyroExample-vc2003.vcproj b/Legacy/Aria/examples/gyroExample-vc2003.vcproj new file mode 100644 index 0000000..a5aae40 --- /dev/null +++ b/Legacy/Aria/examples/gyroExample-vc2003.vcproj @@ -0,0 +1,173 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/examples/gyroExample-vc2008.vcproj b/Legacy/Aria/examples/gyroExample-vc2008.vcproj new file mode 100644 index 0000000..7946f69 --- /dev/null +++ b/Legacy/Aria/examples/gyroExample-vc2008.vcproj @@ -0,0 +1,234 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/examples/gyroExample-vc2010.vcxproj b/Legacy/Aria/examples/gyroExample-vc2010.vcxproj new file mode 100644 index 0000000..8193445 --- /dev/null +++ b/Legacy/Aria/examples/gyroExample-vc2010.vcxproj @@ -0,0 +1,153 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + gyroExample + {1A8C458C-0086-4788-AF12-F1DFA5EBAD53} + + + + Application + false + MultiByte + + + Application + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + .\../bin\ + ../obj/$(ProjectName)-$(Configuration)-VC10/ + false + .\../bin\ + ../obj/$(ProjectName)-$(Configuration)-VC10/ + false + $(ProjectName).DebugVC10 + + + + $(IntDir)$(ProjectName)-$(Configuration)-BuildLog.htm + + + .\../bin/gyroExample.tlb + + + + + MaxSpeed + OnlyExplicitInline + ..\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + true + true + + + Level3 + true + + + Default + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + AriaVC10.lib + 1.0 + true + ..\lib;%(AdditionalLibraryDirectories) + false + Console + false + + + MachineX86 + + + + + $(IntDir)$(ProjectName)-$(Configuration)-BuildLog.htm + + + .\../bin/gyroExample.tlb + + + + + Disabled + ..\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + true + true + + + true + Level3 + true + + + Default + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + AriaDebugVC10.lib + 1.0 + true + ..\lib;%(AdditionalLibraryDirectories) + false + Console + false + + + MachineX86 + + + + + Disabled + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + EnableFastChecks + true + MaxSpeed + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + + + + \ No newline at end of file diff --git a/Legacy/Aria/examples/gyroExample.cpp b/Legacy/Aria/examples/gyroExample.cpp new file mode 100644 index 0000000..b6b1fc1 --- /dev/null +++ b/Legacy/Aria/examples/gyroExample.cpp @@ -0,0 +1,199 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +/** @example gyroExample.cpp Example program that activates an onboard gyro if it exists and uses its data to correct the robot pose. + * + * This program uses ArActionKeydrive and ArActionJoydrive to allow + * teleoperation with the keyboard or joystick, and displays gyro data. + * Additional keys (numbers 0-9 and letters q, w, e, r, t, y, u, i, o, p) + * activate preset rotation velocities. + * +*/ + +#include "Aria.h" +#include "ArAnalogGyro.h" + + +class GyroTask +{ +public: + // the constructor, it must use constructor chaining to intialize its base + // class ArSimpleUserTask + GyroTask(ArRobot *robot); + // empty destructor + ~GyroTask(void) {} + + // the task we want to do + void doTask(void); + + bool handlePacket(ArRobotPacket *pkt); +protected: + //double myHeading; + ArAnalogGyro *myGyro; + ArRobot *myRobot; + ArFunctorC myTaskCB; + ArRetFunctor1C myPacketHandlerCB; + bool gotGyroPacket; +}; + + +// the constructor, note how it uses chaining to initialize the myTaskCB +GyroTask::GyroTask(ArRobot *robot) : + myTaskCB(this, &GyroTask::doTask), + myPacketHandlerCB(this, &GyroTask::handlePacket), + gotGyroPacket(false) +{ + ArKeyHandler *keyHandler; + myRobot = robot; + // just add it to the robot + myRobot->addUserTask("GyroTask", 50, &myTaskCB); + myRobot->addPacketHandler(&myPacketHandlerCB, ArListPos::LAST); + myRobot->comInt(ArCommands::GYRO, 2); + myGyro = new ArAnalogGyro(myRobot); + if ((keyHandler = Aria::getKeyHandler()) == NULL) + { + keyHandler = new ArKeyHandler; + Aria::setKeyHandler(keyHandler); + if (myRobot != NULL) + myRobot->attachKeyHandler(keyHandler); + else + ArLog::log(ArLog::Terse, "GyroTask: No robot to attach a keyHandler to, keyHandling won't work... either make your own keyHandler and drive it yourself, make a keyhandler and attach it to a robot, or give this a robot to attach to."); + } + keyHandler->addKeyHandler('1', new ArFunctor1C(myRobot,&ArRobot::setRotVel, 10)); + keyHandler->addKeyHandler('2', new ArFunctor1C(myRobot,&ArRobot::setRotVel, 20)); + keyHandler->addKeyHandler('3', new ArFunctor1C(myRobot,&ArRobot::setRotVel, 30)); + keyHandler->addKeyHandler('4', new ArFunctor1C(myRobot,&ArRobot::setRotVel, 40)); + keyHandler->addKeyHandler('5', new ArFunctor1C(myRobot,&ArRobot::setRotVel, 50)); + keyHandler->addKeyHandler('6', new ArFunctor1C(myRobot,&ArRobot::setRotVel, 60)); + keyHandler->addKeyHandler('7', new ArFunctor1C(myRobot,&ArRobot::setRotVel, 70)); + keyHandler->addKeyHandler('8', new ArFunctor1C(myRobot,&ArRobot::setRotVel, 80)); + keyHandler->addKeyHandler('9', new ArFunctor1C(myRobot,&ArRobot::setRotVel, 90)); + keyHandler->addKeyHandler('0', new ArFunctor1C(myRobot,&ArRobot::setRotVel, 100)); + + keyHandler->addKeyHandler('q', new ArFunctor1C(myRobot,&ArRobot::setRotVel, -10)); + keyHandler->addKeyHandler('w', new ArFunctor1C(myRobot,&ArRobot::setRotVel, -20)); + keyHandler->addKeyHandler('e', new ArFunctor1C(myRobot,&ArRobot::setRotVel, -30)); + keyHandler->addKeyHandler('r', new ArFunctor1C(myRobot,&ArRobot::setRotVel, -40)); + keyHandler->addKeyHandler('t', new ArFunctor1C(myRobot,&ArRobot::setRotVel, -50)); + keyHandler->addKeyHandler('y', new ArFunctor1C(myRobot,&ArRobot::setRotVel, -60)); + keyHandler->addKeyHandler('u', new ArFunctor1C(myRobot,&ArRobot::setRotVel, -70)); + keyHandler->addKeyHandler('i', new ArFunctor1C(myRobot,&ArRobot::setRotVel, -80)); + keyHandler->addKeyHandler('o', new ArFunctor1C(myRobot,&ArRobot::setRotVel, -90)); + keyHandler->addKeyHandler('p', new ArFunctor1C(myRobot, &ArRobot::setRotVel, -100)); + + keyHandler->addKeyHandler('a', new ArFunctor1C(myRobot, &ArRobot::setHeading, 0)); + keyHandler->addKeyHandler('s', new ArFunctor1C(myRobot, &ArRobot::setHeading, 90)); + keyHandler->addKeyHandler('d', new ArFunctor1C(myRobot, &ArRobot::setHeading, 180)); + keyHandler->addKeyHandler('f', new ArFunctor1C(myRobot, &ArRobot::setHeading, 270)); + +} + +void GyroTask::doTask(void) +{ + /* + double degrees = -((myRobot->getAnalog() * 5.0 / 255) - 2.509) * 150 / 2.5 * 1.265; + if (fabs(degrees) < 2) + degrees = 0; + myHeading += degrees * .025; + printf("%10f %10f %10f %10f\n", myRobot->getAnalog() * 5.0 / 255, degrees, + myRobot->getRotVel(), myHeading); + fflush(stdout); + */ + printf("gyro th (mode 1 only):%8.4f encoder th:%8.4f ArRobot mixed th:%8.4f temp:%d ave:%g gyro packets:%s\n", myGyro->getHeading(), myRobot->getRawEncoderPose().getTh(), myRobot->getTh(), myGyro->getTemperature(), myGyro->getAverage(), gotGyroPacket?"received":"not received"); +} + + +bool GyroTask::handlePacket(ArRobotPacket *pkt) +{ + if(pkt->getID() == 152) + gotGyroPacket = true; + return true; +} + + +int main(int argc, char **argv) +{ + Aria::init(); + ArRobot robot; + + // the joydrive action + ArActionJoydrive joydriveAct; + // the keydrive action + ArActionKeydrive keydriveAct; + + GyroTask gyro(&robot); + + // sonar device, so the limiter will work, this must be added to the robot + ArSonarDevice sonar; + + ArArgumentParser parser(&argc, argv); + parser.loadDefaultArguments(); + ArRobotConnector connector(&parser, &robot); + if (!Aria::parseArgs() || argc > 1) + { + Aria::logOptions(); + Aria::exit(1); + return 1; + } + + + printf("This program will allow you to use a joystick or keyboard to control the robot.\nYou can use the arrow keys to drive, and the spacebar to stop.\nFor joystick control press the trigger button and then drive.\nPress escape to exit.\n"); + + + // if we don't have a joystick, let 'em know + if (!joydriveAct.joystickInited()) + printf("Do not have a joystick, only the arrow keys on the keyboard will work.\n"); + + // set the joystick so it won't do anything if the button isn't pressed + joydriveAct.setStopIfNoButtonPressed(false); + + // add the sonar to the robot + robot.addRangeDevice(&sonar); + + // try to connect, if we fail exit + if (!connector.connectRobot()) + { + printf("Could not connect to robot... exiting\n"); + Aria::exit(1); + return 1; + } + + robot.comInt(ArCommands::ENABLE, 1); + + robot.addAction(&joydriveAct, 50); + robot.addAction(&keydriveAct, 45); + + // set the joydrive action so it'll let the keydrive action fire if + // there is no button pressed + joydriveAct.setStopIfNoButtonPressed(false); + + + // run the robot, true here so that the run will exit if connection lost + robot.run(true); + + // now exit + Aria::exit(0); + return 0; +} diff --git a/Legacy/Aria/examples/imuExample.cpp b/Legacy/Aria/examples/imuExample.cpp new file mode 100644 index 0000000..0337acf --- /dev/null +++ b/Legacy/Aria/examples/imuExample.cpp @@ -0,0 +1,171 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +/** @example imuExample.cpp Example of gathering IMU data from Seekur + + Sample program that demonstrates how to get IMU data from an IMU on + a Seekur-class robot (from SeekurOS). Only some Seekurs have IMUs. + + [Some Pioneers also have + gyros that are integrated into the robot and normally automatically + correct data or which can optionally return the data seperately + (using different packets and different ARIA interface in ArAnalogGyro).] + + The data comes back in a custom packet with + ID 0x9A. It's requested with client command 26. + + Press escape to exit the program. + + */ + +#include "Aria.h" +#include + +bool imuPacketHandler(ArRobotPacket* packet) { + if (packet->getID() != 0x9a) { + //ArLog::log(ArLog::Normal, "ignoring packet with id: %d", packet->getID()); + return false; + } + int timeSince = packet->bufToByte(); + int numPerAxis = packet->bufToByte(); + + ArLog::log(ArLog::Normal, "got IMUpac, %dms since readings took place, %d readings per axis", timeSince, numPerAxis); + int i; + int range; + double x = 0.0; + double y = 0.0; + double z = 0.0; + double multiplier = 0.0; + double offset = 0.0; + int numGyroAxes = packet->bufToByte(); + for (i=1; i <= numPerAxis; i++) { + x = 0.0; + y = 0.0; + z = 0.0; + range = packet->bufToByte(); + if (range == 3) { + multiplier = 0.07326; + offset = 0.0; + } + else if (range == 2) { + multiplier = 0.03663; + offset = 0.0; + } + else if (range == 1) { + multiplier = 0.01832; + offset = 0.0; + } + if (numGyroAxes >= 1) { + x = (packet->bufToByte2() * multiplier) + offset; + } + if (numGyroAxes >= 2) { + y = (packet->bufToByte2() * multiplier) + offset; + } + if (numGyroAxes >= 3) { + z = (packet->bufToByte2() * multiplier) + offset; + } + ArLog::log(ArLog::Normal, "gyro: reading %d of %d, x: %10.4f deg/s, y: %10.4f deg/s, z: %10.4f deg/s", + i, numPerAxis, x, y, z); + } + int numAccelAxes = packet->bufToByte(); + for (i=1; i <= numPerAxis; i++) { + x = 0.0; + y = 0.0; + z = 0.0; + multiplier = 0.002522 * 9806.65; + offset = 0.0; + if (numAccelAxes >= 1) { + x = (packet->bufToByte2() * multiplier) + offset; + } + if (numAccelAxes >= 2) { + y = (packet->bufToByte2() * multiplier) + offset; + } + if (numAccelAxes >= 3) { + z = (packet->bufToByte2() * multiplier) + offset; + } + ArLog::log(ArLog::Normal, "accel: reading %d of %d, x: %10.4f mg, y: %10.4f mg, z: %10.4f mg", + i, numPerAxis, x, y, z); + } + int numTemperatureAxes = packet->bufToByte(); + for (i=1; i <= numPerAxis; i++) { + x = 0.0; + y = 0.0; + z = 0.0; + multiplier = 0.1453; + offset = 25.0; + if (numTemperatureAxes >= 1) { + x = (packet->bufToByte2() * multiplier) + offset; + } + if (numTemperatureAxes >= 2) { + y = (packet->bufToByte2() * multiplier) + offset; + } + if (numTemperatureAxes >= 3) { + z = (packet->bufToByte2() * multiplier) + offset; + } + ArLog::log(ArLog::Normal, "temperature: reading %d of %d, x: %10.4f degC, y: %10.4f degC, z: %10.4f degC", + i, numPerAxis, x, y, z); + } + ArLog::log(ArLog::Normal, ""); + ArLog::log(ArLog::Normal, ""); + + return true; +} + +int main(int argc, char **argv) { + Aria::init(); + ArLog::init(ArLog::StdOut, ArLog::Normal, "", true); + ArArgumentParser parser(&argc, argv); + ArRobot *robot = new ArRobot; + ArSimpleConnector simpleConnector(&parser); + ArKeyHandler keyHandler; + Aria::setKeyHandler(&keyHandler); + robot->attachKeyHandler(&keyHandler); + + parser.loadDefaultArguments(); + if (!simpleConnector.parseArgs() || !parser.checkHelpAndWarnUnparsed(1)) { + simpleConnector.logOptions(); + keyHandler.restore(); + Aria::exit(1); + } + if (!simpleConnector.connectRobot(robot)) { + ArLog::log(ArLog::Terse, "Error connecting to robot."); + Aria::shutdown(); + keyHandler.restore(); + Aria::exit(1); + } + ArLog::log(ArLog::Normal, "Connected to robot."); + ArGlobalRetFunctor1 myImuPacketHandler(&imuPacketHandler); + robot->addPacketHandler(&myImuPacketHandler, ArListPos::FIRST); + robot->runAsync(true); + ArUtil::sleep(500); + robot->lock(); + robot->comInt(26, 2); // request IMU packets continuously + ArLog::log(ArLog::Normal, "Requested IMU packets, waiting..."); + robot->unlock(); + robot->waitForRunExit(); + Aria::shutdown(); + exit(0); +} + diff --git a/Legacy/Aria/examples/ipthru-vc2003.vcproj b/Legacy/Aria/examples/ipthru-vc2003.vcproj new file mode 100644 index 0000000..dbbcacf --- /dev/null +++ b/Legacy/Aria/examples/ipthru-vc2003.vcproj @@ -0,0 +1,185 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/examples/ipthru-vc2008.vcproj b/Legacy/Aria/examples/ipthru-vc2008.vcproj new file mode 100644 index 0000000..7fd4fce --- /dev/null +++ b/Legacy/Aria/examples/ipthru-vc2008.vcproj @@ -0,0 +1,249 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/examples/ipthru-vc2010.vcxproj b/Legacy/Aria/examples/ipthru-vc2010.vcxproj new file mode 100644 index 0000000..c18e7a0 --- /dev/null +++ b/Legacy/Aria/examples/ipthru-vc2010.vcxproj @@ -0,0 +1,153 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + ipthru + {B0CD9146-122F-49FD-A12A-7A970514DFB1} + + + + Application + false + MultiByte + + + Application + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + .\../bin\ + ../obj/$(ProjectName)-$(Configuration)-VC10/ + false + .\../bin\ + ../obj/$(ProjectName)-$(Configuration)-VC10/ + false + $(ProjectName).DebugVC10 + + + + $(IntDir)$(ProjectName)-$(Configuration)-BuildLog.htm + + + .\../bin/ipthru.tlb + + + + + Disabled + ..\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + true + true + + + true + Level3 + true + + + Default + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + AriaDebugVC10.lib + 1.0 + true + ..\lib;%(AdditionalLibraryDirectories) + false + Console + false + + + MachineX86 + + + + + $(IntDir)$(ProjectName)-$(Configuration)-BuildLog.htm + + + .\../bin/ipthru.tlb + + + + + MaxSpeed + OnlyExplicitInline + ..\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + true + true + + + Level3 + true + + + Default + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + AriaVC10.lib + 1.0 + true + ..\lib;%(AdditionalLibraryDirectories) + false + Console + false + + + MachineX86 + + + + + Disabled + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + EnableFastChecks + true + MaxSpeed + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + + + + \ No newline at end of file diff --git a/Legacy/Aria/examples/ipthru.cpp b/Legacy/Aria/examples/ipthru.cpp new file mode 100644 index 0000000..b5522d8 --- /dev/null +++ b/Legacy/Aria/examples/ipthru.cpp @@ -0,0 +1,237 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#include "Aria.h" + + +/* + Utility that forwards data back and forth from a tcp port to a serial + port. This can be used to run programs on your workstation instead + of the robot's onboard computer, or to bridge networks. + However, it can negatively impact performance, and may cause some things + to simply not work; we do not recommend or support using this program + other than for quick testing or development. +*/ + +void usage(char *progName) +{ + printf("There are four ways to use %s\n", progName); + printf("%s\t\t\tUses a robot, port 8101 and %s\n", progName, ArUtil::COM1); + printf("%s laser\t\tUses a laser, port 8102 and %s\n", progName, ArUtil::COM3); + printf("%s \n", progName); + printf("%s laser\n", progName); + printf("-----------------------------------------------------------\n"); + printf("portNumToForwardFrom: The tcp port to listen on.\n"); + printf("portNameToForwardTo: The serial port name to open.\n"); + printf("laser: option, if given it'll use laser packet receivers and not robot packet receivers.\n"); +} + +int main(int argc, char **argv) +{ + // this is how long to wait after there's been no data to close the + // connection.. if its 0 and its using robot it'll set it to 5000 (5 + // seconds), if its 0 and using laser, it'll set it to 60000 (60 + // seconds, which is needed if the sick driver is controlling power + int timeout = 0; + // true will print out packets as they come and go, false won't + bool tracePackets = false; + + // The socket objects + ArSocket masterSock, clientSock; + // The connections + ArTcpConnection clientConn; + ArSerialConnection robotConn; + // the receivers, first for the robot + ArRobotPacketReceiver clientRec(&clientConn); + ArRobotPacketReceiver robotRec(&robotConn); + // then for the laser + ArSickPacketReceiver clientSickRec(&clientConn, 0, false, true); + ArSickPacketReceiver robotSickRec(&robotConn); + // how about a packet + ArBasePacket *packet; + // our timer for how often we test the client + ArTime lastClientTest; + ArTime lastData; + // where we're forwarding from and to + int portNumber; + const char *portName; + // if we're using the robot or the laser + bool useRobot; + + if (argc == 1) + { + printf("Using robot and port 8101 and serial connection %s, by default.\n", ArUtil::COM1); + useRobot = true; + portNumber = 8101; + portName = ArUtil::COM1; + } + else if (argc == 2) + { + // if laser isn't the last arg, somethings wrong + if (strcmp(argv[1], "laser") != 0) + { + usage(argv[0]); + return -1; + } + useRobot = false; + portNumber = 8102; + portName = ArUtil::COM3; + printf("Using laser and port %d and serial connection %s, by command line arguments.\n", portNumber, portName); + printf("(Note: Requests to change BAUD rate cannot be fulfilled; use 9600 rate only.)\n"); + } + else if (argc == 3) + { + if ((portNumber = atoi(argv[1])) <= 0) + { + usage(argv[0]); + return -1; + } + portName = argv[2]; + printf("Using robot and port %d and serial connection %s, by command line arguments.\n", portNumber, portName); + } + else if (argc == 4) + { + if ((portNumber = atoi(argv[1])) <= 0) + { + usage(argv[0]); + return -1; + } + // if laser isn't the last arg, somethings wrong + if (strcmp(argv[3], "laser") != 0) + { + usage(argv[0]); + return -1; + } + useRobot = false; + portName = argv[2]; + printf("Using laser and port %d and serial connection %s, by command line arguments.\n", portNumber, portName); + printf("(Note: Requests to change BAUD rate cannot be fulfilled; use 9600 rate only.)\n"); + } + else + { + usage(argv[0]); + return -1; + } + if (timeout == 0 && useRobot) + timeout = 5000; + else if (timeout == 0) + timeout = 60000; + + // Initialize Aria. For Windows, this absolutely must be done. Because + // Windows does not initialize the socket layer for each program. Each + // program must initialize the sockets itself. + Aria::init(Aria::SIGHANDLE_NONE); + + // Lets open the master socket + if (masterSock.open(portNumber, ArSocket::TCP)) + printf("Opened the master port at %d\n", portNumber); + else + { + printf("Failed to open the master port at %d: %s\n", + portNumber, masterSock.getErrorStr().c_str()); + return -1; + } + + // just go forever + while (1) + { + // Lets wait for the client to connect to us. + if (masterSock.accept(&clientSock)) + printf("Client has connected\n"); + else + printf("Error in accepting a connection from the client: %s\n", + masterSock.getErrorStr().c_str()); + + // now set up our connection so our packet receivers work + clientConn.setSocket(&clientSock); + clientConn.setStatus(ArDeviceConnection::STATUS_OPEN); + lastClientTest.setToNow(); + lastData.setToNow(); + // open up the robot port + if (robotConn.open(portName) != 0) + { + printf("Could not open robot port %s.\n", portName); + return -1; + } + + // while we're open, just read from one port and write to the other + while (clientSock.getFD() >= 0) + { + // get our packet + if (useRobot) + packet = clientRec.receivePacket(1); + else + packet = clientSickRec.receivePacket(1); + // see if we had one + if (packet != NULL) + { + if (tracePackets) + { + printf("Client "); + packet->log(); + } + robotConn.writePacket(packet); + lastData.setToNow(); + } + // get our packet + if (useRobot) + packet = robotRec.receivePacket(1); + else + packet = robotSickRec.receivePacket(1); + // see if we had one + if (packet != NULL) + { + if (tracePackets) + { + printf("Robot "); + packet->log(); + } + clientConn.writePacket(packet); + lastData.setToNow(); + } + ArUtil::sleep(1); + // If no datas gone by in timeout ms assume our connection is broken + if (lastData.mSecSince() > timeout) + { + printf("No data received in %d milliseconds, closing connection.\n", + timeout); + clientConn.close(); + } + } + // Now lets close the connection to the client + clientConn.close(); + printf("Socket to client closed\n"); + robotConn.close(); + } + // And lets close the master port + masterSock.close(); + printf("Master socket closed and program exiting\n"); + + // Uninitialize Aria + Aria::uninit(); + + // All done + return(0); +} diff --git a/Legacy/Aria/examples/joydriveActionExample-vc2003.vcproj b/Legacy/Aria/examples/joydriveActionExample-vc2003.vcproj new file mode 100644 index 0000000..3bebd0a --- /dev/null +++ b/Legacy/Aria/examples/joydriveActionExample-vc2003.vcproj @@ -0,0 +1,156 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/examples/joydriveActionExample-vc2008.vcproj b/Legacy/Aria/examples/joydriveActionExample-vc2008.vcproj new file mode 100644 index 0000000..a7b2126 --- /dev/null +++ b/Legacy/Aria/examples/joydriveActionExample-vc2008.vcproj @@ -0,0 +1,210 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/examples/joydriveActionExample-vc2010.vcproj b/Legacy/Aria/examples/joydriveActionExample-vc2010.vcproj new file mode 100644 index 0000000..a7b2126 --- /dev/null +++ b/Legacy/Aria/examples/joydriveActionExample-vc2010.vcproj @@ -0,0 +1,210 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/examples/joydriveActionExample.cpp b/Legacy/Aria/examples/joydriveActionExample.cpp new file mode 100644 index 0000000..87596ab --- /dev/null +++ b/Legacy/Aria/examples/joydriveActionExample.cpp @@ -0,0 +1,155 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#include "Aria.h" + +/** @example joydriveActionExample.cpp Example ArAction object that uses + * ArJoyHandler to get joystick input. + * + This program just drives the robot around with a joystick, + by way of an ArAction class which reads data fram an ArJoyHandler. + Its a practical example of actions. +*/ + +// the action which will drive the robot +class JoydriveAction : public ArAction +{ +public: + // constructor + JoydriveAction(void); + // empty destructor + virtual ~JoydriveAction(void); + //the fire which will actually tell the resolver what to do + virtual ArActionDesired *fire(ArActionDesired currentDesired); + // whether the joystick is initalized or not + bool joystickInited(void); +protected: + // action desired + ArActionDesired myDesired; + // joystick handler + ArJoyHandler myJoyHandler; +}; + +/* + Note the use of constructor chaining with ArAction. +*/ +JoydriveAction::JoydriveAction(void) : + ArAction("Joydrive Action", "This action reads the joystick and sets the translational and rotational velocity based on this.") +{ + // initialize the joystick + myJoyHandler.init(); + // set up the speed parameters on the joystick + myJoyHandler.setSpeeds(50, 700); +} + +JoydriveAction::~JoydriveAction(void) +{ +} + +// whether the joystick is there or not +bool JoydriveAction::joystickInited(void) +{ + return myJoyHandler.haveJoystick(); +} + +// the guts of the thing +ArActionDesired *JoydriveAction::fire(ArActionDesired currentDesired) +{ + int rot, trans; + + // print out some info about hte robot + printf("\rx %6.1f y %6.1f tth %6.1f vel %7.1f mpacs %3d", myRobot->getX(), + myRobot->getY(), myRobot->getTh(), myRobot->getVel(), + myRobot->getMotorPacCount()); + fflush(stdout); + + // see if one of the buttons is pushed, if so drive + if (myJoyHandler.haveJoystick() && (myJoyHandler.getButton(1) || + myJoyHandler.getButton(2))) + { + // get the readings from the joystick + myJoyHandler.getAdjusted(&rot, &trans); + // set what we want to do + myDesired.setVel(trans); + myDesired.setDeltaHeading(-rot); + // return the actionDesired + return &myDesired; + } + else + { + // set what we want to do + myDesired.setVel(0); + myDesired.setDeltaHeading(0); + // return the actionDesired + return &myDesired; + } +} + + +int main(int argc, char **argv) +{ + ArRobot robot; + Aria::init(); + ArSimpleConnector connector(&argc, argv); + if (!connector.parseArgs() || argc > 1) + { + connector.logOptions(); + return 1; + } + + // Instance of the JoydriveAction class defined above + JoydriveAction jdAct; + + // if the joydrive action couldn't find the joystick, then exit. + if (!jdAct.joystickInited()) + { + printf("Do not have a joystick, set up the joystick then rerun the program\n\n"); + Aria::exit(1); + return 1; + } + + // Connect to the robot + if (!connector.connectRobot(&robot)) + { + printf("Could not connect to robot... exiting\n"); + return 2; + } + + + // disable sonar, enable motors, disable amigobot sound + robot.comInt(ArCommands::SONAR, 0); + robot.comInt(ArCommands::ENABLE, 1); + robot.comInt(ArCommands::SOUNDTOG, 0); + + // add the action + robot.addAction(&jdAct, 100); + // run the robot, true so it'll exit if we lose connection + robot.run(true); + + // now exit program + Aria::exit(0); + return 0; +} + diff --git a/Legacy/Aria/examples/joydriveThreaded-vc2003.vcproj b/Legacy/Aria/examples/joydriveThreaded-vc2003.vcproj new file mode 100644 index 0000000..11708c8 --- /dev/null +++ b/Legacy/Aria/examples/joydriveThreaded-vc2003.vcproj @@ -0,0 +1,173 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/examples/joydriveThreaded-vc2008.vcproj b/Legacy/Aria/examples/joydriveThreaded-vc2008.vcproj new file mode 100644 index 0000000..660c2b8 --- /dev/null +++ b/Legacy/Aria/examples/joydriveThreaded-vc2008.vcproj @@ -0,0 +1,234 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/examples/joydriveThreaded-vc2010.vcxproj b/Legacy/Aria/examples/joydriveThreaded-vc2010.vcxproj new file mode 100644 index 0000000..742d379 --- /dev/null +++ b/Legacy/Aria/examples/joydriveThreaded-vc2010.vcxproj @@ -0,0 +1,153 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + joydriveThreaded + {B6C39214-2167-4B3D-8C01-2D98A5642F8E} + + + + Application + false + MultiByte + + + Application + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + .\../bin\ + ../obj/$(ProjectName)-$(Configuration)-VC10/ + false + .\../bin\ + ../obj/$(ProjectName)-$(Configuration)-VC10/ + false + $(ProjectName).DebugVC10 + + + + $(IntDir)$(ProjectName)-$(Configuration)-BuildLog.htm + + + .\../bin/joydriveThreaded.tlb + + + + + MaxSpeed + OnlyExplicitInline + ..\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + true + true + + + Level3 + true + + + Default + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + AriaVC10.lib + 1.0 + true + ..\lib;%(AdditionalLibraryDirectories) + false + Console + false + + + MachineX86 + + + + + $(IntDir)$(ProjectName)-$(Configuration)-BuildLog.htm + + + .\../bin/joydriveThreaded.tlb + + + + + Disabled + ..\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + true + true + + + true + Level3 + true + + + Default + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + AriaDebugVC10.lib + 1.0 + true + ..\lib;%(AdditionalLibraryDirectories) + false + Console + false + + + MachineX86 + + + + + Disabled + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + EnableFastChecks + true + MaxSpeed + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + + + + \ No newline at end of file diff --git a/Legacy/Aria/examples/joydriveThreaded.cpp b/Legacy/Aria/examples/joydriveThreaded.cpp new file mode 100644 index 0000000..db2251d --- /dev/null +++ b/Legacy/Aria/examples/joydriveThreaded.cpp @@ -0,0 +1,265 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#include "Aria.h" + +/* + This program just drives the robot around with a joystick. + + This example shows an example of a program making a thread for its own use + (reading the joystick and driving the robot), having the robot run in its + own thread, and then keeping its main thread to itself. Demonstrates the + thread locking that must be done for threads to work safely. If you don't + know or understand threading, or you don't need threading, you probably + shouldn't do it this way, as it is more complicated. +*/ + +/* + This class creates its own thread, and then runs in the thread, controlling + the robot with the joystick. +*/ +class Joydrive : public ArASyncTask +{ +public: + // constructor + Joydrive(ArRobot *robot); + // empty destructor + ~Joydrive(void) {} + + // the function to run in the new thread, this just is called once, so + // only return when you want th ethread to exit + virtual void * runThread(void *arg); + +protected: + // joystick handler + ArJoyHandler myJoyHandler; + // robot pointer + ArRobot *myRobot; +}; + +// a nice simple constructor +Joydrive::Joydrive(ArRobot *robot) +{ + setThreadName("Joydrive"); + // set the robot pointer + myRobot = robot; + // initialize the joystick + myJoyHandler.init(); + // set up the joystick so we'll get the speeds out we want + myJoyHandler.setSpeeds(40, 700); + + // see if we have a joystick, and let the users know + if (myJoyHandler.haveJoystick()) + { + printf("Have a joystick\n\n"); + } + // if we don't have a joystick, then print error message and exit + else + { + printf("Do not have a joystick, set up the joystick then rerun the program\n\n"); + Aria::exit(1); // exit program with error code 1 + } + + // this is what creates are own thread, its from the ArASyncTask + create(); +} + +// this is the function called in the new thread +void *Joydrive::runThread(void *arg) +{ + threadStarted(); + + int trans, rot; + + // only run while running, ie play nice and pay attention to the thread + //being shutdown + while (myRunning) + { + // lock the robot before touching it + myRobot->lock(); + if (!myRobot->isConnected()) + { + myRobot->unlock(); + break; + } + // print out some information about the robot + printf("\rx %6.1f y %6.1f tth %6.1f vel %7.1f mpacs %3d ", + myRobot->getX(), myRobot->getY(), myRobot->getTh(), + myRobot->getVel(), myRobot->getMotorPacCount()); + fflush(stdout); + // if one of the joystick buttons is pushed, drive the robot + if (myJoyHandler.haveJoystick() && (myJoyHandler.getButton(1) || + myJoyHandler.getButton(2))) + { + // get out the values from the joystick + myJoyHandler.getAdjusted(&rot, &trans); + // drive the robot + myRobot->setVel(trans); + myRobot->setRotVel(-rot); + } + // if no buttons are pushed stop the robot + else + { + myRobot->setVel(0); + myRobot->setRotVel(0); + } + // unlock the robot, so everything else can run + myRobot->unlock(); + // now take a little nap + ArUtil::sleep(50); + } + // return out here, means the thread is done + return NULL; +} + +/* + This is a connection handler, fairly simple, but quite useful, esp when + the robot is running in another thread. +*/ +class ConnHandler +{ +public: + // constructor + ConnHandler(ArRobot *robot, Joydrive *jd); + // Destructor, its just empty + ~ConnHandler(void) {} + // to be called if the connection was made + void connected(void); + // to call if the connection failed + void connFail(void); + // to be called if the connection was lost + void disconnected(void); +protected: + // robot pointer + ArRobot *myRobot; + // pointer to joydrive + Joydrive *myJoydrive; + // the functor callbacks + ArFunctorC *myConnectedCB; + ArFunctorC *myConnFailCB; + ArFunctorC *myDisconnectedCB; + +}; + +// the mythical constructor +ConnHandler::ConnHandler(ArRobot *robot, Joydrive *jd) +{ + // set the pointers + myRobot = robot; + myJoydrive = jd; + + // now create the functor callbacks, then set them on the robot + myConnectedCB = new ArFunctorC(this, &ConnHandler::connected); + myRobot->addConnectCB(myConnectedCB, ArListPos::FIRST); + myConnFailCB = new ArFunctorC(this, &ConnHandler::connFail); + myRobot->addFailedConnectCB(myConnFailCB, ArListPos::FIRST); + myDisconnectedCB = new ArFunctorC(this, + &ConnHandler::disconnected); + myRobot->addDisconnectNormallyCB(myDisconnectedCB, ArListPos::FIRST); + myRobot->addDisconnectOnErrorCB(myDisconnectedCB, ArListPos::FIRST); +} + +// when we connect turn off the sonar, turn on the motors, and disable amigobot +// sound +void ConnHandler::connected(void) +{ + myRobot->comInt(ArCommands::SONAR, 0); + myRobot->comInt(ArCommands::ENABLE, 1); + myRobot->comInt(ArCommands::SOUNDTOG, 0); +} + +// just exit if we failed to connect +void ConnHandler::connFail(void) +{ + printf("Failed to connect.\n"); + myRobot->stopRunning(); + myJoydrive->stopRunning(); + Aria::exit(2); // exit program with error code 2 +} + +// if we lost connection then exit +void ConnHandler::disconnected(void) +{ + printf("Lost connection\n"); + myRobot->stopRunning(); + myJoydrive->stopRunning(); + Aria::exit(3); // exit program with error code 3 +} + +int main(int argc, char **argv) +{ + std::string str; + int ret; + + // connection to the robot + ArTcpConnection con; + // the robot + ArRobot robot; + + // ake the joydrive object, which also creates its own thread + Joydrive joyd(&robot); + + // the connection handler + ConnHandler ch(&robot, &joyd); + + // init aria, which will make a dedicated signal handling thread + Aria::init(Aria::SIGHANDLE_THREAD); + + // open the connection with default args, exit if it fails + if ((ret = con.open()) != 0) + { + str = con.getOpenMessage(ret); + printf("Open failed: %s\n", str.c_str()); + Aria::shutdown(); + return 1; + } + + + // set the connection on the robot + robot.setDeviceConnection(&con); + + // run the robot in its own thread + robot.runAsync(false); + + // have the robot connect asyncronously (so its loop is still running) + // if this fails it means that the robot isn't running in its own thread + if (!robot.asyncConnect()) + { + printf( + "asyncConnect failed because robot is not running in its own thread.\n"); + Aria::shutdown(); + return 1; + } + + // now we just wait for the robot to be done running + printf("Waiting for the robot's run to exit.\n"); + robot.waitForRunExit(); + // then we exit + printf("exiting main\n"); + Aria::exit(0); // exit program + return 0; +} + + diff --git a/Legacy/Aria/examples/joydriveUserTask-vc2003.vcproj b/Legacy/Aria/examples/joydriveUserTask-vc2003.vcproj new file mode 100644 index 0000000..beeaede --- /dev/null +++ b/Legacy/Aria/examples/joydriveUserTask-vc2003.vcproj @@ -0,0 +1,173 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/examples/joydriveUserTask-vc2008.vcproj b/Legacy/Aria/examples/joydriveUserTask-vc2008.vcproj new file mode 100644 index 0000000..f8dc9ec --- /dev/null +++ b/Legacy/Aria/examples/joydriveUserTask-vc2008.vcproj @@ -0,0 +1,234 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/examples/joydriveUserTask.cpp b/Legacy/Aria/examples/joydriveUserTask.cpp new file mode 100644 index 0000000..04a3139 --- /dev/null +++ b/Legacy/Aria/examples/joydriveUserTask.cpp @@ -0,0 +1,165 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#include "Aria.h" + +/* + This program just drives the robot around with a joystick. + + This example uses a user task which has a joystick handler to drive the + robot. +*/ + +// the clas which'll have the task to drive the robot +class Joydrive +{ +public: + // the constructor + Joydrive(ArRobot *robot); + // the destructor + ~Joydrive(void); + + // the function which'll drive the robot + void drive(void); + +protected: + // the joystick handler + ArJoyHandler myJoyHandler; + // robot pointer + ArRobot *myRobot; + // the callback + ArFunctorC myDriveCB; +}; + +/* + the constructor, note the use of constructor chaining +*/ +Joydrive::Joydrive(ArRobot *robot) : + myDriveCB(this, &Joydrive::drive) +{ + // set the robot, and add joydrive as a task + myRobot = robot; + if (myRobot != NULL) + myRobot->addUserTask("joydrive", 50, &myDriveCB); + + // initialize the joystick handler + myJoyHandler.init(); + // set the values we'll get back out of the joystick handler + myJoyHandler.setSpeeds(100, 700); + + // see if we have the joystick, and let the user know + if (myJoyHandler.haveJoystick()) + { + printf("Have a joystick\n\n"); + } + // we don't have a joystick, exit + else + { + printf("Do not have a joystick, set up the joystick then rerun the program\n\n"); + Aria::exit(1); + } +} + +Joydrive::~Joydrive(void) +{ + // remove the user task from the robot + if (myRobot != NULL) + myRobot->remUserTask(&myDriveCB); +} + +void Joydrive::drive(void) +{ + int trans, rot; + + // print out some data about the robot + printf("\rx %6.1f y %6.1f tth %6.1f vel %7.1f mpacs %3d ", + myRobot->getX(), myRobot->getY(), myRobot->getTh(), + myRobot->getVel(), myRobot->getMotorPacCount()); + fflush(stdout); + + // see if a joystick butotn is pushed, if so drive + if (myJoyHandler.haveJoystick() && (myJoyHandler.getButton(1) || + myJoyHandler.getButton(2))) + { + // get the values out of the joystick handler + myJoyHandler.getAdjusted(&rot, &trans); + // drive the robot + myRobot->setVel(trans); + myRobot->setRotVel(-rot); + } + // if a button isn't pushed, stop the robot + else + { + myRobot->setVel(0); + myRobot->setRotVel(0); + } +} + +int main(int argc, char **argv) +{ + std::string str; + int ret; + + // connection + ArTcpConnection con; + // robot, this starts it with state reflecting turned off + ArRobot robot(NULL, false); + // make the joydrive instance, which adds its task to the robot + Joydrive joyd(&robot); + + // mandatory aria initialization + Aria::init(); + + // open the connection, if it fails, exit + if ((ret = con.open()) != 0) + { + str = con.getOpenMessage(ret); + printf("Open failed: %s\n", str.c_str()); + Aria::exit(1); + return 1; + } + + // set the robots connection + robot.setDeviceConnection(&con); + // try to connect, if we fail exit + if (!robot.blockingConnect()) + { + printf("Could not connect to robot... exiting\n"); + Aria::exit(1); + return 1; + } + + // turn off sonar, turn the motors on, turn off amigobot sound + robot.comInt(ArCommands::SONAR, 0); + robot.comInt(ArCommands::ENABLE, 1); + robot.comInt(ArCommands::SOUNDTOG, 0); + + // run the robot, true so that if connection is lost the run stops + robot.run(true); + // now exit + Aria::exit(0); // exit program + return 0; +} + diff --git a/Legacy/Aria/examples/laserConnect.cpp b/Legacy/Aria/examples/laserConnect.cpp new file mode 100644 index 0000000..50e4e8f --- /dev/null +++ b/Legacy/Aria/examples/laserConnect.cpp @@ -0,0 +1,133 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#include "Aria.h" + +/** @example laserConnect.cpp example showing how to connect to laser rangefinders attached to the robot and retrieve data from them. What kinds of laser or lasers are connected to the robot, and their parameters, are loaded from the robot's parameter file in the params directory. First the default for this type of mobile robot is loaded (e.g. p3dx-sh.p for a Pioneer 3 DX), followed by a parameter file specific to this individual robot (based on its 'name'), if such a parameter file exists. Laser parameters may also be given as command line options, use the -help option to list them. This program will only connect to any lasers that have LaserAutoConnect true in the parameter file, or if the -connectLaser or -cl command-line options are given. You may need to edit the parameter file for your robot to set LaserAutoConnect to true. + + TODO: show how to force laser connect even if autoconnect is false. + * + * This program will work either with the MobileSim simulator or on a real + * robot's onboard computer. (Or use -remoteHost to connect to a wireless + * ethernet-serial bridge.) + */ + +int main(int argc, char **argv) +{ + Aria::init(); + ArLog::init(ArLog::StdErr, ArLog::Verbose); + ArRobot robot; + ArArgumentParser parser(&argc, argv); + parser.loadDefaultArguments(); + + ArRobotConnector robotConnector(&parser, &robot); + ArLaserConnector laserConnector(&parser, &robot, &robotConnector); + + // Connect to the robot, get some initial data from it such as type and name, + // and then load parameter files for this robot. + if(!robotConnector.connectRobot()) + { + ArLog::log(ArLog::Terse, "lasersExample: Could not connect to the robot."); + if(parser.checkHelpAndWarnUnparsed()) + { + // -help not given + Aria::logOptions(); + Aria::exit(1); + } + } + + + if (!Aria::parseArgs()) + { + Aria::logOptions(); + Aria::exit(2); + return 2; + } + + ArLog::log(ArLog::Normal, "lasersExample: Connected to robot."); + + // Start the robot processing cycle running in the background. + // True parameter means that if the connection is lost, then the + // run loop ends. + robot.runAsync(true); + + + // Connect to laser(s) as defined in parameter files. + // (Some flags are available as arguments to connectLasers() to control error behavior and to control which lasers are put in the list of lasers stored by ArRobot. See docs for details.) + if(!laserConnector.connectLasers()) + { + ArLog::log(ArLog::Terse, "Could not connect to configured lasers. Exiting."); + Aria::exit(3); + return 3; + } + + // Allow some time to read laser data + ArUtil::sleep(500); + + ArLog::log(ArLog::Normal, "Connected to all lasers."); + + // Print out some data from each connected laser. + while(robot.isConnected()) + { + int numLasers = 0; + + // Get a pointer to ArRobot's list of connected lasers. We will lock the robot while using it to prevent changes by tasks in the robot's background task thread or any other threads. Each laser has an index. You can also store the laser's index or name (laser->getName()) and use that to get a reference (pointer) to the laser object using ArRobot::findLaser(). + robot.lock(); + std::map *lasers = robot.getLaserMap(); + + for(std::map::const_iterator i = lasers->begin(); i != lasers->end(); ++i) + { + int laserIndex = (*i).first; + ArLaser* laser = (*i).second; + if(!laser) + continue; + ++numLasers; + laser->lockDevice(); + + // The current readings are a set of obstacle readings (with X,Y positions as well as other attributes) that are the most recent set from teh laser. + std::list *currentReadings = laser->getCurrentBuffer(); // see ArRangeDevice interface doc + + // There is a utility to find the closest reading wthin a range of degrees around the laser, here we use this laser's full field of view (start to end) + // If there are no valid closest readings within the given range, dist will be greater than laser->getMaxRange(). + double angle = 0; + double dist = laser->currentReadingPolar(laser->getStartDegrees(), laser->getEndDegrees(), &angle); + + ArLog::log(ArLog::Normal, "Laser #%d (%s): %s. Have %d 'current' readings. Closest reading is at %3.0f degrees and is %2.4f meters away.", laserIndex, laser->getName(), (laser->isConnected() ? "connected" : "NOT CONNECTED"), currentReadings->size(), angle, dist/1000.0); + laser->unlockDevice(); + } + if(numLasers == 0) + ArLog::log(ArLog::Normal, "No lasers."); + else + ArLog::log(ArLog::Normal, ""); + + // Unlock robot and sleep for 5 seconds before next loop. + robot.unlock(); + ArUtil::sleep(5000); + } + + ArLog::log(ArLog::Normal, "lasersExample: exiting."); + Aria::exit(0); + return 0; +} diff --git a/Legacy/Aria/examples/lasers.cpp b/Legacy/Aria/examples/lasers.cpp new file mode 100644 index 0000000..a3f74f9 --- /dev/null +++ b/Legacy/Aria/examples/lasers.cpp @@ -0,0 +1,133 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#include "Aria.h" + +/** @example lasers.cpp example showing how to connect to laser rangefinders attached to the robot and retrieve data from them. What kinds of laser or lasers are connected to the robot, and their parameters, are loaded from the robot's parameter file in the params directory. First the default for this type of mobile robot is loaded (e.g. p3dx-sh.p for a Pioneer 3 DX), followed by a parameter file specific to this individual robot (based on its 'name'), if such a parameter file exists. Laser parameters may also be given as command line options, use the -help option to list them. This program will only connect to any lasers that have LaserAutoConnect true in the parameter file, or if the -connectLaser or -cl command-line options are given. You may need to edit the parameter file for your robot to set LaserAutoConnect to true. + + TODO: show how to force laser connect even if autoconnect is false. + * + * This program will work either with the MobileSim simulator or on a real + * robot's onboard computer. (Or use -remoteHost to connect to a wireless + * ethernet-serial bridge.) + */ + +int main(int argc, char **argv) +{ + Aria::init(); + ArLog::init(ArLog::StdErr, ArLog::Verbose); + ArRobot robot; + ArArgumentParser parser(&argc, argv); + parser.loadDefaultArguments(); + + ArRobotConnector robotConnector(&parser, &robot); + ArLaserConnector laserConnector(&parser, &robot, &robotConnector); + + // Connect to the robot, get some initial data from it such as type and name, + // and then load parameter files for this robot. + if(!robotConnector.connectRobot()) + { + ArLog::log(ArLog::Terse, "lasersExample: Could not connect to the robot."); + if(parser.checkHelpAndWarnUnparsed()) + { + // -help not given + Aria::logOptions(); + Aria::exit(1); + } + } + + + if (!Aria::parseArgs()) + { + Aria::logOptions(); + Aria::exit(2); + return 2; + } + + ArLog::log(ArLog::Normal, "lasersExample: Connected to robot."); + + // Start the robot processing cycle running in the background. + // True parameter means that if the connection is lost, then the + // run loop ends. + robot.runAsync(true); + + + // Connect to laser(s) as defined in parameter files. + // (Some flags are available as arguments to connectLasers() to control error behavior and to control which lasers are put in the list of lasers stored by ArRobot. See docs for details.) + if(!laserConnector.connectLasers()) + { + ArLog::log(ArLog::Terse, "Could not connect to configured lasers. Exiting."); + Aria::exit(3); + return 3; + } + + // Allow some time to read laser data + ArUtil::sleep(500); + + ArLog::log(ArLog::Normal, "Connected to all lasers."); + + // Print out some data from each connected laser. + while(robot.isConnected()) + { + int numLasers = 0; + + // Get a pointer to ArRobot's list of connected lasers. We will lock the robot while using it to prevent changes by tasks in the robot's background task thread or any other threads. Each laser has an index. You can also store the laser's index or name (laser->getName()) and use that to get a reference (pointer) to the laser object using ArRobot::findLaser(). + robot.lock(); + std::map *lasers = robot.getLaserMap(); + + for(std::map::const_iterator i = lasers->begin(); i != lasers->end(); ++i) + { + int laserIndex = (*i).first; + ArLaser* laser = (*i).second; + if(!laser) + continue; + ++numLasers; + laser->lockDevice(); + + // The current readings are a set of obstacle readings (with X,Y positions as well as other attributes) that are the most recent set from teh laser. + std::list *currentReadings = laser->getCurrentBuffer(); // see ArRangeDevice interface doc + + // There is a utility to find the closest reading wthin a range of degrees around the laser, here we use this laser's full field of view (start to end) + // If there are no valid closest readings within the given range, dist will be greater than laser->getMaxRange(). + double angle = 0; + double dist = laser->currentReadingPolar(laser->getStartDegrees(), laser->getEndDegrees(), &angle); + + ArLog::log(ArLog::Normal, "Laser #%d (%s): %s. Have %d 'current' readings. Closest reading is at %3.0f degrees and is %2.4f meters away.", laserIndex, laser->getName(), (laser->isConnected() ? "connected" : "NOT CONNECTED"), currentReadings->size(), angle, dist/1000.0); + laser->unlockDevice(); + } + if(numLasers == 0) + ArLog::log(ArLog::Normal, "No lasers."); + else + ArLog::log(ArLog::Normal, ""); + + // Unlock robot and sleep for 5 seconds before next loop. + robot.unlock(); + ArUtil::sleep(5000); + } + + ArLog::log(ArLog::Normal, "lasersExample: exiting."); + Aria::exit(0); + return 0; +} diff --git a/Legacy/Aria/examples/lineFinderExample.cpp b/Legacy/Aria/examples/lineFinderExample.cpp new file mode 100644 index 0000000..cb597cd --- /dev/null +++ b/Legacy/Aria/examples/lineFinderExample.cpp @@ -0,0 +1,103 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#include "Aria.h" + +/** @example lineFinderExample.cpp Simple example of Aria's line-finder utility, + * which uses data from a laser rangefinder to detect a continues line of + * points. + * + * This example program will constantly search for a line-like pattern in the + * sensor readings of a laser rangefinder. If you press the 'f' key, those + * points will be saved in 'points' and 'lines' files. Use arrow keys or + * joystick to teleoperate the robot. + */ + +int main(int argc, char **argv) +{ + Aria::init(); + + ArSimpleConnector connector(&argc, argv); + ArRobot robot; + ArSick sick; + + if (!Aria::parseArgs() || argc > 1) + { + Aria::logOptions(); + Aria::exit(1); // exit program with error code 1 + return 1; + } + + ArKeyHandler keyHandler; + Aria::setKeyHandler(&keyHandler); + robot.attachKeyHandler(&keyHandler); + + + robot.addRangeDevice(&sick); + + // Create the ArLineFinder object. Set it to log lots of information about its + // processing. + ArLineFinder lineFinder(&sick); + lineFinder.setVerbose(true); + + // Add key callbacks that simply call the ArLineFinder::getLinesAndSaveThem() + // function, which searches for lines in the current set of laser sensor + // readings, and saves them in files with the names 'points' and 'lines'. + ArFunctorC findLineCB(&lineFinder, + &ArLineFinder::getLinesAndSaveThem); + keyHandler.addKeyHandler('f', &findLineCB); + keyHandler.addKeyHandler('F', &findLineCB); + + + ArLog::log(ArLog::Normal, "lineFinderExample: connecting to robot..."); + if (!connector.connectRobot(&robot)) + { + printf("Could not connect to robot... exiting\n"); + Aria::exit(1); // exit program with error code 1 + return 1; + } + robot.runAsync(true); + + // now set up the laser + ArLog::log(ArLog::Normal, "lineFinderExample: connecting to SICK laser..."); + connector.setupLaser(&sick); + sick.runAsync(); + if (!sick.blockingConnect()) + { + printf("Could not connect to SICK laser... exiting\n"); + Aria::exit(1); + return 1; + } + + printf("If you press the 'f' key the points and lines found will be saved\n"); + printf("Into the 'points' and 'lines' file in the current working directory\n"); + + robot.waitForRunExit(); + Aria::exit(0); + return 0; +} + + + diff --git a/Legacy/Aria/examples/moduleExample.cpp b/Legacy/Aria/examples/moduleExample.cpp new file mode 100644 index 0000000..32f92e6 --- /dev/null +++ b/Legacy/Aria/examples/moduleExample.cpp @@ -0,0 +1,103 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#include "Aria.h" + + +/** @example moduleExample.cpp Example demonstrating how to load an ArModule + * + This is a simple program that loads the module moduleExample_Mod, which is + defined in moduleExample_Mod.cpp. The + program simply calls ArModuleLoader::load() with a short message + argument and ArModuleLoader::reload with no argument and finally + calls ArModuleLoader::close(). The return status of the load(), + reload(), and close() are checked and printed out. + ArModuleLoader uses the name of the module file without the platform-specific + suffix (i.e. ".dll" on Windows and ".so" on Linux) to load the module. + + @sa moduleExample_Mod.cpp. + @sa ArModuleLoader in the reference manual. +*/ + + +void printStatus(ArModuleLoader::Status status) +{ + if (status == ArModuleLoader::STATUS_ALREADY_LOADED) + ArLog::log(ArLog::Terse, "moduleExample: Module already loaded."); + else if (status == ArModuleLoader::STATUS_FAILED_OPEN) + ArLog::log(ArLog::Terse, "moduleExample: Failed to find or open the simpleMod module."); + else if (status == ArModuleLoader::STATUS_INVALID) + ArLog::log(ArLog::Terse, "moduleExample: Invalid file."); + else if (status == ArModuleLoader::STATUS_INIT_FAILED) + ArLog::log(ArLog::Terse, "moduleExample: Module Init failed."); + else if (status == ArModuleLoader::STATUS_SUCCESS) + ArLog::log(ArLog::Terse, "moduleExample: Module succedded."); + else if (status == ArModuleLoader::STATUS_EXIT_FAILED) + ArLog::log(ArLog::Terse, "moduleExample: Module exit sequence failed."); + else if (status == ArModuleLoader::STATUS_NOT_FOUND) + ArLog::log(ArLog::Terse, "moduleExample: Module not found."); + else + ArLog::log(ArLog::Terse, "moduleExample: Module returned unknown status!"); + ArLog::log(ArLog::Terse, ""); +} + +int main(int argc, char **argv) +{ + + Aria::init(); + + ArArgumentParser parser(&argc, argv); + // set up our simple connector + ArSimpleConnector simpleConnector(&parser); + ArRobot robot; + + // set up the robot for connecting + if (!simpleConnector.connectRobot(&robot)) + { + printf("Could not connect to robot... exiting\n"); + Aria::exit(1); + } + + robot.runAsync(true); + + ArModuleLoader::Status status; + std::string str; + + ArLog::log(ArLog::Terse, "moduleExample: Loading the module \"moduleExample_Mod\" with a string argument..."); + status=ArModuleLoader::load("./moduleExample_Mod", &robot, (char *)"You've loaded a module!"); + printStatus(status); + //ArLog::log(ArLog::Terse, "moduleExample: Reloading the module with no argument..."); + //status=ArModuleLoader::reload("./moduleExample_Mod", &robot); + //printStatus(status); + + //ArLog::log(ArLog::Terse, "moduleExample: Closing the module..."); + //status=ArModuleLoader::close("./moduleExample_Mod"); + //printStatus(status); + + ArUtil::sleep(3000); + + Aria::exit(0); + return(0); +} diff --git a/Legacy/Aria/examples/moduleExample.vcproj b/Legacy/Aria/examples/moduleExample.vcproj new file mode 100644 index 0000000..5f4760c --- /dev/null +++ b/Legacy/Aria/examples/moduleExample.vcproj @@ -0,0 +1,148 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/examples/moduleExample_Mod.cpp b/Legacy/Aria/examples/moduleExample_Mod.cpp new file mode 100644 index 0000000..a5808c3 --- /dev/null +++ b/Legacy/Aria/examples/moduleExample_Mod.cpp @@ -0,0 +1,85 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#include "Aria.h" + + +/** @example moduleExample_Mod.cpp + * @brief Example demonstrating how to implement a module with ArModule + * + This is a simple example of how to define a module of code that Aria's ArModuleLoader class can dynamically load at runtime. + On Windows, loadable modules are DLL files. On Linux, they are shared object (.so) + files (ARIA's Makefiles can compile any source file ending in "Mod.cpp" into + a .so, so to build this module, run "make moduleExample_Mod.so"). + ArModuleLoader knows about these platform conventions, so only the base name + (without the .dll or .so suffix) is used to load it. + To implement a loadable module, you derive a class from ArModule, + instantiate the pure virtual functions init() and exit(), and create an + instance of that class. The two functions simply print out the equivalent + of Hello World. An important part is the global instance of the class + and the call to the macro ARDEF_MODULE(). Without that macro invocation, + Aria will never be able to invoke those two functions. + + The program moduleExample.cpp is designed to load this module and check the + error return. + + @sa moduleExample.cpp. + @sa ArModule in the reference manual. +*/ + + +class SimpleMod : public ArModule +{ +public: + + bool init(ArRobot *robot, void *argument = NULL); + bool exit(); +}; + +SimpleMod aModule; +ARDEF_MODULE(aModule); + +bool SimpleMod::init(ArRobot *robot, void *argument) +{ + ArLog::log(ArLog::Terse, "module: init(%p) called in the loaded module!", robot); + if (argument != NULL) + ArLog::log(ArLog::Terse, "module: Argument given to ArModuleLoader::load was the string '%s'.", + (char *)argument); + else + ArLog::log(ArLog::Terse, "module: No argument was given to ArModuleLoader (this is OK)."); + + // Do stuff here... + + return(true); +} + +bool SimpleMod::exit() +{ + ArLog::log(ArLog::Terse, "module: exit() called."); + + // Do stuff here... + + return(true); +} diff --git a/Legacy/Aria/examples/moduleExample_Mod.vcproj b/Legacy/Aria/examples/moduleExample_Mod.vcproj new file mode 100644 index 0000000..c8e2c2d --- /dev/null +++ b/Legacy/Aria/examples/moduleExample_Mod.vcproj @@ -0,0 +1,158 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/examples/mtxIO.cpp b/Legacy/Aria/examples/mtxIO.cpp new file mode 100644 index 0000000..795c4b7 --- /dev/null +++ b/Legacy/Aria/examples/mtxIO.cpp @@ -0,0 +1,159 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#include "Aria.h" +#include "ArMTXIO.h" + +/** @example mtxIO.cpp Sets patterns on digital outputs and acts on digital + * inputs. Attach LEDs to the outputs and buttons to the digital inputs to + * use. (See the Pioneer LX manual and robots.mobilerobots.com for more + * details.) + * The 'mtx' Linux kernel module must be loaded, and the /dev/mtx character + * device must have been created (see mtxIODriver documentation). You must + * have read/write access to /dev/mtx. + */ + +void printBits(unsigned short c) { + int i; + for (i=0; i < 16; i++) { + if (i == 8) { + ArLog::log(ArLog::Normal, " "); + } + if (0x8000 & (c << i)) { + ArLog::log(ArLog::Normal, "1"); + } + else { + ArLog::log(ArLog::Normal, "0"); + } + } + ArLog::log(ArLog::Normal, " (0x%04x) ", c); +} + +int main(int argc, char **argv) +{ + Aria::init(); + ArArgumentParser parser(&argc, argv); + parser.loadDefaultArguments(); + ArRobot robot; + + ArRobotConnector robotConnector(&parser, &robot); + if(!robotConnector.connectRobot()) + { + ArLog::log(ArLog::Terse, "mtxIO: Could not connect to the robot."); + if(parser.checkHelpAndWarnUnparsed()) + { + // -help not given + Aria::logOptions(); + Aria::exit(1); + } + } + + if (!Aria::parseArgs() || !parser.checkHelpAndWarnUnparsed()) + { + Aria::logOptions(); + Aria::exit(1); + } + ArLog::log(ArLog::Normal, "mtxIO: Connected."); + robot.comInt(ArCommands::JOYINFO, 0); + + ArMTXIO mtxIO; + + if(!mtxIO.isEnabled()) + { + ArLog::log(ArLog::Terse, "mtxIO: Error opening MTX IO device interface!"); + Aria::exit(4); + } + + robot.runAsync(true); + + unsigned char out = 1; + while(true) + { + mtxIO.lock(); + + // print state of inputs + unsigned char inp; + mtxIO.getDigitalInputMon1(&inp); + printBits(inp); + mtxIO.getDigitalInputMon2(&inp); + printBits(inp); + + + +/* shouldn't be neccesary + unsigned char cur; + + // get current state + if(!mtxIO.getDigitalOutputControl1(&cur)) + { + ArLog::log(ArLog::Terse, "mtxIO: Error getting current state of output control 1"); + mtxIO.unlock(); + Aria::exit(2); + } +*/ + + // set new state on both output banks + + if(!mtxIO.setDigitalOutputControl1(&out)) + { + ArLog::log(ArLog::Terse, "mtxIO: Error setting state of output control 1"); + mtxIO.unlock(); + Aria::exit(3); + } + + if(!mtxIO.setDigitalOutputControl2(&out)) + { + ArLog::log(ArLog::Terse, "mtxIO: Error setting state of output control 2"); + mtxIO.unlock(); + Aria::exit(3); + } + + // wait + mtxIO.unlock(); + ArUtil::sleep(500); + + // shift + + out = out << 1; + if(out == 0) out = 1; + + } + + + Aria::exit(0); + + // wait + mtxIO.unlock(); + ArUtil::sleep(500); + + // shift + out = out << 1; + if(out == 0) out = 1; + } + + + Aria::exit(0); + +} diff --git a/Legacy/Aria/examples/mtxLCDDisplay.cpp b/Legacy/Aria/examples/mtxLCDDisplay.cpp new file mode 100644 index 0000000..59634a2 --- /dev/null +++ b/Legacy/Aria/examples/mtxLCDDisplay.cpp @@ -0,0 +1,86 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#include "Aria.h" + +/** @example mtxLCDDisplay.cpp Display text on the MTX LCD display */ + +int main(int argc, char **argv) +{ + Aria::init(); + ArArgumentParser parser(&argc, argv); + parser.loadDefaultArguments(); + ArRobot robot; + + ArRobotConnector robotConnector(&parser, &robot); + if(!robotConnector.connectRobot()) + { + ArLog::log(ArLog::Terse, "mtxLCDDisplay: Could not connect to the robot."); + if(parser.checkHelpAndWarnUnparsed()) + { + // -help not given + Aria::logOptions(); + Aria::exit(1); + } + } + + if (!Aria::parseArgs() || !parser.checkHelpAndWarnUnparsed()) + { + Aria::logOptions(); + Aria::exit(1); + } + + robot.comInt(ArCommands::JOYINFO, 0); + + robot.runAsync(true); // ArLCDMTX uses an ArRobot task to communicate with the LCD. + + ArLCDMTX* lcd = robot.findLCD(1); + if(!lcd) + { + ArLog::log(ArLog::Normal, "Not connected to an LCD display. Use --help for options to customize nonstandard LCD connections."); + Aria::exit(2); + } + + lcd->setMainStatus("Hello, world."); + lcd->setTextStatus("text status"); + +#if 0 + for(unsigned char i = 0; i < 100; i += 10) + { + ArUtil::sleep(200); + lcd->setSystemMeters(i, i); + } + for(unsigned char i = 100; i >= 0; i -= 10) + { + ArUtil::sleep(200); + lcd->setSystemMeters(i, i); + } +#endif + + robot.waitForRunExit(); + + Aria::exit(0); + return 0; +} diff --git a/Legacy/Aria/examples/mtxPowerControl.cpp b/Legacy/Aria/examples/mtxPowerControl.cpp new file mode 100644 index 0000000..5a29f89 --- /dev/null +++ b/Legacy/Aria/examples/mtxPowerControl.cpp @@ -0,0 +1,114 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#include "Aria.h" +#include "ArMTXIO.h" + +/** @example mtxPowerControl.cpp Shows how to turn power outputs on and off on + * MTX. + * The 'mtx' Linux kernel module must be loaded, and the /dev/mtx character + * device must have been created (see mtxPowerControlDriver documentation). You must + * have read/write access to /dev/mtx. + */ + +void testPower(ArMTXIO& io, const char* name, int bank, int bit, const char *conndesc) +{ + io.lock(); + ArLog::log(ArLog::Terse, "mtxPowerControl: Turning on %s (bank %d bit %d) for 3 seconds. This is at connector %s", name, bank, bit, conndesc); + io.setPowerOutput(bank, bit, true); + io.unlock(); + ArUtil::sleep(3000); + io.lock(); + ArLog::log(ArLog::Terse, "mtxPowerControl: Turning off %s.", name); + io.setPowerOutput(bank, bit, false); + io.unlock(); + ArUtil::sleep(3000); +} + +int main(int argc, char **argv) +{ + Aria::init(); + ArArgumentParser parser(&argc, argv); + parser.loadDefaultArguments(); + ArRobot robot; + + ArRobotConnector robotConnector(&parser, &robot); + if(!robotConnector.connectRobot()) + { + ArLog::log(ArLog::Terse, "mtxPowerControl: Could not connect to the robot."); + if(parser.checkHelpAndWarnUnparsed()) + { + // -help not given + Aria::logOptions(); + Aria::exit(1); + } + } + + if (!Aria::parseArgs() || !parser.checkHelpAndWarnUnparsed()) + { + Aria::logOptions(); + Aria::exit(1); + } + ArLog::log(ArLog::Normal, "mtxPowerControl: Connected."); + robot.comInt(ArCommands::JOYINFO, 0); + + ArMTXIO io; + + if(!io.isEnabled()) + { + ArLog::log(ArLog::Terse, "mtxPowerControl: Error opening MTX IO device interface!"); + Aria::exit(4); + } + + robot.runAsync(true); + + // Note that bank and bits are 0-indexed, so 1 is subtracted here to effect + // that. + testPower(io, "Aux_5V_Out", 3-1, 1-1, "AUX POWER pin #4"); + testPower(io, "Aux_12V_Out", 3-1, 2-1, "AUX POWER pin #5"); + testPower(io, "Aux_20V_Out", 3-1, 3-1, "AUX POWER pin #6"); + testPower(io, "Aux_24V_Raw_1", 2-1, 5-1, "USER POWER pin #7"); + testPower(io, "Aux_24V_Raw_2", 2-1, 6-1, "USER POWER pin #8"); + testPower(io, "Aux_24V_Raw_3_4", 2-1, 7-1, "USER POWER pins 9, 10 (no estop), 11, 12 with estop)"); + + + // You can control power to robot components as well. See manual for more + // info. + // LRF power is bank 1 bit 3 + // Wheel lights is bank 1 bit 6 + // Sonar 1 power is bank 1 bit 7 + // Sonar 2 power is bank 1 bit 8 + // Audio amp. is bank 3 bit 5 + // USB 1+2 is Bank 2 bit 1 (USB12_5V_SW on AUX SENSORS pin 9, and on USB connectors 1 and 2) + // USB 3 is Bank 2 bit 2 (USB3_5V_SW on AUX SENSORS pin 14, and on USB connector 3) + // Aux laser 1 power is bank 2 bit 3 (vert) (Vertical_Laser_Power, AUX SENSORS pins 5 and 10) + // Aux laser 2 power is bank 2 bit 4 (foot) (Foot_Laser_Power, AUX SENSORS pin 15 + + + + ArLog::log(ArLog::Terse, "mtxPowerControl: Exit"); + Aria::exit(0); + +} diff --git a/Legacy/Aria/examples/mtxWheelLights.cpp b/Legacy/Aria/examples/mtxWheelLights.cpp new file mode 100644 index 0000000..72a80ee --- /dev/null +++ b/Legacy/Aria/examples/mtxWheelLights.cpp @@ -0,0 +1,106 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#include "Aria.h" + +/** @example mtxWheelLights.cpp Shows possible MTX wheel lamp states */ + +int main(int argc, char **argv) +{ + Aria::init(); + ArArgumentParser parser(&argc, argv); + parser.loadDefaultArguments(); + ArRobot robot; + + ArRobotConnector robotConnector(&parser, &robot); + if(!robotConnector.connectRobot()) + { + ArLog::log(ArLog::Terse, "mtxWheelLights: Could not connect to the robot."); + if(parser.checkHelpAndWarnUnparsed()) + { + // -help not given + Aria::logOptions(); + Aria::exit(1); + } + } + + if (!Aria::parseArgs() || !parser.checkHelpAndWarnUnparsed()) + { + Aria::logOptions(); + Aria::exit(1); + } + ArLog::log(ArLog::Normal, "mtxWheelLights: Connected."); + robot.runAsync(true); + + struct { + ArTypes::UByte pattern; + ArTypes::Byte value; + ArTypes::UByte flags; + ArTypes::UByte flags2; + } lamp; + + lamp.value = 0; + lamp.flags = 0; + lamp.flags2 = 0; + + const int sleeptime = 3000; + + for(lamp.pattern = 1; lamp.pattern <= 10; ++(lamp.pattern)) + { + ArLog::log(ArLog::Normal, "mtxWheelLights: pattern %d...", lamp.pattern); + robot.comDataN(ArCommands::WHEEL_LIGHT, (const char*)&lamp, 4); + ArUtil::sleep(sleeptime); + + if(lamp.pattern == 6) + { + for(lamp.value = 0; lamp.value <= 100; lamp.value += 10) + { + ArLog::log(ArLog::Normal, "mtxWheelLights: pattern %d with value %d...", lamp.pattern, lamp.value); + robot.comDataN(ArCommands::WHEEL_LIGHT, (const char*)&lamp, 4); + ArUtil::sleep(sleeptime); + } + lamp.value = 0; + } + else + { + lamp.value = 50; + ArLog::log(ArLog::Normal, "mtxWheelLights: patterd %d with value 50...", lamp.pattern); + robot.comDataN(ArCommands::WHEEL_LIGHT, (const char*)&lamp, 4); + ArUtil::sleep(sleeptime); + lamp.value = 0; + } + + + ArLog::log(ArLog::Normal, "mtxWheelLights: pattern %d with warning flag...", lamp.pattern); + lamp.flags |= ArUtil::BIT1; + robot.comDataN(ArCommands::WHEEL_LIGHT, (const char*)&lamp, 4); + ArUtil::sleep(sleeptime); + lamp.flags = 0; + } + + ArLog::log(ArLog::Normal, "mtxWheelLights: Exiting."); + Aria::exit(0); + return 0; +} diff --git a/Legacy/Aria/examples/netServerExample-vc2003.vcproj b/Legacy/Aria/examples/netServerExample-vc2003.vcproj new file mode 100644 index 0000000..daeb328 --- /dev/null +++ b/Legacy/Aria/examples/netServerExample-vc2003.vcproj @@ -0,0 +1,156 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/examples/netServerExample-vc2008.vcproj b/Legacy/Aria/examples/netServerExample-vc2008.vcproj new file mode 100644 index 0000000..35263cd --- /dev/null +++ b/Legacy/Aria/examples/netServerExample-vc2008.vcproj @@ -0,0 +1,212 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/examples/netServerExample-vc2010.vcxproj b/Legacy/Aria/examples/netServerExample-vc2010.vcxproj new file mode 100644 index 0000000..f020c26 --- /dev/null +++ b/Legacy/Aria/examples/netServerExample-vc2010.vcxproj @@ -0,0 +1,144 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + netServerExample + {806CF3BE-8A4D-4C32-8574-58F3E85CA08C} + + + + Application + false + MultiByte + + + Application + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + .\../bin\ + ../obj/$(ProjectName)-$(Configuration)-VC10/ + false + .\../bin\ + ../obj/$(ProjectName)-$(Configuration)-VC10/ + false + $(ProjectName).DebugVC10 + + + + $(IntDir)$(ProjectName)-$(Configuration)-BuildLog.htm + + + .\../bin/netServerSimple.tlb + + + + + MaxSpeed + OnlyExplicitInline + ..\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + true + true + + + Level3 + true + + + Default + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + AriaVC10.lib + 1.0 + true + ..\lib;%(AdditionalLibraryDirectories) + false + Console + false + + + MachineX86 + + + + + $(IntDir)$(ProjectName)-$(Configuration)-BuildLog.htm + + + .\../bin/netServerSimple.tlb + + + + + Disabled + ..\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + true + true + + + true + Level3 + true + + + Default + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + AriaDebugVC10.lib + 1.0 + true + ..\lib;%(AdditionalLibraryDirectories) + false + Console + false + + + MachineX86 + + + + + + + + + \ No newline at end of file diff --git a/Legacy/Aria/examples/netServerExample.cpp b/Legacy/Aria/examples/netServerExample.cpp new file mode 100644 index 0000000..350b78f --- /dev/null +++ b/Legacy/Aria/examples/netServerExample.cpp @@ -0,0 +1,91 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#include "Aria.h" + +/** @example netServerExample.cpp Shows how to use ArNetServer, a simple text + * command receiver + */ + +// To use the net server, start this program, then use the 'telnet' program to connect to localhost +// on TCP port 7171 by running this command: +// telnet localhost 7171 +// When connected and prompted for a password, type in: +// password +// and press enter. Then you can enter a command. Use the 'help' command to print available commands. +// For this program, try "test" and "test2" with and without additional arguments. +// ArNetServer is a simple way to provide a quick remote control interface for a robot control +// program running on the robot's onboard computer over wireless networking, if you don't want to +// use the ArNetworking library and MobileEyes. (You can provide both options in a program however, +// ArNetworking and ArNetServer use different TCP ports and will both run fine in the same program.) + +// This function just prints out what the client entered and then sends some +// data back. You could modify it to, for example, control the robot with +// different commands. +void test(char **argv, int argc, ArSocket *socket) +{ + int i; + printf("Client said: "); + for (i = 0; i < argc; ++i) + printf("\t%s\n", argv[i]); + printf("\n"); + socket->writeString("Thank you, command received."); +} + + +int main(int argc, char **argv) +{ + // Initialize Aria + Aria::init(); + // we need a server + ArNetServer server; + // a callback for our test function + ArGlobalFunctor3 testCB(&test); + + // start the server up without a robot on port 7171 with a password + // of password and allow multiple clients + if (!server.open(NULL, 7171, "password", true)) + { + printf("Could not open server.\n"); + Aria::exit(1); + return 1; + } + + // add our test command + server.addCommand("test", &testCB, "this simply prints out the command given on the server"); + server.addCommand("test2", &testCB, "this simply prints out the command given on the server"); + + //server.setLoggingDataSent(true); + //server.setLoggingDataReceived(true); + // run while the server is running + while (server.isOpen() && Aria::getRunning()) + { + server.runOnce(); + ArUtil::sleep(1); + } + server.close(); + Aria::exit(0); + return 0; +} diff --git a/Legacy/Aria/examples/robotConnectionCallbacks.cpp b/Legacy/Aria/examples/robotConnectionCallbacks.cpp new file mode 100644 index 0000000..9839c3e --- /dev/null +++ b/Legacy/Aria/examples/robotConnectionCallbacks.cpp @@ -0,0 +1,144 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#include "Aria.h" + +/** @example robotConnectionCallbacks.cpp Demonstrates how callbacks can be registered with ArRobot to be + * called when a connection succeeds or fails. +*/ + +/* + This class contains the methods called by the connection callback functors. +*/ +class ConnHandler +{ +public: + // Constructor + ConnHandler(ArRobot *robot); + + // Destructor, its just empty + ~ConnHandler(void) {} + + // called if the connection was sucessfully made + void connected(void); + + // called if the connection failed. stop the robot processing thread. + void connectionFailed(void); + + // called when the connection is closed + void disconnected(void); + + // called if the connection is lost due to an error + void connectionLost(void); + +protected: + // keep a robot pointer + ArRobot *myRobot; + + // the functor callbacks + ArFunctorC myConnectedCB; + ArFunctorC myConnFailCB; + ArFunctorC myDisconnectedCB; + ArFunctorC myConnLostCB; +}; + +/* ConnHandler constructor. Initialize functor objects, then + * add them as connection handler callbacks with the robot object. +*/ +ConnHandler::ConnHandler(ArRobot *robot) : + myConnectedCB(this, &ConnHandler::connected), + myConnFailCB(this, &ConnHandler::connectionFailed), + myDisconnectedCB(this, &ConnHandler::disconnected), + myConnLostCB(this, &ConnHandler::connectionLost) + +{ + // keep a robot pointer for use by the handler callback methods + myRobot = robot; + + // add the callbacks to the robot + myRobot->addConnectCB(&myConnectedCB, ArListPos::FIRST); + myRobot->addFailedConnectCB(&myConnFailCB, ArListPos::FIRST); + myRobot->addDisconnectNormallyCB(&myDisconnectedCB, ArListPos::FIRST); + myRobot->addDisconnectOnErrorCB(&myDisconnectedCB, ArListPos::FIRST); +} + +// just exit if the connection failed +void ConnHandler::connectionFailed(void) +{ + ArLog::log(ArLog::Normal, "ConnHandler: Connection failed. Exiting the program."); + Aria::exit(1); +} + +void ConnHandler::connected(void) +{ + ArLog::log(ArLog::Normal, "ConnHandler: Connected. Turning off sonar,"); + // turn off sonar, turn off amigobot sounds + myRobot->comInt(ArCommands::SONAR, 0); + myRobot->comInt(ArCommands::SOUNDTOG, 0); +} + +// disconnected +void ConnHandler::disconnected(void) +{ + ArLog::log(ArLog::Normal, "ConnHandler: Connection closed. Exiting the program."); + Aria::exit(0); +} + +// lost connection due to errror, exit +void ConnHandler::connectionLost(void) +{ + ArLog::log(ArLog::Normal, "ConnHandler: Lost connection due to an error! Exiting the program!"); + Aria::exit(1); +} + + + +int main(int argc, char **argv) +{ + Aria::init(); + ArRobot robot; + ArArgumentParser argParser(&argc, argv); + ArSimpleConnector con(&argParser); + if(!Aria::parseArgs() || !argParser.checkHelpAndWarnUnparsed()) + { + Aria::logOptions(); + return 1; + } + + // Create a connection handler object, defined above, then try to connect to the + // robot. + ConnHandler ch(&robot); + con.connectRobot(&robot); + robot.runAsync(true); + + // Sleep for 10 seconds, then request that ArRobot stop its thread. + ArLog::log(ArLog::Normal, "Sleeping for 10 seconds..."); + ArUtil::sleep(10000); + ArLog::log(ArLog::Normal, "...requesting that the robot thread exit, then shutting down ARIA and exiting."); + robot.stopRunning(); + Aria::exit(0); + return 0; +} + diff --git a/Legacy/Aria/examples/robotSyncTaskExample-vc2003.vcproj b/Legacy/Aria/examples/robotSyncTaskExample-vc2003.vcproj new file mode 100644 index 0000000..7d3a58e --- /dev/null +++ b/Legacy/Aria/examples/robotSyncTaskExample-vc2003.vcproj @@ -0,0 +1,156 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/examples/robotSyncTaskExample-vc2008.vcproj b/Legacy/Aria/examples/robotSyncTaskExample-vc2008.vcproj new file mode 100644 index 0000000..e0e0168 --- /dev/null +++ b/Legacy/Aria/examples/robotSyncTaskExample-vc2008.vcproj @@ -0,0 +1,212 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/examples/robotSyncTaskExample-vc2010.vcxproj b/Legacy/Aria/examples/robotSyncTaskExample-vc2010.vcxproj new file mode 100644 index 0000000..c48c67f --- /dev/null +++ b/Legacy/Aria/examples/robotSyncTaskExample-vc2010.vcxproj @@ -0,0 +1,144 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + robotSyncTaskExample + {69571F42-5098-41FB-B8A8-19ECCCDB9BB3} + + + + Application + false + MultiByte + + + Application + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + .\../bin\ + ../obj/$(ProjectName)-$(Configuration)-VC10/ + false + .\../bin\ + ../obj/$(ProjectName)-$(Configuration)-VC10/ + false + $(ProjectName).DebugVC10 + + + + $(IntDir)$(ProjectName)-$(Configuration)-BuildLog.htm + + + .\../bin/simpleUserTask.tlb + + + + + Disabled + ..\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + true + true + + + true + Level3 + true + + + Default + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + AriaDebugVC10.lib + 1.0 + true + ..\lib;%(AdditionalLibraryDirectories) + false + Console + false + + + MachineX86 + + + + + $(IntDir)$(ProjectName)-$(Configuration)-BuildLog.htm + + + .\../bin/simpleUserTask.tlb + + + + + MaxSpeed + OnlyExplicitInline + ..\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + true + true + + + Level3 + true + + + Default + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + AriaVC10.lib + 1.0 + true + ..\lib;%(AdditionalLibraryDirectories) + false + Console + false + + + MachineX86 + + + + + + + + + \ No newline at end of file diff --git a/Legacy/Aria/examples/robotSyncTaskExample.cpp b/Legacy/Aria/examples/robotSyncTaskExample.cpp new file mode 100644 index 0000000..57474c0 --- /dev/null +++ b/Legacy/Aria/examples/robotSyncTaskExample.cpp @@ -0,0 +1,130 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#include "Aria.h" + +/** @example robotSyncTaskExample.cpp Shows how to add a task callback to ArRobot's synchronization/processing cycle + + A sensor interpretation task callback is invoked + by the ArRobot object every cycle as it runs, which records the robot's current + pose and velocity. + + Note that tasks must take a small amount of time to execute, to avoid delaying the + robot cycle. +*/ + +class PrintingTask +{ +public: + // Constructor. Adds our 'user task' to the given robot object. + PrintingTask(ArRobot *robot); + + // Destructor. Removes our user task from the robot + ~PrintingTask(void); + + // This method will be called by the callback functor + void doTask(void); +protected: + ArRobot *myRobot; + + // The functor to add to the robot for our 'user task'. + ArFunctorC myTaskCB; +}; + + +// the constructor (note how it uses chaining to initialize myTaskCB) +PrintingTask::PrintingTask(ArRobot *robot) : + myTaskCB(this, &PrintingTask::doTask) +{ + myRobot = robot; + // just add it to the robot + myRobot->addSensorInterpTask("PrintingTask", 50, &myTaskCB); +} + +PrintingTask::~PrintingTask() +{ + myRobot->remSensorInterpTask(&myTaskCB); +} + +void PrintingTask::doTask(void) +{ + // print out some info about the robot + printf("\rx %6.1f y %6.1f th %6.1f vel %7.1f mpacs %3d", myRobot->getX(), + myRobot->getY(), myRobot->getTh(), myRobot->getVel(), + myRobot->getMotorPacCount()); + fflush(stdout); + + // Need sensor readings? Try myRobot->getRangeDevices() to get all + // range devices, then for each device in the list, call lockDevice(), + // getCurrentBuffer() to get a list of recent sensor reading positions, then + // unlockDevice(). +} + +int main(int argc, char** argv) +{ + // the connection + ArSimpleConnector con(&argc, argv); + if(!con.parseArgs()) + { + con.logOptions(); + return 1; + } + + // robot + ArRobot robot; + + // sonar array range device + ArSonarDevice sonar; + + // This object encapsulates the task we want to do every cycle. + // Upon creation, it puts a callback functor in the ArRobot object + // as a 'user task'. + PrintingTask pt(&robot); + + // initialize aria + Aria::init(); + + // add the sonar object to the robot + robot.addRangeDevice(&sonar); + + // open the connection to the robot; if this fails exit + if(!con.connectRobot(&robot)) + { + printf("Could not connect to the robot.\n"); + return 2; + } + printf("Connected to the robot. (Press Ctrl-C to exit)\n"); + + + // Start the robot process cycle running. Each cycle, it calls the robot's + // tasks. When the PrintingTask was created above, it added a new + // task to the robot. 'true' means that if the robot connection + // is lost, then ArRobot's processing cycle ends and this call returns. + robot.run(true); + + printf("Disconnected. Goodbye.\n"); + + return 0; +} diff --git a/Legacy/Aria/examples/seekurPower.cpp b/Legacy/Aria/examples/seekurPower.cpp new file mode 100644 index 0000000..1e34ee0 --- /dev/null +++ b/Legacy/Aria/examples/seekurPower.cpp @@ -0,0 +1,189 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#include "Aria.h" + +/** @example seekurPower.cpp Control Seekur or Seekur Jr. accessory power + * switching from command line options. Run with -help for help on command + * line options. See robot manuals and notes on http://robots.mobilerobots.com + * for more information. + */ + +typedef struct { + const char *option; + int port; + const char *description; + int set; +} powerspec; + +powerspec PowerSpecs[] = { + {"pc2", 1, "Turn onboard computer #2 on or off.", 0}, + {"pc3", 13, "Turn onboard computer #3 on or off.", 0}, + {"pc4", 14, "Turn onboard computer #4 on or off", 0}, + {"pc5", 15, "Turn onboard computer #5 on or off.", 0}, + {"lrf1", 9, "Turn laser rangefinder #1 on or off.", 0}, + {"lrf2", 24, "Turn laser rangefinder #2 on or off.", 0}, + {"lrf1heat", 11, "Turn laser rangefinder #1's heater on or off.", 0}, + {"lrf2heat", 27, "Turn laser rangefinder #2's heater on or off.", 0}, + {"gps", 6, "Turn GPS receeiver on or off.", 0}, + {"poe", 4, "Turn 12V Power over Ethernet port on or off.", 0}, + {"lan", 5, "Turn internal LAN ethernet switch on or off.", 0}, + {"camera", 12, "Turn the 24V RVision camera on or off.", 0}, + {"rvision", 12, "Turn the 24V RVision camera on or off.", 0}, + {"ptu1", 9, "Turn pan/tilt unit #1 on or off.", 0}, + {"ptu2", 22, "Turn pan/tilt unit #2 on or off.", 0}, + {"ptu3", 23, "Turn pan/tilt unit #3 on or off.", 0}, + {"arm", 29, "Turn the 24V manipulator arm on or off.", 0}, + {"armcam", 7, "Turn the arm camera or other 12V arm accessories on or off.", 0} +}; + +int main(int argc, char **argv) +{ + int numPowerSpecs = sizeof(PowerSpecs)/sizeof(powerspec); + Aria::init(); + ArArgumentParser parser(&argc, argv); + parser.loadDefaultArguments(); + ArRobot robot; + ArRobotConnector robotConnector(&parser, &robot); + + if(!robotConnector.connectRobot()) + { + ArLog::log(ArLog::Terse, "seekurPower: Error: Could not connect to the robot."); + Aria::logOptions(); + Aria::exit(1); + } + + if (!Aria::parseArgs() || parser.checkArgument("help")) + { + Aria::logOptions(); + ArLog::log(ArLog::Terse, "Options for seekurPower command (your robot may not have some of these devices):"); + ArLog::log(ArLog::Terse, "- \t\tTurn port on or off, or reset by turning off then on again. Refer to robot documentation or http://robots.mobilerobots.com/wiki/Seekur_Switched_Power_Outputs for list and notes."); + for(int i = 0; i < numPowerSpecs; ++i) + ArLog::log(ArLog::Terse, "-%s \t\t%s (port %d)", PowerSpecs[i].option, PowerSpecs[i].description, PowerSpecs[i].port); + ArLog::log(ArLog::Terse, "-robotOff\t\tTurn whole robot off"); + Aria::exit(2); + } + + if(parser.checkArgument("-robotOff")) + { + ArLog::log(ArLog::Terse, "-robotOff given -- powering down entire robot with command #119 in 5 seconds..."); + for(int i = 5; i > 0; --i) + { + ArLog::log(ArLog::Terse, "Shutting down in %d seconds...", i); + ArUtil::sleep(1000); + } + robot.com(119); + Aria::exit(0); + } + + + std::list todo; + + int nargs = parser.getArgc(); + for(int argi = 1; argi < nargs; ++argi) + { + const char *opt = parser.getArg(argi); + if(opt[0] != '-') + { + ArLog::log(ArLog::Terse, "seekurPower: Error: invalid option %s. Use -help for list of options.", opt); + Aria::exit(4); + } + ++opt; + if(opt[0] == '-') + ++opt; + bool found = false; + if(argi == nargs-1) // option given as last argument, with no value + { + ArLog::log(ArLog::Terse, "seekurPower: Error: Missing argument to last option %s. Specify on, off or reset.", opt); + Aria::exit(7); + } + const char *val = parser.getArg(++argi); + for(int pi = 0; pi < numPowerSpecs; ++pi) + { + powerspec ps = PowerSpecs[pi]; + if(strcmp(opt, ps.option) == 0) + { + found = true; + if(strcmp(val, "on") == 0) + ps.set = 1; + else if(strcmp(val, "off") == 0) + ps.set = 0; + else if(strcmp(val, "reset") == 0) + ps.set = 2; + else + { + ArLog::log(ArLog::Terse, "seekurPower: Error: Invalid value '%s' for option %s. Use on, off or reset.", val, opt); + Aria::exit(6); + } + todo.push_back(ps); + break; + } + } + if(!found) + { + if(ArUtil::isOnlyNumeric(opt)) + { + found = true; + powerspec ps; + ps.option = opt; + ps.description = NULL; + ps.port = atoi(opt); + if(strcmp(val, "on") == 0) + ps.set = 1; + else if(strcmp(val, "off") == 0) + ps.set = 0; + else if(strcmp(val, "reset") == 0) + ps.set = 2; + todo.push_back(ps); + } + } + if(!found) + { + ArLog::log(ArLog::Terse, "seekurPower: Warning: unrecognized option %s. Use -help for list of options.", opt); + } + } + + + for(std::list::const_iterator i = todo.begin(); i != todo.end(); ++i) + { + powerspec ps = *i; + if(ps.set == 2) + { + ArLog::log(ArLog::Normal, "seekurPower: Switching %s (port %d) off, waiting 2 seconds., then switching it back on again...", ps.option, ps.port); + robot.com2Bytes(116, ps.port, 0); + ArUtil::sleep(2000); + robot.com2Bytes(116, ps.port, 1); + } + else + { + ArLog::log(ArLog::Normal, "seekurPower: Switching %s (port %d) %s...", ps.option, ps.port, ps.set?"on":"off"); + robot.com2Bytes(116, ps.port, ps.set); + } + } + + + Aria::exit(0); +} + diff --git a/Legacy/Aria/examples/sickLogger-vc2003.vcproj b/Legacy/Aria/examples/sickLogger-vc2003.vcproj new file mode 100644 index 0000000..38f878d --- /dev/null +++ b/Legacy/Aria/examples/sickLogger-vc2003.vcproj @@ -0,0 +1,187 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/examples/sickLogger-vc2008.vcproj b/Legacy/Aria/examples/sickLogger-vc2008.vcproj new file mode 100644 index 0000000..e902540 --- /dev/null +++ b/Legacy/Aria/examples/sickLogger-vc2008.vcproj @@ -0,0 +1,253 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/examples/sickLogger-vc2010.vcxproj b/Legacy/Aria/examples/sickLogger-vc2010.vcxproj new file mode 100644 index 0000000..90866a7 --- /dev/null +++ b/Legacy/Aria/examples/sickLogger-vc2010.vcxproj @@ -0,0 +1,286 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + sickLogger + {F2F3B4A0-9CDF-494F-B7B8-9442EBB6BA5F} + + + + Application + false + MultiByte + + + Application + false + MultiByte + + + Application + false + MultiByte + + + Application + false + MultiByte + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + .\../bin\ + .\../bin\ + ../obj/$(ProjectName)-$(Configuration)-VC10-$(PlatformShortName)/ + ../obj/$(ProjectName)-$(Configuration)-VC10-$(PlatformShortName)/ + false + false + .\../bin\ + .\../bin\ + ../obj/$(ProjectName)-$(Configuration)-VC10-$(PlatformShortName)/ + ../obj/$(ProjectName)-$(Configuration)-VC10-$(PlatformShortName)/ + false + false + $(ProjectName).DebugVC10 + $(ProjectName).DebugVC10 + + + + $(IntDir)$(ProjectName)-$(Configuration)-BuildLog.htm + + + .\../bin/sickLogger.tlb + + + + + Disabled + ..\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + true + true + + + true + Level3 + true + ProgramDatabase + Default + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + AriaDebugVC9.lib + $(OutDir)$(ProjectName)DebugVC10.exe + 1.0 + true + ..\lib;%(AdditionalLibraryDirectories) + false + Console + false + + + MachineX86 + + + + + $(IntDir)$(ProjectName)-$(Configuration)-BuildLog.htm + + + .\../bin/sickLogger.tlb + + + + + Disabled + ..\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + true + true + + + true + Level3 + true + ProgramDatabase + Default + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + AriaDebugVC9.lib + $(OutDir)$(ProjectName)DebugVC10.exe + 1.0 + true + ..\lib;%(AdditionalLibraryDirectories) + false + Console + false + + + + + + + $(IntDir)$(ProjectName)-$(Configuration)-BuildLog.htm + + + .\../bin/sickLogger.tlb + + + + + MaxSpeed + OnlyExplicitInline + ..\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;%(PreprocessorDefinitions) + false + Sync + Default + MultiThreadedDLL + false + false + true + + + Level3 + true + + + Default + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + AriaVC10.lib + $(OutDir)$(ProjectName)VC10.exe + 1.0 + true + ..\lib;%(AdditionalLibraryDirectories) + false + Console + false + + + MachineX86 + + + + + $(IntDir)$(ProjectName)-$(Configuration)-BuildLog.htm + + + .\../bin/sickLogger.tlb + + + + + MaxSpeed + OnlyExplicitInline + ..\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;%(PreprocessorDefinitions) + false + Sync + Default + MultiThreadedDLL + false + false + true + + + Level3 + true + + + Default + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + AriaVC10.lib + $(OutDir)$(ProjectName)VC10.exe + 1.0 + true + ..\lib;%(AdditionalLibraryDirectories) + false + Console + false + + + + + + + Disabled + Disabled + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + EnableFastChecks + EnableFastChecks + true + true + MaxSpeed + MaxSpeed + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + + + + \ No newline at end of file diff --git a/Legacy/Aria/examples/sickLogger.cpp b/Legacy/Aria/examples/sickLogger.cpp new file mode 100644 index 0000000..b419b7b --- /dev/null +++ b/Legacy/Aria/examples/sickLogger.cpp @@ -0,0 +1,151 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#include "Aria.h" + +/* +This program will let you joystick the robot around, and take logs for +the mapper while you drive, automatically... + +Control: + +Attach an analog joystick to the joyport on the robot, not on the +computer. Now calibrate the joystick: Leaving the stick centered, +press the trigger button for a second or so, then release it. Now +rotate the stick around its extremes two or three times, holding it in +each corner for a second or two. You are now ready to drive. You can +then drive the robot by holding the trigger and moving the joystick. +To make goals you can press the top button on the joystick (this +requires AROS1_5). + +You could also attach USB joystick attached to robot computer (this +depends on having a robot equiped with an accessible usb port): To +drive the robot just press the trigger button and then move the +joystick how you wish the robot to move. You can use the throttle on +the side of the joystick to control the maximum (and hence scaled) +speed at which the robot drives. To make a goal you can press any of +the other buttons on the joystick itself (button 2, 3, or 4). + +You could run this with the keyboard, but not very versatile. Use the +arrow keys to control the robot, and press g to make a goal. +*/ + + +int main(int argc, char **argv) +{ + Aria::init(); + ArArgumentParser parser(&argc, argv); + parser.loadDefaultArguments(); + + ArRobot robot; + ArRobotConnector robotConnector(&parser, &robot); + ArLaserConnector laserConnector(&parser, &robot, &robotConnector); + ArAnalogGyro analogGyro(&robot); + + // Always connect to the laser, and add half-degree increment and 180 degrees as default arguments for + // laser + parser.addDefaultArgument("-connectLaser -laserDegrees 180 -laserIncrement half"); + + if(!robotConnector.connectRobot()) + { + ArLog::log(ArLog::Terse, "sickLagger: Could not connect to the robot."); + if(parser.checkHelpAndWarnUnparsed()) + { + Aria::logOptions(); + Aria::exit(1); + } + } + + if(!Aria::parseArgs() || !parser.checkHelpAndWarnUnparsed()) + { + Aria::logOptions(); + Aria::exit(1); + } + + ArKeyHandler keyHandler; + Aria::setKeyHandler(&keyHandler); + robot.attachKeyHandler(&keyHandler); + +#ifdef WIN32 + printf("Pausing 5 seconds so you can disconnect VNC if you are using it.\n"); + ArUtil::sleep(5000); +#endif + + + std::string filename = "1scans.2d"; + if (argc > 1) + filename = argv[1]; + printf("Logging to file %s\n", filename.c_str()); + + + + + ArActionGroupRatioDriveUnsafe group(&robot); + group.activateExclusive(); + + robot.runAsync(true); + + if(!laserConnector.connectLasers(false, false, true)) + { + ArLog::log(ArLog::Terse, "sickLogger: Error: Could not connect to laser(s). Use -help to list options."); + Aria::exit(3); + } + + + // Allow some time for first set of laser reading to arrive + ArUtil::sleep(500); + + + // enable the motors, disable amigobot sounds + robot.comInt(ArCommands::SONAR, 0); + robot.comInt(ArCommands::ENABLE, 1); + robot.comInt(ArCommands::SOUND, 32); + robot.comInt(ArCommands::SOUNDTOG, 0); + // enable the joystick driving from the one connected to the microcontroller + robot.comInt(ArCommands::JOYDRIVE, 1); + + // Create the logging object + // This must be created after the robot and laser are connected so it can get + // correct parameters from them. + // The third argmument is how far the robot must travel before a new laser + // scan is logged. + // The fourth argument is how many degrees the robot must rotate before a new + // laser scan is logged. The sixth boolean argument is whether to place a goal + // when the g or G key is pressed (by adding a handler to the global + // ArKeyHandler) or when the robots joystick button is + // pressed. + ArLaser *laser = robot.findLaser(1); + if(!laser) + { + ArLog::log(ArLog::Terse, "sickLogger: Error, not connected to any lasers."); + Aria::exit(2); + } + ArLaserLogger logger(&robot, laser, 300, 25, filename.c_str(), true); + + // just hang out and wait for the end + robot.waitForRunExit(); + + Aria::exit(0); +} diff --git a/Legacy/Aria/examples/sickLoggerStatic-vc2003.vcproj b/Legacy/Aria/examples/sickLoggerStatic-vc2003.vcproj new file mode 100644 index 0000000..0d10061 --- /dev/null +++ b/Legacy/Aria/examples/sickLoggerStatic-vc2003.vcproj @@ -0,0 +1,182 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/examples/sickRobotExample.cpp b/Legacy/Aria/examples/sickRobotExample.cpp new file mode 100644 index 0000000..38a5da7 --- /dev/null +++ b/Legacy/Aria/examples/sickRobotExample.cpp @@ -0,0 +1,145 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#include "Aria.h" + +/* + This program connects to a robot, then to a laser, then prints out + some readings, and finally exits. +*/ + +int main(int argc, char **argv) +{ + // parse our args and make sure they were all accounted for + ArSimpleConnector connector(&argc, argv); + + // the robot + ArRobot robot; + // the laser + ArSick sick; + // all the information for our printing out + double dist, angle; + std::list *readings; + std::list::iterator it; + double farDist, farAngle; + bool found; + + if (!connector.parseArgs() || argc > 1) + { + connector.logOptions(); + Aria::exit(1); + return 1; + } + + // add the laser to the robot + robot.addRangeDevice(&sick); + + // try to connect, if we fail exit + if (!connector.connectRobot(&robot)) + { + printf("Could not connect to robot... exiting\n"); + Aria::exit(1); + return 1; + } + + // start the robot running, true so that if we lose connection the run stops + robot.runAsync(true); + + // now set up the laser + connector.setupLaser(&sick); + printf("filter threshold (distance to other readings) for current buffer is %0.2f mm\n", sick.getFilterNearDist()); + printf("timeout on current readings is %d sec. (0 means disabled).\n", sick.getMaxSecondsToKeepCurrent()); + + sick.runAsync(); + + if (!sick.blockingConnect()) + { + printf("Could not connect to SICK laser... exiting\n"); + Aria::shutdown(); + return 1; + } + + printf("Connected\n"); + ArUtil::sleep(500); + + int times = 0; + while (times++ < 3) + { + //dist = sick.getCurrentBuffer().getClosestPolar(-90, 90, ArPose(0, 0), 30000, &angle); + sick.lockDevice(); + + /* Current closest reading within a degree range */ + dist = sick.currentReadingPolar(-90, 90, &angle); + if (dist < sick.getMaxRange()) + printf("Closest reading %.2f mm away at %.2f degrees\n", dist, angle); + else + printf("No close reading.\n"); + + /* Print current buffer of reading positions (maybe filtered) */ + readings = sick.getCurrentBuffer(); + int i = 0; + for (it = readings->begin(), found = false; it != readings->end(); it++) + { + i++; + dist = (*it)->findDistanceTo(ArPose(0, 0)); + angle = (*it)->findAngleTo(ArPose(0, 0)); + if (!found || dist > farDist) + { + found = true; + farDist = dist; + farAngle = angle; + } + } + printf("%d readings in current buffer\n", i); + if (found) + printf("Furthest reading %.2f mm away at %.2f degrees\n", + farDist, farAngle); + else + printf("No far reading found.\n"); + + /* Print set of raw, unfiltered readings */ + int nign = 0; + printf("%lu raw readings.\n", sick.getRawReadings()->size()); + for(std::list::const_iterator ri = sick.getRawReadings()->begin(); ri != sick.getRawReadings()->end(); ++ri) + { + if((*ri)->getIgnoreThisReading()) { + ++nign; + } + } + printf("%d readings are being ignored (nothing detected at those angles)\n", nign); + + sick.unlockDevice(); + ArUtil::sleep(100); + + puts(""); + } + + Aria::exit(0); + return 0; +} + + + + diff --git a/Legacy/Aria/examples/sickTeleop-vc2003.vcproj b/Legacy/Aria/examples/sickTeleop-vc2003.vcproj new file mode 100644 index 0000000..47a0e80 --- /dev/null +++ b/Legacy/Aria/examples/sickTeleop-vc2003.vcproj @@ -0,0 +1,185 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/examples/sickTeleop-vc2008.vcproj b/Legacy/Aria/examples/sickTeleop-vc2008.vcproj new file mode 100644 index 0000000..abfc544 --- /dev/null +++ b/Legacy/Aria/examples/sickTeleop-vc2008.vcproj @@ -0,0 +1,249 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/examples/sickTeleop.cpp b/Legacy/Aria/examples/sickTeleop.cpp new file mode 100644 index 0000000..8a2b70b --- /dev/null +++ b/Legacy/Aria/examples/sickTeleop.cpp @@ -0,0 +1,124 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#include "Aria.h" + +/* + This is an example of how to use the limiting actions. + + It requires a SICK laser. Use either a joystick or keyboard + to drive the robot. If the SICK laser detects obstacles, actions + slow down the robot as it approaches. + + The way it works is that it has a limiting behavior higher priority + than the joydrive and keydrive actions. So if the limiting behaviors + detect obstacles that are too close, they set speed limits proportional + to the distance that slow down the robot and eventually prevent the + joydrive and keydrive actions from having any effect on the robot. +*/ + + +int main(int argc, char **argv) +{ + Aria::init(); + ArArgumentParser argParser(&argc, argv); + argParser.loadDefaultArguments(); + argParser.addDefaultArgument("-connectLaser"); // also by default always try to connect to the first laser. + + ArRobot robot; + ArRobotConnector robotConnector(&argParser, &robot); + ArLaserConnector laserConnector(&argParser, &robot, &robotConnector); + + ArActionJoydrive jdAct; + ArActionKeydrive keyAct; + + // limiter for close obstacles + ArActionLimiterForwards limiter("speed limiter near", 300, 600, 250); + + // limiter for far away obstacles + ArActionLimiterForwards limiterFar("speed limiter far", 300, 1100, 400); + + // limiter that uses the IR sensors on a Peoplebot, if equipped + ArActionLimiterTableSensor tableLimiter; + + // limiter so we don't bump things backwards + ArActionLimiterBackwards backwardsLimiter; + + + if(!robotConnector.connectRobot()) + { + printf("Could not connect to robot... exiting\n"); + Aria::logOptions(); + Aria::exit(1); + return 1; + } + + if(!Aria::parseArgs() || !argParser.checkHelpAndWarnUnparsed()) + { + printf("Could not connect to robot... exiting\n"); + Aria::logOptions(); + Aria::exit(2); + return 2; + } + + ArLog::log(ArLog::Normal, "Connected to robot."); + robot.runAsync(true); + + // laserConnector uses parameters from the robot parameter file(s) and from + // command line options to determine what kinds of lasers the robot has and + // how to connect to them. See the section on robot parameter files in the + // ARIA API Reference Manual, and the ArLaserConnector class documentation. + + if(!laserConnector.connectLasers()) + { + ArLog::log(ArLog::Terse, "Error connecting to configured lasers (see robot parameter file(s) and command line options)"); + Aria::exit(3); + return 3; + } + + // If laserConnector succeeded in connecting to lasers, ArLaser interface + // objects for them are stored in a + // list in the ArRobot object (robot). ArRobot can automatically use them in + // its utilities for checking range devices for obstacles, and you can query + // that list. (ArLaser is a subclass of ArRangeDevice.) + + // enable the motors, disable amigobot sounds + robot.comInt(ArCommands::ENABLE, 1); + robot.comInt(ArCommands::SOUNDTOG, 0); + + // add the actions, use high priority numbers for the limitier actions. + robot.addAction(&tableLimiter, 100); + robot.addAction(&limiter, 95); + robot.addAction(&limiterFar, 90); + robot.addAction(&backwardsLimiter, 85); + robot.addAction(&keyAct, 51); + robot.addAction(&jdAct, 50); + + // wait for end of robot connection + robot.waitForRunExit(); + + Aria::exit(0); + return 0; +} diff --git a/Legacy/Aria/examples/simpleConnect-vc2003.vcproj b/Legacy/Aria/examples/simpleConnect-vc2003.vcproj new file mode 100644 index 0000000..1388a84 --- /dev/null +++ b/Legacy/Aria/examples/simpleConnect-vc2003.vcproj @@ -0,0 +1,176 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/examples/simpleConnect-vc2008.vcproj b/Legacy/Aria/examples/simpleConnect-vc2008.vcproj new file mode 100644 index 0000000..58d53d8 --- /dev/null +++ b/Legacy/Aria/examples/simpleConnect-vc2008.vcproj @@ -0,0 +1,237 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/examples/simpleConnect-vc2010.vcxproj b/Legacy/Aria/examples/simpleConnect-vc2010.vcxproj new file mode 100644 index 0000000..baef08d --- /dev/null +++ b/Legacy/Aria/examples/simpleConnect-vc2010.vcxproj @@ -0,0 +1,156 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + simpleConnect + {D6C8A2A9-C3E1-4F70-924D-BDEA60B4C667} + + + + Application + false + MultiByte + false + + + Application + false + MultiByte + false + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + ../bin\ + ../obj/$(ProjectName)-$(Configuration)-VC10/ + false + ../bin\ + ../obj/$(ProjectName)-$(Configuration)-VC10/ + false + $(ProjectName).DebugVC10 + + + + $(IntDir)$(ProjectName)-$(Configuration)-BuildLog.htm + + + .\../bin/simpleConnect.tlb + + + + + MaxSpeed + OnlyExplicitInline + ..\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + false + Default + MultiThreadedDLL + true + true + + + Level3 + true + + + Default + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + AriaVC10.lib + 1.0 + true + ..\lib;%(AdditionalLibraryDirectories) + false + Console + false + + + MachineX86 + + + + + $(IntDir)$(ProjectName)-$(Configuration)-BuildLog.htm + + + .\../bin/simpleConnect.tlb + + + + + Disabled + ..\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + true + true + + + true + Level3 + true + + + Default + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + AriaDebugVC10.lib + 1.0 + true + ..\lib;%(AdditionalLibraryDirectories) + true + true + Console + false + + + MachineX86 + + + + + Disabled + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + EnableFastChecks + true + MaxSpeed + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + + + + \ No newline at end of file diff --git a/Legacy/Aria/examples/simpleConnect.cpp b/Legacy/Aria/examples/simpleConnect.cpp new file mode 100644 index 0000000..4249777 --- /dev/null +++ b/Legacy/Aria/examples/simpleConnect.cpp @@ -0,0 +1,99 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#include "Aria.h" + +/** @example simpleConnect.cpp example showing how to connect to the robot with ArRobotConnector + * + * One of the simplest ARIA programs possible: + * Connects with ArRobotConnector, waits 3 seconds doing + * nothing, then exits. + * + * This program will work either with the MobileSim simulator or on a real + * robot's onboard computer. (Or use -remoteHost to connect to a wireless + * ethernet-serial bridge.) + */ + +int main(int argc, char **argv) +{ + Aria::init(); + ArArgumentParser parser(&argc, argv); + parser.loadDefaultArguments(); + ArRobot robot; + + // Connect to the robot, get some initial data from it such as type and name, + // and then load parameter files for this robot. + ArRobotConnector robotConnector(&parser, &robot); + if(!robotConnector.connectRobot()) + { + ArLog::log(ArLog::Terse, "simpleConnect: Could not connect to the robot."); + if(parser.checkHelpAndWarnUnparsed()) + { + // -help not given + Aria::logOptions(); + Aria::exit(1); + } + } + + if (!Aria::parseArgs() || !parser.checkHelpAndWarnUnparsed()) + { + Aria::logOptions(); + Aria::exit(1); + } + + ArLog::log(ArLog::Normal, "simpleConnect: Connected."); + + robot.comInt(ArCommands::JOYINFO, 0); + + // Start the robot processing cycle running in the background. + // True parameter means that if the connection is lost, then the + // run loop ends. + robot.runAsync(true); + + // Print out some data from the SIP. We must "lock" the ArRobot object + // before calling its methods, and "unlock" when done, to prevent conflicts + // with the background thread started by the call to robot.runAsync() above. + // See the section on threading in the manual for more about this. + robot.lock(); + ArLog::log(ArLog::Normal, "simpleConnect: Pose=(%.2f,%.2f,%.2f), Trans. Vel=%.2f, Battery=%.2fV", + robot.getX(), robot.getY(), robot.getTh(), robot.getVel(), robot.getBatteryVoltage()); + robot.unlock(); + + // Sleep for 3 seconds. + ArLog::log(ArLog::Normal, "simpleConnect: Sleeping for 3 seconds..."); + ArUtil::sleep(3000); + + + ArLog::log(ArLog::Normal, "simpleConnect: Ending robot thread..."); + robot.stopRunning(); + + // wait for the thread to stop + robot.waitForRunExit(); + + // exit + ArLog::log(ArLog::Normal, "simpleConnect: Exiting."); + Aria::exit(0); + return 0; +} diff --git a/Legacy/Aria/examples/simpleMotionCommands.cpp b/Legacy/Aria/examples/simpleMotionCommands.cpp new file mode 100644 index 0000000..74db62e --- /dev/null +++ b/Legacy/Aria/examples/simpleMotionCommands.cpp @@ -0,0 +1,168 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#include "Aria.h" + +/** @example simpleMotionCommands.cpp example showing how to connect and send + * basic motion commands to the robot + * + * ARIA provides two levels of robot motion control, direct motion commands, and + * actions. This example shows direct motion commands. See actionExample.cpp, + * actionGroupExample.cpp, and others for examples on how to use actions. + * Actions provide a more modular way of performing more complex motion + * behaviors than the simple imperitive style used here. + * + * See the ArRobot class documentation, as well as the overview of robot motion, + * for more information. + * + * WARNING: this program does no sensing or avoiding of obstacles, the robot WILL + * collide with any objects in the way! Make sure the robot has about 2-3 + * meters of free space around it before starting the program. + * + * This program will work either with the MobileSim simulator or on a real + * robot's onboard computer. (Or use -remoteHost to connect to a wireless + * ethernet-serial bridge.) + */ + +int main(int argc, char **argv) +{ + + Aria::init(); + ArRobot robot; + ArArgumentParser parser(&argc, argv); + parser.loadDefaultArguments(); + + ArLog::log(ArLog::Terse, "WARNING: this program does no sensing or avoiding of obstacles, the robot WILL collide with any objects in the way! Make sure the robot has approximately 3 meters of free space on all sides."); + + // ArRobotConnector connects to the robot, get some initial data from it such as type and name, + // and then loads parameter files for this robot. + ArRobotConnector robotConnector(&parser, &robot); + if(!robotConnector.connectRobot()) + { + ArLog::log(ArLog::Terse, "simpleMotionCommands: Could not connect to the robot."); + if(parser.checkHelpAndWarnUnparsed()) + { + Aria::logOptions(); + Aria::exit(1); + return 1; + } + } + if (!Aria::parseArgs()) + { + Aria::logOptions(); + Aria::exit(1); + return 1; + } + + ArLog::log(ArLog::Normal, "simpleMotionCommands: Connected."); + + // Start the robot processing cycle running in the background. + // True parameter means that if the connection is lost, then the + // run loop ends. + robot.runAsync(true); + + // Print out some data from the SIP. + + // We must "lock" the ArRobot object + // before calling its methods, and "unlock" when done, to prevent conflicts + // with the background thread started by the call to robot.runAsync() above. + // See the section on threading in the manual for more about this. + // Make sure you unlock before any sleep() call or any other code that will + // take some time; if the robot remains locked during that time, then + // ArRobot's background thread will be blocked and unable to communicate with + // the robot, call tasks, etc. + + robot.lock(); + ArLog::log(ArLog::Normal, "simpleMotionCommands: Pose=(%.2f,%.2f,%.2f), Trans. Vel=%.2f, Rot. Vel=%.2f, Battery=%.2fV", + robot.getX(), robot.getY(), robot.getTh(), robot.getVel(), robot.getRotVel(), robot.getBatteryVoltage()); + robot.unlock(); + + // Sleep for 3 seconds. + ArLog::log(ArLog::Normal, "simpleMotionCommands: Will start driving in 3 seconds..."); + ArUtil::sleep(3000); + + // Set forward velocity to 50 mm/s + ArLog::log(ArLog::Normal, "simpleMotionCommands: Driving forward at 250 mm/s for 5 sec..."); + robot.lock(); + robot.enableMotors(); + robot.setVel(250); + robot.unlock(); + ArUtil::sleep(5000); + + ArLog::log(ArLog::Normal, "simpleMotionCommands: Stopping."); + robot.lock(); + robot.stop(); + robot.unlock(); + ArUtil::sleep(1000); + + ArLog::log(ArLog::Normal, "simpleMotionCommands: Rotating at 10 deg/s for 5 sec..."); + robot.lock(); + robot.setRotVel(10); + robot.unlock(); + ArUtil::sleep(5000); + + ArLog::log(ArLog::Normal, "simpleMotionCommands: Rotating at -10 deg/s for 10 sec..."); + robot.lock(); + robot.setRotVel(-10); + robot.unlock(); + ArUtil::sleep(10000); + + ArLog::log(ArLog::Normal, "simpleMotionCommands: Driving forward at 150 mm/s for 5 sec..."); + robot.lock(); + robot.setRotVel(0); + robot.setVel(150); + robot.unlock(); + ArUtil::sleep(5000); + + ArLog::log(ArLog::Normal, "simpleMotionCommands: Stopping."); + robot.lock(); + robot.stop(); + robot.unlock(); + ArUtil::sleep(1000); + + + // Other motion command functions include move(), setHeading(), + // setDeltaHeading(). You can also adjust acceleration and deceleration + // values used by the robot with setAccel(), setDecel(), setRotAccel(), + // setRotDecel(). See the ArRobot class documentation for more. + + + robot.lock(); + ArLog::log(ArLog::Normal, "simpleMotionCommands: Pose=(%.2f,%.2f,%.2f), Trans. Vel=%.2f, Rot. Vel=%.2f, Battery=%.2fV", + robot.getX(), robot.getY(), robot.getTh(), robot.getVel(), robot.getRotVel(), robot.getBatteryVoltage()); + robot.unlock(); + + + ArLog::log(ArLog::Normal, "simpleMotionCommands: Ending robot thread..."); + robot.stopRunning(); + + // wait for the thread to stop + robot.waitForRunExit(); + + // exit + ArLog::log(ArLog::Normal, "simpleMotionCommands: Exiting."); + Aria::exit(0); + return 0; +} diff --git a/Legacy/Aria/examples/socketClientExample-vc2003.vcproj b/Legacy/Aria/examples/socketClientExample-vc2003.vcproj new file mode 100644 index 0000000..bb0a9bb --- /dev/null +++ b/Legacy/Aria/examples/socketClientExample-vc2003.vcproj @@ -0,0 +1,156 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/examples/socketClientExample-vc2008.vcproj b/Legacy/Aria/examples/socketClientExample-vc2008.vcproj new file mode 100644 index 0000000..2618fce --- /dev/null +++ b/Legacy/Aria/examples/socketClientExample-vc2008.vcproj @@ -0,0 +1,212 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/examples/socketClientExample-vc2010.vcxproj b/Legacy/Aria/examples/socketClientExample-vc2010.vcxproj new file mode 100644 index 0000000..865719f --- /dev/null +++ b/Legacy/Aria/examples/socketClientExample-vc2010.vcxproj @@ -0,0 +1,144 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + socketClientExample + {5571A55D-018E-485E-802E-D3F200D587DC} + + + + Application + false + MultiByte + + + Application + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + .\../bin\ + ../obj/$(ProjectName)-$(Configuration)-VC10/ + false + .\../bin\ + ../obj/$(ProjectName)-$(Configuration)-VC10/ + false + $(ProjectName).DebugVC10 + + + + $(IntDir)$(ProjectName)-$(Configuration)-BuildLog.htm + + + .\../bin/clientHelloWorld.tlb + + + + + MaxSpeed + OnlyExplicitInline + ..\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + true + true + + + Level3 + true + + + Default + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + AriaVC10.lib + 0.7 + true + ..\lib;%(AdditionalLibraryDirectories) + false + Console + false + + + MachineX86 + + + + + $(IntDir)$(ProjectName)-$(Configuration)-BuildLog.htm + + + .\../bin/clientHelloWorld.tlb + + + + + Disabled + ..\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + true + true + + + true + Level3 + true + + + Default + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + AriaDebugVC10.lib + 1.0 + true + ..\lib;%(AdditionalLibraryDirectories) + false + Console + false + + + MachineX86 + + + + + + + + + \ No newline at end of file diff --git a/Legacy/Aria/examples/socketClientExample.cpp b/Legacy/Aria/examples/socketClientExample.cpp new file mode 100644 index 0000000..f0cc157 --- /dev/null +++ b/Legacy/Aria/examples/socketClientExample.cpp @@ -0,0 +1,117 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#include "Aria.h" + + +/** @example socketClientExample.cpp ArSocket example client program + * + * + This is an example to show how to use ArSocket to create a client and + a server. This is the client program. The server is + socketServerExample.cpp. + + This connects to a server on the host 'localhost' on port 7777. It waits for the server + to say hello, then it says hello in reponse. It then closes the socket and + exits. + + First run the server program socketServerExample. Then run + this client program on the same computer, perhaps in a different + terminal window. You should see the server accept the connection, + send its greeting to this client program, and see this client + respond with its greeting text to the server. + + @see ArSocket + @see socketServerExample.cpp + + Also see the ArNetworking library for a more complete + networking framework. +*/ + + +int main() +{ + // The string to send to the server. + const char *strToSend="Hello Server"; + // The buffer in which to recieve the hello from the server + char buff[100]; + // The size of the string the server sent + size_t strSize; + + // The socket object + ArSocket sock; + + // Initialize Aria. It is especially important to do + // this on Windows, because it will initialize Window's + // sockets system. + Aria::init(); + + // Connect to the server + ArLog::log(ArLog::Normal, "socketClientExample: Connecting to localhost TCP port 7777..."); + if (sock.connect("localhost", 7777, ArSocket::TCP)) + ArLog::log(ArLog::Normal, "socketClientExample: Connected to server at localhost TCP port 7777."); + else + { + ArLog::log(ArLog::Terse, "socketClientExample: Error connecting to server at localhost TCP port 7777: %s", sock.getErrorStr().c_str()); + return(-1); + } + + // Read data from the socket. read() will block until + // data is received. + strSize=sock.read(buff, sizeof(buff)); + + // If the amount read is 0 or less, its an error condition. + if (strSize > 0) + { + buff[strSize]='\0'; // Terminate the string with a NULL character: + ArLog::log(ArLog::Normal, "socketClientExample: Server said: \"%s\"", buff); + } + else + { + ArLog::log(ArLog::Terse, "socketClientExample: Error in waiting/reading from the server."); + Aria::exit(-1); + return(-1); + } + + // Send the string 'Hello Server' to the server. write() should + // return the same number of bytes that we told it to write. Otherwise, + // its an error condition. + if (sock.write(strToSend, strlen(strToSend)) == strlen(strToSend)) + ArLog::log(ArLog::Normal, "socketClientExample: Said hello to the server."); + else + { + ArLog::log(ArLog::Terse, "socketClientExample: Error sending hello string to the server."); + Aria::exit(-1); + return(-1); + } + + // Now close the connection to the server + sock.close(); + ArLog::log(ArLog::Normal, "socketClientExample: Socket to server closed."); + + // Uninitialize Aria and exit + Aria::exit(0); + return(0); +} diff --git a/Legacy/Aria/examples/socketServerExample-vc2003.vcproj b/Legacy/Aria/examples/socketServerExample-vc2003.vcproj new file mode 100644 index 0000000..a5d0168 --- /dev/null +++ b/Legacy/Aria/examples/socketServerExample-vc2003.vcproj @@ -0,0 +1,156 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/examples/socketServerExample-vc2008.vcproj b/Legacy/Aria/examples/socketServerExample-vc2008.vcproj new file mode 100644 index 0000000..0b0d75c --- /dev/null +++ b/Legacy/Aria/examples/socketServerExample-vc2008.vcproj @@ -0,0 +1,210 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/examples/socketServerExample-vc2010.vcxproj b/Legacy/Aria/examples/socketServerExample-vc2010.vcxproj new file mode 100644 index 0000000..4c88480 --- /dev/null +++ b/Legacy/Aria/examples/socketServerExample-vc2010.vcxproj @@ -0,0 +1,143 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + socketServerExample + {CD42EA8C-AEEC-4B0A-AAE5-C8096EB9ACDF} + + + + Application + false + MultiByte + + + Application + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + .\../bin\ + ../obj/$(Configuration)-VC9\ + false + .\../bin\ + ../obj/$(Configuration)-VC9\ + false + + + + $(IntDir)$(ProjectName)BuildLog.htm + + + .\../bin/serverHelloWorld.tlb + + + + + MaxSpeed + OnlyExplicitInline + ..\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + true + true + + + Level3 + true + + + Default + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;winmm.lib;AriaVC9.lib;%(AdditionalDependencies) + 0.7 + true + ..\lib;%(AdditionalLibraryDirectories) + false + Console + false + + + MachineX86 + + + + + $(IntDir)$(ProjectName)BuildLog.htm + + + .\../bin/serverHelloWorld.tlb + + + + + Disabled + ..\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + true + true + + + true + Level3 + true + + + Default + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;winmm.lib;AriaDebugVC9.lib;%(AdditionalDependencies) + 1.0 + true + ..\lib;%(AdditionalLibraryDirectories) + false + Console + false + + + MachineX86 + + + + + + + + + \ No newline at end of file diff --git a/Legacy/Aria/examples/socketServerExample.cpp b/Legacy/Aria/examples/socketServerExample.cpp new file mode 100644 index 0000000..0f85400 --- /dev/null +++ b/Legacy/Aria/examples/socketServerExample.cpp @@ -0,0 +1,146 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#include "Aria.h" + + +/** @example socketServerExample.cpp ArSocket example server program + * + This is an example to show how to use ArSocket. + a server. This is the server program. The client is socketClientExample.cpp + + This program opens a server on port 7777. It waits for the + client to connect and says hello to the client. It then waits for the + client to say hello and then exits. + + First run this server program. Then run the client program, + socketClientExample, perhaps in a different terminal window. + You should see the server accept the connection, send its + greeting to the client, recieve a response from the client, + and then the connection closes. + + This server only accepts one client connection, and then + it exits. In practice, most servers would loop, accepting + many clients, and simultaneously handling curently open + client connections. You can use threads to do that (see + ArASyncTask), but ArSocket is not inherently thread-safe, + you would also need to use an ArMutex object to protect + ArSocket calls. + + @see ArSocket + @see socketClientExample.cpp + + Also see the ArNetServer to help manage a server, or the + ArNetworking library for a more complete networking framework. +*/ + + +int main() +{ + // The string to send to the client. + char *strToSend="Hello Client"; + // The buffer in which to recieve the hello from the client + char buff[100]; + // The size of the string the client sent + size_t strSize; + + // Initialize Aria. This is especially essential on Windows, + // because it will initialize Windows's sockets sytem. + Aria::init(); + + // The socket objects: one for accepting new client connections, + // and another for communicating with a client after it connects. + ArSocket serverSock, clientSock; + + + // Open the server socket + if (serverSock.open(7777, ArSocket::TCP)) + ArLog::log(ArLog::Normal, "socketServerExample: Opened the server port."); + else + { + ArLog::log(ArLog::Normal, "socketServerExample: Failed to open the server port: %s.", + serverSock.getErrorStr().c_str()); + Aria::exit(-1); + return(-1); + } + + for(int clientNo = 0; Aria::getRunning(); ++clientNo) + { + + // Wait for a client to connect to us. + ArLog::log(ArLog::Normal, "socketServerExample: Waiting for a client to connect. Press CTRL-C to exit."); + + if (serverSock.accept(&clientSock)) + ArLog::log(ArLog::Normal, "socketServerExample: Client %d has connected.", clientNo); + else + ArLog::log(ArLog::Terse, "socketServerExample: Error in accepting a connection from the client: %s.", + serverSock.getErrorStr().c_str()); + + // Send the string 'Hello Client' to the client. write() should + // return the same number of bytes that we told it to write. Otherwise, + // its an error condition. + if (clientSock.write(strToSend, strlen(strToSend)) == strlen(strToSend)) + ArLog::log(ArLog::Normal, "socketServerExample: Said hello to the client."); + else + { + ArLog::log(ArLog::Normal, "socketServerExample: Error in sending hello string to the client."); + Aria::exit(-1); + return(-1); + } + + // Read data from the client. read() will block until data is + // received. + strSize=clientSock.read(buff, sizeof(buff)); + + // If the amount read is 0 or less, its an error condition. + if (strSize > 0) + { + // Terminate the string with a NULL character. + buff[strSize]='\0'; + ArLog::log(ArLog::Normal, "socketServerExample: Client said: %s.", buff); + } + else + { + ArLog::log(ArLog::Normal, "socketServerExample: Error in waiting/reading the hello from the client."); + Aria::exit(-1); + return(-1); + } + + // Now lets close the connection to the client + clientSock.close(); + ArLog::log(ArLog::Normal, "socketServerExample: Socket to client closed."); + + } + + // And lets close the server port + serverSock.close(); + ArLog::log(ArLog::Normal, "socketServerExample: Server socket closed."); + + + // Uninitialize Aria and exit the program + Aria::exit(0); + + return(0); +} diff --git a/Legacy/Aria/examples/sound-computers.wav b/Legacy/Aria/examples/sound-computers.wav new file mode 100644 index 0000000000000000000000000000000000000000..f4cc6d59888b0a9ef163f0b572b1a2118f73bb26 GIT binary patch literal 48494 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�A78N4PuyFed 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 UIWp$<$`3Zzco`9!bHl>_2jF-8UH||9 literal 0 HcmV?d00001 diff --git a/Legacy/Aria/examples/sound-impressed.wav b/Legacy/Aria/examples/sound-impressed.wav new file mode 100644 index 0000000000000000000000000000000000000000..b24630b69d15d69a662991eeccd2b46bccabe0ee GIT binary patch literal 13728 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 literal 0 HcmV?d00001 diff --git a/Legacy/Aria/examples/sound-r2a.wav b/Legacy/Aria/examples/sound-r2a.wav new file mode 100644 index 0000000000000000000000000000000000000000..80e9c39e4e29dcc033a6586d143edd0c03729cc2 GIT binary patch literal 31810 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 literal 0 HcmV?d00001 diff --git a/Legacy/Aria/examples/sound-r2b.wav b/Legacy/Aria/examples/sound-r2b.wav new file mode 100644 index 0000000000000000000000000000000000000000..02467dcded303212e3be70a855b2db7aa50b5e84 GIT binary patch literal 178806 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

8i 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

-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 literal 0 HcmV?d00001 diff --git a/Legacy/Aria/examples/soundsQueueExample-vc2003.vcproj b/Legacy/Aria/examples/soundsQueueExample-vc2003.vcproj new file mode 100644 index 0000000..5b68a40 --- /dev/null +++ b/Legacy/Aria/examples/soundsQueueExample-vc2003.vcproj @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/examples/soundsQueueExample-vc2008.vcproj b/Legacy/Aria/examples/soundsQueueExample-vc2008.vcproj new file mode 100644 index 0000000..6184d58 --- /dev/null +++ b/Legacy/Aria/examples/soundsQueueExample-vc2008.vcproj @@ -0,0 +1,194 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/examples/soundsQueueExample-vc2010.vcxproj b/Legacy/Aria/examples/soundsQueueExample-vc2010.vcxproj new file mode 100644 index 0000000..a04ad83 --- /dev/null +++ b/Legacy/Aria/examples/soundsQueueExample-vc2010.vcxproj @@ -0,0 +1,116 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + soundsQueueExample + {2F512A11-402E-496D-B20C-806414BDFE9F} + soundqueueexample + ManagedCProj + + + + Application + MultiByte + false + + + Application + MultiByte + false + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + ..\bin\ + ../obj/$(ProjectName)-$(Configuration)-VC10/ + false + false + ..\bin\ + ../obj/$(ProjectName)-$(Configuration)-VC10/ + false + $(ProjectName).DebugVC10 + + + + $(IntDir)$(ProjectName)-$(Configuration)-BuildLog.htm + + + /I "C:\reed\Aria\include" %(AdditionalOptions) + Disabled + ..\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + false + Default + MultiThreadedDebugDLL + true + true + true + Level3 + + + Default + + + AriaDebugVC10.lib + $(OutDir)$(ProjectName).exe + true + ..\lib;%(AdditionalLibraryDirectories) + true + true + Console + false + + + MachineX86 + + + + + $(IntDir)$(ProjectName)-$(Configuration)-BuildLog.htm + + + ..\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;%(PreprocessorDefinitions) + false + MultiThreaded + Level3 + ProgramDatabase + + + $(OutDir)$(ProjectName).exe + true + false + + + AriaVC10.lib + ..\lib;%(AdditionalLibraryDirectories) + + + + + + + + + \ No newline at end of file diff --git a/Legacy/Aria/examples/soundsQueueExample.cpp b/Legacy/Aria/examples/soundsQueueExample.cpp new file mode 100644 index 0000000..59b1056 --- /dev/null +++ b/Legacy/Aria/examples/soundsQueueExample.cpp @@ -0,0 +1,165 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ + +/** @example soundsQueueExample.cpp This program demonstrates the sound output queue ArSoundsQueue + * + * Shows how to operate the sounds queue and add WAV files to play. + * + * You may specify up to 10 file names on the command line. + * This example only demonstrates using the sounds queue for + * WAV file playback. For demonstration of using the sounds + * queue for speech synthesis, see the examples provided with + * either the ArSpeechSynth_Cepstral or ArSpeechSynth_Festival + * libraries. + * + * Usage: + * soundQueue <wav file names> + */ + +#include "Aria.h" +#include "ariaTypedefs.h" +#include "ariaUtil.h" +#include "ArSoundsQueue.h" +#include "ArSoundPlayer.h" +#include +#include + +using namespace std; + +void queueNowEmpty() { + printf("The sound queue is now empty.\n"); +} + +void queueNowNonempty() { + printf("The sound queue is now non-empty.\n"); +} + +bool no() { + // just a false tautology + return false; +} + +int main(int argc, char** argv) { + Aria::init(); + //ArLog::init(ArLog::StdErr, ArLog::Verbose); + + // Create the sound queue. + ArSoundsQueue soundQueue; + + // Set WAV file callbacks + soundQueue.setPlayWavFileCallback(ArSoundPlayer::getPlayWavFileCallback()); + soundQueue.setInterruptWavFileCallback(ArSoundPlayer::getStopPlayingCallback()); + + // Notifications when the queue goes empty or non-empty. + soundQueue.addQueueEmptyCallback(new ArGlobalFunctor(&queueNowEmpty)); + soundQueue.addQueueNonemptyCallback(new ArGlobalFunctor(&queueNowNonempty)); + + // Run the sound queue in a new thread + soundQueue.runAsync(); + + // Get WAV file names from command line + if(argc < 2) + { + cerr << "Usage: " << argv[0] << " \n"; + Aria::exit(-1); + } + std::vector filenames; + for(int i = 1; i < min(argc, 11); i++) + { + filenames.push_back(argv[i]); + } + + // This functor can be used to cancel all sound playback until removed + ArGlobalRetFunctor dontPlayItem(&no); + + while(Aria::getRunning()) + { + cout << "Queue is " << + string(soundQueue.isPaused()?"paused":(soundQueue.isPlaying()?"playing":"ready")) + << ", with " << soundQueue.getCurrentQueueSize() << " pending sounds." << endl + << "Enter a command followed by the enter key:\n" + << "\tp\trequest pause state (cumulative)\n" + << "\tr\trequest resume state (cumulative)\n" + << "\ti\tinterrupt current sound\n" + << "\tc\tclear the queue\n" + << "\tC\tclear priority < 4 from the queue.\n" + << "\tn\tAdd " << filenames[0] << " to the queue, but with a condition callback to prevent it playing.\n" + << "\tv\tAdjust volume -50%\n" + << "\tV\tAdjust volume +50%\n" + << "\to\tAdjust volume -100%\n" + << "\tO\tAdjust volume +100%\n" + << "\tl\tAdjust volume -200%\n" + << "\tL\tAdjust volume +200%\n" + << "\t-\tSet volume adjustment to normal level\n" + ; + for(size_t i = 0; i < filenames.size(); i++) + cout << "\t" << i << "\tadd " << filenames[i] << " to the queue\n"; + cout << "\tq\tquit\n\n"; + + int c = getchar(); + if(c == '\n') + continue; + switch(c) + { + case 'p': soundQueue.pause(); break; + case 'r': soundQueue.resume(); break; + case 'i': soundQueue.interrupt(); break; + case 'q': soundQueue.stop(); ArUtil::sleep(100); Aria::exit(0); + case 'c': soundQueue.clearQueue(); break; + case 'C': soundQueue.removePendingItems(4); break; + case 'n': + { + cout << "Adding \"" << filenames[0] << "\" but with a condition callback that will prevent it from playing...\n"; + ArSoundsQueue::Item item = soundQueue.createDefaultFileItem(filenames[0]); + item.playbackConditionCallbacks.push_back(&dontPlayItem); + soundQueue.addItem(item); + break; + } + case 'v': ArSoundPlayer::setVolumePercent(-50.0); break; + case 'V': ArSoundPlayer::setVolumePercent(50.0); break; + case 'o': ArSoundPlayer::setVolumePercent(-100.0); break; + case 'O': ArSoundPlayer::setVolumePercent(100.0); break; + case 'l': ArSoundPlayer::setVolumePercent(-200.0); break; + case 'L': ArSoundPlayer::setVolumePercent(200.0); break; + case '-': ArSoundPlayer::setVolumePercent(0.0); break; + default: + if(filenames.size() > 0 && c >= '0' && c <= '9') + { + size_t i = c - '0'; + if(i < filenames.size()) + { + cout << "Adding \"" << filenames[i] << "\" to the queue...\n"; + soundQueue.play(filenames[i]); + } + } + } + } + cout << "ended.\n"; + Aria::exit(0); + return 0; +} + + diff --git a/Legacy/Aria/examples/teleopActionsExample-vc2003.vcproj b/Legacy/Aria/examples/teleopActionsExample-vc2003.vcproj new file mode 100644 index 0000000..97a139f --- /dev/null +++ b/Legacy/Aria/examples/teleopActionsExample-vc2003.vcproj @@ -0,0 +1,156 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/examples/teleopActionsExample-vc2008.vcproj b/Legacy/Aria/examples/teleopActionsExample-vc2008.vcproj new file mode 100644 index 0000000..0d1bfee --- /dev/null +++ b/Legacy/Aria/examples/teleopActionsExample-vc2008.vcproj @@ -0,0 +1,212 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/examples/teleopActionsExample-vc2010.vcxproj b/Legacy/Aria/examples/teleopActionsExample-vc2010.vcxproj new file mode 100644 index 0000000..ae6bc4a --- /dev/null +++ b/Legacy/Aria/examples/teleopActionsExample-vc2010.vcxproj @@ -0,0 +1,144 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + teleopActionsExample + {9E2494B2-5359-47C8-9122-549EDD467615} + + + + Application + false + MultiByte + + + Application + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + .\../bin\ + ../obj/$(ProjectName)-$(Configuration)-VC10/ + false + .\../bin\ + ../obj/$(ProjectName)-$(Configuration)-VC10/ + false + $(ProjectName).DebugVC10 + + + + $(IntDir)$(ProjectName)-$(Configuration)-BuildLog.htm + + + .\../bin/teleop.tlb + + + + + Disabled + ..\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + true + true + + + true + Level3 + true + + + Default + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + AriaDebugVC10.lib + 1.0 + true + ..\lib;%(AdditionalLibraryDirectories) + false + Console + false + + + MachineX86 + + + + + $(IntDir)$(ProjectName)-$(Configuration)-BuildLog.htm + + + .\../bin/teleop.tlb + + + + + MaxSpeed + OnlyExplicitInline + ..\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + true + true + + + Level3 + true + + + Default + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + AriaVC10.lib + 1.0 + true + ..\lib;%(AdditionalLibraryDirectories) + false + Console + false + + + MachineX86 + + + + + + + + + \ No newline at end of file diff --git a/Legacy/Aria/examples/teleopActionsExample.cpp b/Legacy/Aria/examples/teleopActionsExample.cpp new file mode 100644 index 0000000..8eab7e5 --- /dev/null +++ b/Legacy/Aria/examples/teleopActionsExample.cpp @@ -0,0 +1,119 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#include "Aria.h" + +/** @example teleopActionsExample.cpp Example using actions for safe + * teleoperation with keyboard or joystick. + + This example program creates several "limiting" actions (stop the robot + from hitting detected obstacles), as well as Joydrive and Keydrive + actions which request movement based on keys pressed or a joystick + attached to the computer. The limiting actions are added at a higher + priority than the teleoperation actions, so they prevent those actions + from driving the robot if nearby obstacles are detected; otherwise, + you can drive the robot using they joystick or keyboard. +*/ + +int main(int argc, char **argv) +{ + Aria::init(); + ArArgumentParser parser(&argc, argv); + parser.loadDefaultArguments(); + ArRobot robot; + ArRobotConnector robotConnector(&parser, &robot); + if(!robotConnector.connectRobot()) + { + ArLog::log(ArLog::Terse, "teleopActionsExample: Could not connect to the robot."); + if(parser.checkHelpAndWarnUnparsed()) + { + Aria::logOptions(); + Aria::exit(1); + } + } + if (!Aria::parseArgs() || !parser.checkHelpAndWarnUnparsed()) + { + Aria::logOptions(); + Aria::exit(1); + } + ArLog::log(ArLog::Normal, "teleopActionsExample: Connected."); + + + // limiter for close obstacles + ArActionLimiterForwards limiter("speed limiter near", 300, 600, 250); + // limiter for far away obstacles + ArActionLimiterForwards limiterFar("speed limiter far", 300, 1100, 400); + // limiter that checks IR sensors (like Peoplebot has) + ArActionLimiterTableSensor tableLimiter; + // limiter so we don't bump things backwards + ArActionLimiterBackwards backwardsLimiter; + // the joydrive action + ArActionJoydrive joydriveAct; + // the keydrive action + ArActionKeydrive keydriveAct; + + // sonar device, used by the limiter actions. + ArSonarDevice sonar; + + + + printf("This program will allow you to use a joystick or keyboard to control the robot.\nYou can use the arrow keys to drive, and the spacebar to stop.\nFor joystick control press the trigger button and then drive.\nPress escape to exit.\n"); + + // if we don't have a joystick, let 'em know + if (!joydriveAct.joystickInited()) + printf("Do not have a joystick, only the arrow keys on the keyboard will work.\n"); + + // add the sonar to the robot + robot.addRangeDevice(&sonar); + + + // set the robots maximum velocity (sonar don't work at all well if you're + // going faster) + robot.setAbsoluteMaxTransVel(400); + + // enable the motor + robot.enableMotors(); + + // Add the actions, with the limiters as highest priority, then the teleop. + // actions. This will keep the teleop. actions from being able to drive too + // fast and hit something + robot.addAction(&tableLimiter, 100); + robot.addAction(&limiter, 95); + robot.addAction(&limiterFar, 90); + robot.addAction(&backwardsLimiter, 85); + robot.addAction(&joydriveAct, 50); + robot.addAction(&keydriveAct, 45); + + // Configure the joydrive action so it will let the lower priority actions + // (i.e. keydriveAct) request motion if the joystick button is + // not pressed. + joydriveAct.setStopIfNoButtonPressed(false); + + + // run the robot, true means that the run will exit if connection lost + robot.run(true); + + Aria::exit(0); +} diff --git a/Legacy/Aria/examples/threadExample-vc2003.vcproj b/Legacy/Aria/examples/threadExample-vc2003.vcproj new file mode 100644 index 0000000..d82dd3c --- /dev/null +++ b/Legacy/Aria/examples/threadExample-vc2003.vcproj @@ -0,0 +1,256 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/examples/threadExample-vc2008.vcproj b/Legacy/Aria/examples/threadExample-vc2008.vcproj new file mode 100644 index 0000000..bcb4577 --- /dev/null +++ b/Legacy/Aria/examples/threadExample-vc2008.vcproj @@ -0,0 +1,237 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/examples/threadExample-vc2010.vcxproj b/Legacy/Aria/examples/threadExample-vc2010.vcxproj new file mode 100644 index 0000000..c51f8e8 --- /dev/null +++ b/Legacy/Aria/examples/threadExample-vc2010.vcxproj @@ -0,0 +1,157 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + threadExample + {4BB4D8FF-F83B-406A-85AF-C7DF75ABCF59} + + + + Application + false + MultiByte + false + + + Application + false + MultiByte + false + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + ../bin\ + ../obj/$(ProjectName)-$(Configuration)-VC10/ + false + ../bin\ + ../obj/$(ProjectName)-$(Configuration)-VC10/ + false + $(ProjectName).DebugVC10 + + + + .\../bin/threadExample.tlb + + + + + MaxSpeed + OnlyExplicitInline + ..\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + false + Default + MultiThreadedDLL + false + false + true + + + Level3 + true + + + Default + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + AriaVC10.lib + 1.0 + true + ..\lib;%(AdditionalLibraryDirectories) + false + Console + false + + + MachineX86 + + + $(IntDir)$(ProjectName)-$(Configuration)-BuildLog.htm + + + + + .\../bin/threadExample.tlb + + + + + Disabled + ..\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + false + false + true + + + true + Level3 + true + ProgramDatabase + Default + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + AriaDebugVC10.lib + 1.0 + true + ..\lib;%(AdditionalLibraryDirectories) + true + true + Console + false + + + MachineX86 + + + $(IntDir)$(ProjectName)-$(Configuration)-BuildLog.htm + + + + + Disabled + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + EnableFastChecks + true + MaxSpeed + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + + + + \ No newline at end of file diff --git a/Legacy/Aria/examples/threadExample.cpp b/Legacy/Aria/examples/threadExample.cpp new file mode 100644 index 0000000..efe3bed --- /dev/null +++ b/Legacy/Aria/examples/threadExample.cpp @@ -0,0 +1,184 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ + +/** @example threadExample.cpp Example showing ARIA's cross-platform threading tools. + * + * ARIA provides some tools for writing multithreaded programs. These are + * abstractions of the threading library provided by the native operating + * system. + * + * The three main tools are: + *
    + *
  • ArASyncTask a class which can run a method in a new thread
  • + *
  • ArMutex, an object that can be shared by multiple threads to provide + * mutual exclusion from other shared data.
  • + *
  • ArCondition, an object that can cause a thread to block + * execution until signaled by another thread to continue.
  • + *
+ * + * This example program shows the use of all three, with two threads + * interacting: the program's main thread of execution, and a new thread + * created using ArASyncTask. An ArMutex object is used to keep use of + * some shared data safe, and then the use of ArCondition is shown. + * + * Threading can be error-prone, since any (perhaps subconcious) assumptions + * you have about the linear execution of code may not apply to simultaneous threads. + * Furthermore, different computers will execute multithreaded code in + * different ways (especially if they have different numbers of CPUs). + * ARIA's threading tools can help make multiple threads work, and help make + * multithreaded code portable, but you must always think carefully about + * how code might execute (including error conditions!) to avoid deadlocks and + * race conditions. + */ + +#include "Aria.h" + + +/* A subclass of ArASyncTask, to contain a method that runs in a new thread */ +class ExampleThread : public ArASyncTask +{ + ArCondition myCondition; + ArMutex myMutex; + int myCounter; +public: + + /* Construtor. Initialize counter. */ + ExampleThread() : myCounter(0) + { + myCondition.setLogName("ExampleThreadCondition"); + } + + + /* This method is called in the new thread when launched. The void* parameter + * and return value are platform implementation-specific and can be ignored. + * This method will run in a loop, incrementing the counter each second, but + * locking the mutex to prevent conflicting access by other threads. + * If it reaches a value divisible by ten, signal our condition variable. + */ + void* runThread(void*) + { + // Run until the thread is requested to end by another thread. + while(this->getRunningWithLock()) + { + myMutex.lock(); + + // Increment the counter. + myCounter++; + ArLog::log(ArLog::Normal, "Example thread: incremented counter to %d.", myCounter); + + // If it's now divisible by 10, signal the condition variable. + if(myCounter % 10 == 0) + { + ArLog::log(ArLog::Normal, "Example thread: Signalling condition."); + myCondition.signal(); + } + + // Unlock, then sleep. We unlock before the sleep, so that while + // we are sleeping, other threads that try to lock the mutex won't + // be blocked until this thread is done sleeping. + myMutex.unlock(); + ArUtil::sleep(1000); + } + + ArLog::log(ArLog::Normal, "Example thread: requested stop running, ending thread."); + return NULL; + } + + /* Other threads can call this to wait for a condition eventually + * signalled by this thread. (So note that in this example program, this + * function is not executed within "Example thread", but is executed in the main thread.) + */ + void waitOnCondition() + { + myCondition.wait(); + ArLog::log(ArLog::Normal, " %s ArCondition object was signalled, done waiting for it.", myCondition.getLogName()); + } + + /* Get the counter. Not threadsafe, you must lock the mutex during access. */ + int getCounter() { return myCounter; } + + /* Set the countner. Not threadsafe, you must lock the mutex during access. */ + void setCounter(int ctr) { myCounter = ctr; } + + /* Lock the mutex object. */ + void lockMutex() { myMutex.lock(); } + + /* Unlock the mutex object. */ + void unlockMutex() { myMutex.unlock(); } + +}; + +int main() +{ + Aria::init(); + + ExampleThread exampleThread; + + /* Launch the new thread in the background. This thread (i.e. the main program thread, + * executing main()) continues immediately after the new thread is created. */ + ArLog::log(ArLog::Normal, "Main thread: Running new example thread ..."); + exampleThread.runAsync(); + + /* Loop, reading the value contained in the ExampleThread object. + * We will also use ArUtil::sleep() to make this thread sleep each iteration, + * instead of running as fast as possible and potentially preventing other + * threads from access to the mutex and the shared counter. + * When the counter reaches 10, break out of the loop and then wait on the + * condition variable. + */ + while(true) + { + exampleThread.lockMutex(); + int c = exampleThread.getCounter(); + exampleThread.unlockMutex(); // we can unlock the mutex now, since we made a copy of the counter. + + printf("Main thread: Counter=%d.\n", c); + + if(c >= 10) + break; + + ArUtil::sleep(600); + } + + + /* This shows how to block on an ArCondition object. + * wait() will *only* return when the condition object is + * signaled by the other thread. + */ + ArLog::log(ArLog::Normal, "Main thread: Waiting on condition object..."); + exampleThread.waitOnCondition(); + + ArLog::log(ArLog::Normal, "Main thread: Condition was signaled, and execution continued. Telling the other thread to stop running."); + exampleThread.stopRunning(); + + ArLog::log(ArLog::Normal, "Main thread: Waiting for the other thread to exit, then exiting the program."); + do { + ArUtil::sleep(250); + } while(exampleThread.getRunningWithLock()); + + ArLog::log(ArLog::Normal, "Main thread: Exiting program."); + return 0; +} diff --git a/Legacy/Aria/examples/triangleDriveToActionExample.cpp b/Legacy/Aria/examples/triangleDriveToActionExample.cpp new file mode 100644 index 0000000..5f8ca0e --- /dev/null +++ b/Legacy/Aria/examples/triangleDriveToActionExample.cpp @@ -0,0 +1,130 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ + +/** @example triangleDriveToActionExample.cpp Example/demonstration of + * ArActionTriangleDriveTo, which drives the robot towards a specially shaped + * triangular target + * + Press g or G to use ArActionTriangleDriveTo to detect and drive towards + a triangular target shape. Press s or S to stop. + See ArActionTriangleDriveTo for more information about the triangular target and what the action does and its parameters. + **/ + +#include "Aria.h" + + +int main(int argc, char **argv) +{ + Aria::init(); + + // parse our args and make sure they were all accounted for + ArSimpleConnector connector(&argc, argv); + + ArRobot robot; + + // the laser. ArActionTriangleDriveTo will use this laser object since it is + // named "laser" when added to the ArRobot. + ArSick sick; + + if (!connector.parseArgs() || argc > 1) + { + connector.logOptions(); + Aria::exit(1); + return 1; + } + + // a key handler so we can do our key handling + ArKeyHandler keyHandler; + // let the global aria stuff know about it + Aria::setKeyHandler(&keyHandler); + // toss it on the robot + robot.attachKeyHandler(&keyHandler); + + // add the laser to the robot + robot.addRangeDevice(&sick); + + ArSonarDevice sonar; + robot.addRangeDevice(&sonar); + + ArActionTriangleDriveTo triangleDriveTo; + ArFunctorC lineGoCB(&triangleDriveTo, + &ArActionTriangleDriveTo::activate); + keyHandler.addKeyHandler('g', &lineGoCB); + keyHandler.addKeyHandler('G', &lineGoCB); + ArFunctorC lineStopCB(&triangleDriveTo, + &ArActionTriangleDriveTo::deactivate); + keyHandler.addKeyHandler('s', &lineStopCB); + keyHandler.addKeyHandler('S', &lineStopCB); + + ArActionLimiterForwards limiter("limiter", 150, 0, 0, 1.3); + robot.addAction(&limiter, 70); + ArActionLimiterBackwards limiterBackwards; + robot.addAction(&limiterBackwards, 69); + + robot.addAction(&triangleDriveTo, 60); + + ArActionKeydrive keydrive; + robot.addAction(&keydrive, 55); + + + ArActionStop stopAction; + robot.addAction(&stopAction, 50); + + // try to connect, if we fail exit + if (!connector.connectRobot(&robot)) + { + printf("Could not connect to robot... exiting\n"); + Aria::exit(1); + return 1; + } + + robot.comInt(ArCommands::SONAR, 1); + robot.comInt(ArCommands::ENABLE, 1); + + // start the robot running, true so that if we lose connection the run stops + robot.runAsync(true); + + // now set up the laser + connector.setupLaser(&sick); + + sick.runAsync(); + + if (!sick.blockingConnect()) + { + printf("Could not connect to SICK laser... exiting\n"); + Aria::exit(1); + return 1; + } + + printf("If you press the 'g' key it'll go find a triangle, if you press 's' it'll stop.\n"); + + robot.waitForRunExit(); + Aria::exit(0); + return 0; +} + + + diff --git a/Legacy/Aria/examples/twoRobotWander-vc2003.vcproj b/Legacy/Aria/examples/twoRobotWander-vc2003.vcproj new file mode 100644 index 0000000..93626ff --- /dev/null +++ b/Legacy/Aria/examples/twoRobotWander-vc2003.vcproj @@ -0,0 +1,173 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/examples/twoRobotWander-vc2008.vcproj b/Legacy/Aria/examples/twoRobotWander-vc2008.vcproj new file mode 100644 index 0000000..2c5f6d8 --- /dev/null +++ b/Legacy/Aria/examples/twoRobotWander-vc2008.vcproj @@ -0,0 +1,165 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/examples/twoRobotWander-vc2010.vcxproj b/Legacy/Aria/examples/twoRobotWander-vc2010.vcxproj new file mode 100644 index 0000000..33eeb12 --- /dev/null +++ b/Legacy/Aria/examples/twoRobotWander-vc2010.vcxproj @@ -0,0 +1,139 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + twoRobotWander + + + + + + Application + false + MultiByte + + + Application + false + MultiByte + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + .\../bin\ + .\../obj/release\ + false + .\../bin\ + .\../obj/debug\ + false + + + + MaxSpeed + OnlyExplicitInline + ..\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + true + true + + + Level3 + true + + + Default + + + ws2_32.lib;winmm.lib;AriaVC9.lib;%(AdditionalDependencies) + 1.0 + true + ..\lib;%(AdditionalLibraryDirectories) + false + Console + MachineX86 + + + .\../bin/twoRobotWander.tlb + + + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + + + Disabled + ..\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + true + true + + + true + Level3 + true + + + Default + + + ws2_32.lib;winmm.lib;AriaDebugVC9.lib;%(AdditionalDependencies) + 1.0 + true + ..\lib;%(AdditionalLibraryDirectories) + false + Console + MachineX86 + + + .\../bin/twoRobotWander.tlb + + + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + + + Disabled + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + EnableFastChecks + true + MaxSpeed + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + + + + \ No newline at end of file diff --git a/Legacy/Aria/examples/twoRobotWander.cpp b/Legacy/Aria/examples/twoRobotWander.cpp new file mode 100644 index 0000000..74d199d --- /dev/null +++ b/Legacy/Aria/examples/twoRobotWander.cpp @@ -0,0 +1,231 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#include "Aria.h" + +/* Example showing how two ArRobot objects can be used in one program. + + Normally, a program will only connect to one robot, and will only have + one ArRobot object. However, it is possible to connect to more than + one robot from the same program -- for example, this may be useful for doing + multirobot experiments in a simulator, or to control remote robots with + wireless-serial bridge devices from an offboard computer. This program + demonstrates this by connecting to two robots over TCP connections. + (Old systems with dedicated serial-radio links for each robot would require + modifying this program to use serial connections instead.) + + Specify the hostnames of each robot with -rh1 and -rh2 command line arguments + (defaults are "localhost" for each). Specify port numbers for each with + -rp1 and -rp2 command line arguments (defaults are 8101 for each if + the hostnames are different, or 8101 and 8102 if the hostnames are the same). + + This program will just have two robots wander around, avoiding obstacles + detected by the sonar, or otherwise moving forward at constant velocity. + First it has one robot wander for a period of time, then it has the + second robot wander around. +*/ + +int main(int argc, char** argv) +{ + int ret; + std::string str; + int curRobot; + + // get hostnames and port numbers for connecting to the robots. + ArArgumentParser argParser(&argc, argv); + char* host1 = argParser.checkParameterArgument("-rh1"); + if(!host1) host1 = "localhost"; + char* host2 = argParser.checkParameterArgument("-rh2"); + if(!host2) host2 = "localhost"; + + int port1 = 8101; + int port2 = 8101; + if(strcmp(host1, host2) == 0 ) + { + // same host, it must be using two ports (but can still override below with -rp2) + port2++; + } + + bool argSet = false; + argParser.checkParameterArgumentInteger("-rp1", &port1, &argSet); + if(!argSet) argParser.checkParameterArgumentInteger("-rrtp1", &port1); + argSet = false; + argParser.checkParameterArgumentInteger("-rp2", &port2, &argSet); + if(!argSet) argParser.checkParameterArgumentInteger("-rrtp2", &port2); + + if(!argParser.checkHelpAndWarnUnparsed()) + { + ArLog::log(ArLog::Terse, "Usage: twoRobotWander [-rh1 ] [-rh2 ] [-rp1 ] [-rp2 ]\n"\ + "\t Is the network host name of the first robot."\ + " Default is localhost (for the simulator).\n"\ + "\t Is the network host name of the second robot."\ + " Default is localhost (for the simulator).\n"\ + "\t Is the TCP port number of the first robot. Default is 8101.\n"\ + "\t Is the TCP port number of the second robot. Default is 8102 if"\ + " both robots have the same hostname, or 8101 if they differ.\n\n"); + return 1; + } + + + + // + // The first robot's objects + // + // the first robot connection + ArTcpConnection con1; + // the first robot + ArRobot robot1; + // sonar, must be added to the first robot + ArSonarDevice sonar1; + // the actions we'll use to wander for the first robot + ArActionStallRecover recover1; + ArActionBumpers bumpers1; + ArActionAvoidFront avoidFront1; + ArActionConstantVelocity constantVelocity1("Constant Velocity", 400); + + // + // The second robot's objects + // + // the second robot connection + ArTcpConnection con2; + // the second robot + ArRobot robot2; + // sonar, must be added to the second robot + ArSonarDevice sonar2; + // the actions we'll use to wander for the second robot + ArActionStallRecover recover2; + ArActionBumpers bumpers2; + ArActionAvoidFront avoidFront2; + ArActionConstantVelocity constantVelocity2("Constant Velocity", 400); + + // mandatory init + Aria::init(); + + // + // Lets get robot 1 going + // + + // open the connection, if this fails exit + ArLog::log(ArLog::Normal, "Connecting to first robot at %s:%d...", host1, port1); + if ((ret = con1.open(host1, port1)) != 0) + { + str = con1.getOpenMessage(ret); + printf("Open failed to robot 1: %s\n", str.c_str()); + Aria::exit(1); + return 1; + } + + // add the sonar to the robot + robot1.addRangeDevice(&sonar1); + + // set the device connection on the robot + robot1.setDeviceConnection(&con1); + + // try to connect, if we fail exit + if (!robot1.blockingConnect()) + { + printf("Could not connect to robot 1... exiting\n"); + Aria::exit(1); + return 1; + } + + // turn on the motors, turn off amigobot sounds + robot1.comInt(ArCommands::ENABLE, 1); + robot1.comInt(ArCommands::SOUNDTOG, 0); + + // add the actions + robot1.addAction(&recover1, 100); + robot1.addAction(&bumpers1, 75); + robot1.addAction(&avoidFront1, 50); + robot1.addAction(&constantVelocity1, 25); + + + // + // Lets get robot 2 going + // + + // open the connection, if this fails exit + ArLog::log(ArLog::Normal, "Connecting to second robot at %s:%d...", host2, port2); + if ((ret = con2.open(host2, port2)) != 0) + { + str = con2.getOpenMessage(ret); + printf("Open failed to robot 2: %s\n", str.c_str()); + Aria::exit(1); + return 1; + } + + // add the sonar to the robot + robot2.addRangeDevice(&sonar2); + + // set the device connection on the robot + robot2.setDeviceConnection(&con2); + + // try to connect, if we fail exit + if (!robot2.blockingConnect()) + { + printf("Could not connect to robot 2... exiting\n"); + Aria::exit(1); + return 1; + } + + // turn on the motors, turn off amigobot sounds + robot2.comInt(ArCommands::ENABLE, 1); + robot2.comInt(ArCommands::SOUNDTOG, 0); + + // add the actions + robot2.addAction(&recover2, 100); + robot2.addAction(&bumpers2, 75); + robot2.addAction(&avoidFront2, 50); + robot2.addAction(&constantVelocity2, 25); + + // start the robots running. true so that if we lose connection to either + // robot, the run stops. + robot1.runAsync(true); + robot2.runAsync(true); + + // As long as both robot loops are running, lets alternate between the + // two wandering around. + curRobot=1; + while (robot1.isRunning() && robot2.isRunning()) + { + ArUtil::sleep(10000); + if (curRobot == 1) + { + robot1.stop(); + robot2.clearDirectMotion(); + curRobot=2; + } + else + { + robot2.stop(); + robot1.clearDirectMotion(); + curRobot=1; + } + } + + // now exit + Aria::exit(0); + return 0; +} diff --git a/Legacy/Aria/examples/wander-vc2003.vcproj b/Legacy/Aria/examples/wander-vc2003.vcproj new file mode 100644 index 0000000..2ad412b --- /dev/null +++ b/Legacy/Aria/examples/wander-vc2003.vcproj @@ -0,0 +1,173 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/examples/wander-vc2008.vcproj b/Legacy/Aria/examples/wander-vc2008.vcproj new file mode 100644 index 0000000..5374801 --- /dev/null +++ b/Legacy/Aria/examples/wander-vc2008.vcproj @@ -0,0 +1,234 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/examples/wander-vc2010.vcxproj b/Legacy/Aria/examples/wander-vc2010.vcxproj new file mode 100644 index 0000000..1d4a82c --- /dev/null +++ b/Legacy/Aria/examples/wander-vc2010.vcxproj @@ -0,0 +1,153 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + wander + {5239B513-8B95-4EDB-9FBA-63CB8D7CDEA3} + + + + Application + false + MultiByte + + + Application + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + .\../bin\ + ../obj/$(ProjectName)-$(Configuration)-VC10/ + false + .\../bin\ + ../obj/$(ProjectName)-$(Configuration)-VC10/ + false + $(ProjectName).DebugVC10 + + + + $(IntDir)$(ProjectName)-$(Configuration)-BuildLog.htm + + + .\../bin/wander.tlb + + + + + MaxSpeed + OnlyExplicitInline + ..\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + true + true + + + Level3 + true + + + Default + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + AriaVC10.lib + 1.0 + true + ..\lib;%(AdditionalLibraryDirectories) + false + Console + false + + + MachineX86 + + + + + $(IntDir)$(ProjectName)-$(Configuration)-BuildLog.htm + + + .\../bin/wander.tlb + + + + + Disabled + ..\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + true + true + + + true + Level3 + true + + + Default + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + AriaDebugVC10.lib + 1.0 + true + ..\lib;%(AdditionalLibraryDirectories) + false + Console + false + + + MachineX86 + + + + + Disabled + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + EnableFastChecks + true + MaxSpeed + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + + + + \ No newline at end of file diff --git a/Legacy/Aria/examples/wander.cpp b/Legacy/Aria/examples/wander.cpp new file mode 100644 index 0000000..e817459 --- /dev/null +++ b/Legacy/Aria/examples/wander.cpp @@ -0,0 +1,118 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#include "Aria.h" + + +/** @example wander.cpp + * Example using actions and range devices to implement a random wander avoiding obstacles. + * + * This program will just have the robot wander around. It uses some avoidance + * actions if obstacles are detected with the sonar or laser (if robot has a + * laser), otherwise it just has a constant forward velocity. + * + * Press Control-C or Escape keys to exit. + * + * This program will work either with the MobileSim simulator or on a real + * robot's onboard computer. (Or use -remoteHost to connect to a wireless + * ethernet-serial bridge.) +*/ + +int main(int argc, char **argv) +{ + Aria::init(); + ArArgumentParser argParser(&argc, argv); + argParser.loadDefaultArguments(); + ArRobot robot; + ArRobotConnector robotConnector(&argParser, &robot); + ArLaserConnector laserConnector(&argParser, &robot, &robotConnector); + + // Always try to connect to the first laser: + argParser.addDefaultArgument("-connectLaser"); + + if(!robotConnector.connectRobot()) + { + ArLog::log(ArLog::Terse, "Could not connect to the robot."); + if(argParser.checkHelpAndWarnUnparsed()) + { + // -help not given, just exit. + Aria::logOptions(); + Aria::exit(1); + return 1; + } + } + + + // Trigger argument parsing + if (!Aria::parseArgs() || !argParser.checkHelpAndWarnUnparsed()) + { + Aria::logOptions(); + Aria::exit(1); + return 1; + } + + ArKeyHandler keyHandler; + Aria::setKeyHandler(&keyHandler); + robot.attachKeyHandler(&keyHandler); + + puts("This program will make the robot wander around. It uses some avoidance\n" + "actions if obstacles are detected, otherwise it just has a\n" + "constant forward velocity.\n\nPress CTRL-C or Escape to exit."); + + ArSonarDevice sonar; + robot.addRangeDevice(&sonar); + + robot.runAsync(true); + + + // try to connect to laser. if fail, warn but continue, using sonar only + if(!laserConnector.connectLasers()) + { + ArLog::log(ArLog::Normal, "Warning: unable to connect to requested lasers, will wander using robot sonar only."); + } + + + // turn on the motors, turn off amigobot sounds + robot.enableMotors(); + robot.comInt(ArCommands::SOUNDTOG, 0); + + // add a set of actions that combine together to effect the wander behavior + ArActionStallRecover recover; + ArActionBumpers bumpers; + ArActionAvoidFront avoidFrontNear("Avoid Front Near", 225, 0); + ArActionAvoidFront avoidFrontFar; + ArActionConstantVelocity constantVelocity("Constant Velocity", 400); + robot.addAction(&recover, 100); + robot.addAction(&bumpers, 75); + robot.addAction(&avoidFrontNear, 50); + robot.addAction(&avoidFrontFar, 49); + robot.addAction(&constantVelocity, 25); + + // wait for robot task loop to end before exiting the program + robot.waitForRunExit(); + + Aria::exit(0); + return 0; +} diff --git a/Legacy/Aria/examples/wanderAndLogData-vc2003.vcproj b/Legacy/Aria/examples/wanderAndLogData-vc2003.vcproj new file mode 100644 index 0000000..6463573 --- /dev/null +++ b/Legacy/Aria/examples/wanderAndLogData-vc2003.vcproj @@ -0,0 +1,130 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/examples/wanderAndLogData-vc2008.vcproj b/Legacy/Aria/examples/wanderAndLogData-vc2008.vcproj new file mode 100644 index 0000000..2600d45 --- /dev/null +++ b/Legacy/Aria/examples/wanderAndLogData-vc2008.vcproj @@ -0,0 +1,191 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/examples/wanderAndLogData-vc2010.vcxproj b/Legacy/Aria/examples/wanderAndLogData-vc2010.vcxproj new file mode 100644 index 0000000..4f73f91 --- /dev/null +++ b/Legacy/Aria/examples/wanderAndLogData-vc2010.vcxproj @@ -0,0 +1,114 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + wanderAndLogData + {06616FA8-EBC6-4B23-B70C-E332A19160F1} + wanderAndLogData + ManagedCProj + + + + Application + MultiByte + false + + + Application + MultiByte + false + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + ..\bin\ + ../obj/$(ProjectName)-$(Configuration)-VC10/ + true + ..\bin\ + ../obj/$(ProjectName)-$(Configuration)-VC10/ + false + $(ProjectName).DebugVC10 + + + + $(IntDir)$(ProjectName)-$(Configuration)-BuildLog.htm + + + Disabled + ..\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;%(PreprocessorDefinitions) + false + Default + MultiThreadedDebugDLL + true + + + Level3 + ProgramDatabase + + + AriaDebugVC10.lib + $(OutDir)$(ProjectName).exe + true + ..\lib;%(AdditionalLibraryDirectories) + true + + + false + + + + + + + $(IntDir)$(ProjectName)-$(Configuration)-BuildLog.htm + + + ..\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;%(PreprocessorDefinitions) + false + MultiThreadedDLL + true + + + Level3 + ProgramDatabase + + + AriaVC10.lib + $(OutDir)$(ProjectName).exe + true + ..\lib;%(AdditionalLibraryDirectories) + false + false + + + + + + + + + + + \ No newline at end of file diff --git a/Legacy/Aria/examples/wanderAndLogData.cpp b/Legacy/Aria/examples/wanderAndLogData.cpp new file mode 100644 index 0000000..adbce6b --- /dev/null +++ b/Legacy/Aria/examples/wanderAndLogData.cpp @@ -0,0 +1,352 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#include "Aria.h" +#include + +/* + * This is useful as a diagnostic tool, plus it shows all the many accessor + * methods of ArRobot for robot state. It makes the robot wander, using sonar + * to avoid obstacles, and prints out various pieces of robot state information + * each second. Refer to the ARIA ArRobot documentation and to your robot manual + * (section on standard ARCOS SIP packet contents) for details on the data. + * + * If -connectLaser command line argument is given, or is set in robot parameter + * file, it will use th elaser as well as the sonar to wander. + * + * ARIA also contains a class called ArDataLogger which is configurable through + * ArConfig. You can use ArDataLogger in your applications to incorporate + * a similar data logging feature. + */ + + + +/* function to display a byte as a string of 8 '1' and '0' characters. */ +std::string byte_as_bitstring(char byte) +{ + char tmp[9]; + int bit; + int ch; + for(bit = 7, ch = 0; bit >= 0; bit--,ch++) + tmp[ch] = ((byte>>bit)&1) ? '1' : '0'; + tmp[8] = 0; + return std::string(tmp); +} + +/* function to display a 2-byte int as a string of 16 '1' and '0' characters. */ +std::string int_as_bitstring(ArTypes::Byte2 n) +{ + char tmp[17]; + int bit; + int ch; + for(bit = 15, ch = 0; bit >= 0; bit--, ch++) + tmp[ch] = ((n>>bit)&1) ? '1' : '0'; + tmp[16] = 0; + return std::string(tmp); +} + +std::string charge_state_string(int state) +{ + switch(state) + { + case ArRobot::CHARGING_UNKNOWN: + return "unknown"; + case ArRobot::CHARGING_NOT: + return "not"; + case ArRobot::CHARGING_BULK: + return "bulk"; + case ArRobot::CHARGING_FLOAT: + return "float"; + case ArRobot::CHARGING_OVERCHARGE: + return "over"; + default: + return "UNREC VAL"; + } +} + +/* Some events might only be detectable in one robot cycle, not over the + * 1-second period that the main thread sleeps. This cycle callback will detect + * those and save them in some global variables. */ +bool wasLeftMotorStalled = false; +bool wasRightMotorStalled = false; +ArTypes::UByte2 cumulativeStallVal = 0; +ArTypes::UByte2 cumulativeRobotFlags = 0; +bool wasLeftIRTriggered = false; +bool wasRightIRTriggered = false; +bool wasEStopTriggered = false; + +bool cycleCallback(ArRobot* robot) +{ + cumulativeStallVal |= robot->getStallValue(); + wasLeftMotorStalled = wasLeftMotorStalled || robot->isLeftMotorStalled(); + wasRightMotorStalled = wasRightMotorStalled || robot->isRightMotorStalled(); + wasEStopTriggered = wasEStopTriggered || robot->getEstop(); + wasLeftIRTriggered = wasLeftIRTriggered || (robot->hasTableSensingIR() && robot->isLeftTableSensingIRTriggered()); + wasRightIRTriggered = wasRightIRTriggered || (robot->hasTableSensingIR() && robot->isRightTableSensingIRTriggered()); + return true; +} + + +unsigned int encoderPacketCountPrevSec; +unsigned int encoderPacketCount; +ArTime encoderPacketTimer; + +bool packetCallback(ArRobotPacket *packet) +{ + if(packet->getID() == 0x90) + { + // encoder packet + ++encoderPacketCount; + if(encoderPacketTimer.secSince() >= 1) + { + encoderPacketCountPrevSec = encoderPacketCount; + encoderPacketCount = 0; + encoderPacketTimer.setToNow(); + } + //printf("got an encoder packet. Count=%d, CountPrevSec=%d\n", encoderPacketCount, encoderPacketCountPrevSec); + } + return false; // let other packet handlers (e.g. in ArRobot) be called +} + + +ArActionGroup *ToggleActionGroup = NULL; +bool ToggleActionGroupActive = false; +void toggleaction(int signal) +{ + ArLog::log(ArLog::Normal, "%s action group.", ToggleActionGroupActive?"Deactivating":"Activating"); + if(ToggleActionGroupActive) + { + ToggleActionGroup->deactivate(); + ToggleActionGroupActive = false; + } + else + { + ToggleActionGroup->activate(); + ToggleActionGroupActive = true; + } +} + + +/* main function */ +int main(int argc, char **argv) +{ + Aria::init(); + ArLog::init(ArLog::StdErr, ArLog::Normal); + + // robot and devices + ArRobot robot; + ArSonarDevice sonar; + ArBumpers bumpers; + ArIRs ir; + + // the actions we'll use to wander and avoid obstacles + ArActionStallRecover recoverAct; + ArActionBumpers bumpAct; + ArActionAvoidFront avoidFrontNearAct("Avoid Front Near", 225, 0); + ArActionAvoidFront avoidFrontFarAct; + ArActionConstantVelocity constantVelocityAct("Constant Velocity", 400); + + printf("This program will make the robot wander around, avoiding obstacles, and print some data and events.\nPress Ctrl-C to exit. Send SIGUSR1 signal to toggle wandering.\n"); + + + ArArgumentParser parser(&argc, argv); + parser.loadDefaultArguments(); + ArRobotConnector robotConnector(&parser, &robot); + + if (!Aria::parseArgs() || !parser.checkHelpAndWarnUnparsed()) + { + ArLog::log(ArLog::Terse, "wanderAndLogData: Could not connect to the robot."); + if(parser.checkHelpAndWarnUnparsed()) + { + Aria::logOptions(); + Aria::exit(1); + return 1; + } + } + + if(!robotConnector.connectRobot()) + { + ArLog::log(ArLog::Terse, "wanderAndLogData: Could not connect to the robot."); + Aria::exit(2); + return 2; + } + + ArLog::log(ArLog::Normal, "wanderAndLogData: Connected."); + + ArLaserConnector laserConnector(&parser, &robot, &robotConnector); + if(!laserConnector.connectLasers()) + ArLog::log(ArLog::Normal, "Warning: unable to connect to requested lasers, will wander using robot sonar only."); + + + // add the range devices to the robot + robot.addRangeDevice(&sonar); + robot.addRangeDevice(&bumpers); + robot.addRangeDevice(&ir); + + // turn on the motors, turn off amigobot sound effects (for old h8-model amigobots) + robot.enableMotors(); + robot.comInt(ArCommands::SOUNDTOG, 0); + + // add the actions created above + ArActionGroup wanderGroup(&robot); + wanderGroup.addAction(&recoverAct, 100); + wanderGroup.addAction(&bumpAct, 75); + wanderGroup.addAction(&avoidFrontNearAct, 50); + wanderGroup.addAction(&avoidFrontFarAct, 49); + wanderGroup.addAction(&constantVelocityAct, 25); + ToggleActionGroup = &wanderGroup; + + // can use SIGUSR1 to disable wandering (use Linux kill command) + signal(SIGUSR1, toggleaction); + + + // Cycle callback to check for events + robot.addUserTask("checkevents", 1, new ArGlobalRetFunctor1(&cycleCallback, &robot)); + + // Packet callback to count packets recieved of different types + encoderPacketCount = 0; + encoderPacketCountPrevSec = 0; + encoderPacketTimer.setToNow(); + robot.addPacketHandler(new ArGlobalRetFunctor1(&packetCallback), ArListPos::FIRST); + + // Activate the wander action + if(!parser.checkArgument("nowander")) + { + ArLog::log(ArLog::Normal, "Beginning wandering actions. Send SIGUSR1 to deactivate wander."); + wanderGroup.activate(); + ToggleActionGroupActive = true; + } + else + { + ArLog::log(ArLog::Normal, "Not activating wandering actions since -nowander option was given. Send SIGUSR1 to activate wander."); + wanderGroup.deactivate(); + ToggleActionGroupActive = false; + } + + // start the robot running, true means that if we lose robot connection the + // ArRobot runloop stops + robot.runAsync(true); + + // Print data header +#define HEADFORMAT "%-24s %-5s %-16s %-5s %-6s %-6s %-16s %-8s %-8s %-8s %-8s %-8s %-8s %-10s %-10s %-5s %-5s %-5s %8s %s" +#define DATAFORMAT "%-24s %03.02f %-16s %-5s %-6s %-6s %-16s %-8d %-8d %-8g %-8g %-8s %-8s %-10lu %-10lu %-5s %-5s %-5d %6s " // doesn't include bumps details on end + printf("\n" HEADFORMAT "\n\n", + "Time", + "Volts", + "Flags", + "EStop", + "StallL", + "StallR", + "StallVal", + "#SIP/s", + "#Son/s", + "Vel L", + "Vel R", + "DigIns", + "DigOuts", + "Enc L", + "Enc R", + "IR L", + "IR R", + "#Enc/s", + "Chargestate", + "Cur Bumps, (Last Bump Pose)" + ); + + // Request that we will want encoder data + robot.requestEncoderPackets(); + + // Print data every second + char timestamp[24]; + while(robot.isRunning()) { + robot.lock(); + time_t t = time(NULL); + strftime(timestamp, 24, "%Y-%m-%d %H:%M:%S", localtime(&t)); + printf( DATAFORMAT, + timestamp, + robot.getRealBatteryVoltage(), + int_as_bitstring(cumulativeRobotFlags).c_str(), + (wasEStopTriggered ? "YES" : " "), + (wasLeftMotorStalled?"YES":" "), + (wasRightMotorStalled?"YES":" "), + int_as_bitstring(cumulativeStallVal).c_str(), + robot.getMotorPacCount(), + robot.getSonarPacCount(), + robot.getLeftVel(), + robot.getRightVel(), + byte_as_bitstring(robot.getDigIn()).c_str(), + byte_as_bitstring(robot.getDigOut()).c_str(), + robot.getLeftEncoder(), + robot.getRightEncoder(), + wasLeftIRTriggered?"YES": " ", + wasRightIRTriggered?"YES":" ", + encoderPacketCountPrevSec, + charge_state_string(robot.getChargeState()).c_str() + ); + + // list indices of bumpers flaged in stallval + // skip the last bit which is a motor stall flag + ArTypes::UByte2 bumpmask = ArUtil::BIT15; + int bump = 0; + for(int bit = 16; bit > 0; bit--) + { + if(bit == 9) // this is also a motor stall bit + { + bumpmask = bumpmask >> 1; + bit--; + continue; + } + //printf("\n\tComparing stallval=%s to bumpmask=%s... ", int_as_bitstring(stallval).c_str(), int_as_bitstring(bumpmask).c_str()); + if(cumulativeStallVal & bumpmask) + printf("%d ", bump); + bumpmask = bumpmask >> 1; + bump++; + } + + // print pose of last bump sensor reading + const std::list* bumpsensed = bumpers.getCurrentBuffer(); + if(bumpsensed) + { + //printf("%d readings. ", bumpsensed->size()); + if(bumpsensed->size() > 0 && bumpsensed->front()) { + printf("(%.0f,%.0f)", bumpsensed->front()->getX(), bumpsensed->front()->getY()); + } + } + + + puts(""); // newline + + // clear events to accumulate for the next second + cumulativeRobotFlags = cumulativeStallVal = 0; + wasLeftMotorStalled = wasRightMotorStalled = wasLeftIRTriggered = wasRightIRTriggered = wasEStopTriggered = false; + + robot.unlock(); + ArUtil::sleep(1000); + } + + // robot cycle stopped, probably because of lost robot connection + Aria::exit(0); // exit program + return 0; +} diff --git a/Legacy/Aria/icon.png b/Legacy/Aria/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..dc7b97ecc83d985a4f7969856e0e8d2d860721f3 GIT binary patch literal 4671 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 mySensorTaskCB; + ArRobot *myRobot; + ArTcpConnection myConn; + int myBlobNum[NUM_CHANNELS]; + int myBlobIndex[NUM_CHANNELS]; + char myData[MAX_DATA]; + bool myBlobsBad; + bool myRequested; + // these are for flipping the image + bool myInverted; + int myHeight; + int myWidth; +}; + +#endif diff --git a/Legacy/Aria/include/ArAMPTU.h b/Legacy/Aria/include/ArAMPTU.h new file mode 100644 index 0000000..5b32a36 --- /dev/null +++ b/Legacy/Aria/include/ArAMPTU.h @@ -0,0 +1,152 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARAMPTU_H +#define ARAMPTU_H + +#include "ariaTypedefs.h" +#include "ArBasePacket.h" +#include "ArPTZ.h" + +/// A class with the commands for the AMPTU +class ArAMPTUCommands +{ +public: + enum { + ABSTILT = 0x35, ///< Absolute tilt + RELTILTU = 0x36, ///< Relative tilt, up + RELTILTD = 0x37, ///< Relative tilt, down + ABSPAN = 0x31, ///< Absolute pan + RELPANCW = 0x32, ///< Relative pan, clockwise + RELPANCCW = 0x33, ///< Relative pan, counter clockwise + PANTILT = 0x28, ///< Pan and tilt absolute + PANTILTUCW = 0x29, ///< Relative tilt up, pan clockwise + PANTILTDCW = 0x2A, ///< Relative tilt down, pan clockwise + PANTILTUCCW = 0x2B, ///< Relative tilt up, pan counter-clockwise + PANTILTDCCW = 0x2C, ///< Relative tilt down, pan counter-clockwise + ZOOM = 0x3F, ///< Zoom + PAUSE = 0x39, ///< Pause the current movement + CONT = 0x3A, ///< Continue paused movement + PURGE = 0x3B, ///< Stops movement and purges commands + STATUS = 0x3C, ///< Requests a status packet + INIT = 0x3D, ///< Initializes the camera + RESP = 0x3E, ///< Response + PANSLEW = 0x34, ///< Sets the pan slew rate + TILTSLEW = 0x38 ///< Sets the tilt slew rate + }; + +}; + +/// A class for for making commands to send to the AMPTU +/** + There are only a few functioning ways to put things into this packet, you + MUST use thse, if you use anything else your commands won't work. You + must use byteToBuf and byte2ToBuf. + @see getUnitNumber + @see setUnitNumber +*/ +class ArAMPTUPacket: public ArBasePacket +{ +public: + /// Constructor + AREXPORT ArAMPTUPacket(ArTypes::UByte2 bufferSize = 30); + /// Destructor + AREXPORT virtual ~ArAMPTUPacket(); + + /// Gets the unit number this packet is for + AREXPORT unsigned char getUnitNumber(void); + /// Sets the unit number htis packet is for + AREXPORT bool setUnitNumber(unsigned char unitNumber); + + AREXPORT virtual void byteToBuf(ArTypes::Byte val); + AREXPORT virtual void byte2ToBuf(ArTypes::Byte2 val); + + AREXPORT virtual void finalizePacket(void); + +protected: + unsigned char myUnitNumber; +}; + +/// Driver for the AMPTU +/// @ingroup ObscureClasses +class ArAMPTU : public ArPTZ +{ +public: + /// Constructor + AREXPORT ArAMPTU(ArRobot *robot, int unitNumber = 0); + /// Destructor + AREXPORT virtual ~ArAMPTU(); + AREXPORT virtual bool init(void); + AREXPORT virtual const char *getTypeName() { return "amptu"; } +protected: + AREXPORT virtual bool pan_i(double deg); + AREXPORT virtual bool panRel_i(double deg); + AREXPORT virtual bool tilt_i(double deg); + AREXPORT virtual bool tiltRel_i(double deg); + AREXPORT virtual bool panTilt_i(double panDeg, double tiltDeg); + AREXPORT virtual bool panTiltRel_i(double panDeg, double tiltDeg); +public: + /// Sets the rate that the camera pans at + AREXPORT bool panSlew(double deg); + /// Sets the rate the camera tilts at + AREXPORT bool tiltSlew(double deg); + virtual bool canZoom(void) const { return false; } + virtual bool canPanTiltSlew() { return true; } + + + + /// Stops current pan/tilt, can be resumed later + AREXPORT bool pause(void); + /// Resumes a previously paused pan/tilt + AREXPORT bool resume(void); + /// Stops motion and purges last command + AREXPORT bool purge(void); + /// Retrieves the camera status + AREXPORT bool requestStatus(void); + /// Gets the angle the camera is panned to + AREXPORT virtual double getPan_i(void) const { return myPan; } + /// Gets the angle the camera is tilted to + AREXPORT virtual double getTilt_i(void) const { return myTilt; } + enum { + MIN_SLEW = 15, + MAX_TILT_SLEW = 200, + MAX_PAN_SLEW = 120 + }; +protected: + ArRobot *myRobot; + ArAMPTUPacket myPacket; + int myUnitNumber; + double myPan; + double myTilt; + double myPanSlew; + double myTiltSlew; + /*double myCurPan; + double myCurTilt; + double myCurPanSlew; + double myCurTiltSlew;*/ +}; + +#endif // ARAMPTU_H + diff --git a/Legacy/Aria/include/ArASyncTask.h b/Legacy/Aria/include/ArASyncTask.h new file mode 100644 index 0000000..8528e89 --- /dev/null +++ b/Legacy/Aria/include/ArASyncTask.h @@ -0,0 +1,109 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ + +#ifndef ARASYNCTASK_H +#define ARASYNCTASK_H + + +#include "ariaTypedefs.h" +#include "ArFunctor.h" +#include "ArThread.h" + + +/// Asynchronous task (runs in its own thread) +/** + The ArAsynTask is a task that runs in its own thread. This is a + rather simple class. The user simply needs to derive their own + class from ArAsyncTask and define the runThread() function. They + then need to create an instance of their task and call run or + runAsync. The standard way to stop a task is to call stopRunning() + which sets ArThread::myRunning to false. In their run loop, they + should pay attention to the getRunning() or the ArThread::myRunning + variable. If this value goes to false, the task should clean up + after itself and exit its runThread() function. + + @ingroup UtilityClasses +**/ +class ArASyncTask : public ArThread +{ +public: + + /// Constructor + AREXPORT ArASyncTask(); + /// Destructor + AREXPORT virtual ~ArASyncTask(); + + /// The main run loop + /** + Override this function and put your taskes run loop here. Check the + value of getRunning() periodicly in your loop. If the value + is false, the loop should exit and runThread() should return. + The argument and return value are specific to the platform thread implementation, and + can be ignored. + @swignote In the wrapper libraries, this method takes no arguments and has no return value. + */ + AREXPORT virtual void * runThread(void *arg) = 0; + + /// Run without creating a new thread +/** + This will run the the ArASyncTask without creating a new + thread to run it in. It performs the needed setup then calls runThread() + directly instead of letting the system threading system do it in a new thread. +*/ + virtual void run(void) { runInThisThread(); } + + /// Run in its own thread + virtual void runAsync(void) { create(); } + + // reimplemented here just so its easier to see in the docs + /// Stop the thread + virtual void stopRunning(void) {myRunning=false;} + + /// Create the task and start it going + AREXPORT virtual int create(bool joinable=true, bool lowerPriority=true); + + /** Internal function used with system threading system to run the new thread. + In general, use run() or runAsync() instead. + @internal + */ + AREXPORT virtual void * runInThisThread(void *arg=0); + + /// Gets a string that describes what the thread is doing, or NULL if it + /// doesn't know. Override this in your subclass to return a status + /// string. This can be used for debugging or UI display. + virtual const char *getThreadActivity(void) { return NULL; } +private: + + // Hide regular Thread::Create + virtual int create(ArFunctor * /*func*/, bool /*joinable=true*/, + bool /*lowerPriority=true*/) {return(false);} + + + ArRetFunctor1C myFunc; +}; + + +#endif // ARASYNCTASK_H diff --git a/Legacy/Aria/include/ArAction.h b/Legacy/Aria/include/ArAction.h new file mode 100644 index 0000000..8974f68 --- /dev/null +++ b/Legacy/Aria/include/ArAction.h @@ -0,0 +1,142 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARACTION_H +#define ARACTION_H + +#include "ariaTypedefs.h" +#include "ArArg.h" +#include "ArActionDesired.h" +#include +#include + +class ArRobot; + +/** @brief Base class for actions + + @ref actions Actions are objects queried for desired behavior by + ArActionResolver to determine robot movement commands. + + To implement an action object, define a subclass of ArAction, + and implement the fire() method. You may also override + setRobot() to obtain information from ArRobot, but you + must also call ArAction::setRobot() so that the ArRobot pointer + is stored by ArAction. + + Several predefined action objects are also included in ARIA, + they are listed here as ArActions's subclasses. + + If an action is not active (it has been deactivated), then + it will be ignored by the action resolver. + Actions may be grouped using ArActionGroup, and activated/deactivated as a group. For example, ArMode, and ArServerMode (from ArNetworking), activate/deactivate action groups when switching modes. + + @see @ref actions description in the ARIA overview. + @see ArActionGroup + @see ArResolver + @see ArRobot + + @ingroup ActionClasses + @ingroup OptionalClasses +*/ +class ArAction +{ +public: + /// Constructor + AREXPORT ArAction(const char * name, const char * description = ""); + /// Desructor + AREXPORT virtual ~ArAction(); + /// Returns whether the action is active or not + AREXPORT virtual bool isActive(void) const; + /// Activate the action + AREXPORT virtual void activate(void); + /// Deactivate the action + AREXPORT virtual void deactivate(void); + /// Fires the action, returning what the action wants to do + /** + @param currentDesired this is the tentative result, based + on the resolver's processing of previous, higher-priority actions. + This is only for the purpose of giving information to the + action, changing it has no effect. + @return pointer to what this action wants to do, NULL if it wants to do + nothing. Common practice is to keep an ArActionDesired + object in your action subclass, and return a pointer to + that object. This avoids the need to create + new objects during each invocation (which could never + be deleted). + Clear your stored ArActionDesired + before modifying it with ArActionDesired::reset(). + */ + AREXPORT virtual ArActionDesired *fire(ArActionDesired currentDesired) = 0; + /// Sets the robot this action is driving + AREXPORT virtual void setRobot(ArRobot *robot); + /// Find the number of arguments this action takes + AREXPORT virtual int getNumArgs(void) const; +#ifndef SWIG + /** Gets the numbered argument + * @swignote Not available + */ + AREXPORT virtual const ArArg *getArg(int number) const; +#endif // SWIG + /// Gets the numbered argument + AREXPORT virtual ArArg *getArg(int number); + /// Gets the name of the action + AREXPORT virtual const char *getName(void) const; + /// Gets the long description of the action + AREXPORT virtual const char *getDescription(void) const; + /// Gets what this action wants to do (for display purposes) + AREXPORT virtual ArActionDesired *getDesired(void) { return NULL; } + /// Gets what this action wants to do (for display purposes) + AREXPORT virtual const ArActionDesired *getDesired(void) const { return NULL; } + /// Log information about this action using ArLog. + AREXPORT virtual void log(bool verbose = true) const; + + /// Get the robot we are controlling, which was set by setRobot() + AREXPORT ArRobot* getRobot() const { return myRobot; } + + /// Sets the default activation state for all ArActions + static void setDefaultActivationState(bool defaultActivationState) + { ourDefaultActivationState = defaultActivationState; } + /// Gets the default activation state for all ArActions + static bool getDefaultActivationState(void) + { return ourDefaultActivationState; } +protected: + /// Sets the argument type for the next argument (must only be used in a constructor!) + AREXPORT void setNextArgument(ArArg const &arg); + + /// The robot we are controlling, set by the action resolver using setRobot() + ArRobot *myRobot; + + // These are mostly for internal use by ArAction, not subclasses: + bool myIsActive; + int myNumArgs; + std::map myArgumentMap; + std::string myName; + std::string myDescription; + + AREXPORT static bool ourDefaultActivationState; +}; + + +#endif //ARACTION_H diff --git a/Legacy/Aria/include/ArActionAvoidFront.h b/Legacy/Aria/include/ArActionAvoidFront.h new file mode 100644 index 0000000..864f1a4 --- /dev/null +++ b/Legacy/Aria/include/ArActionAvoidFront.h @@ -0,0 +1,78 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARACTIONAVOIDFRONT_H +#define ARACTIONAVOIDFRONT_H + +#include "ariaTypedefs.h" +#include "ariaUtil.h" +#include "ArFunctor.h" +#include "ArAction.h" + +/// This action does obstacle avoidance, controlling both trans and rot +/** + This action uses whatever available range device have been added to + the robot to avoid obstacles. See the ArActionAvoidFront + constructor documentation to see the parameters it takes. + + Also note that this action does something most others don't, which + is to check for a specific piece of hardware. This is the + tableSensingIR. If this is set up in the parameters for the robot, + it will use DigIn0 and DigIn1, where the tableSensingIRs are + connected. Note that if you make useTableIRIfAvail false in the + constructor it'll ignore these. Whether the action thinks the robot + has them or not depends on the value of tableSensingIR in the + parameter file for that robot. + + @ingroup ActionClasses +*/ +class ArActionAvoidFront : public ArAction +{ +public: + /// Constructor + AREXPORT ArActionAvoidFront(const char *name = "avoid front obstacles", + double obstacleDistance = 450, double avoidVelocity = 200, + double turnAmount = 15, bool useTableIRIfAvail = true); + /// Destructor + AREXPORT virtual ~ArActionAvoidFront(); + AREXPORT virtual ArActionDesired *fire(ArActionDesired currentDesired); + AREXPORT virtual ArActionDesired *getDesired(void) { return &myDesired; } +#ifndef SWIG + AREXPORT virtual const ArActionDesired *getDesired(void) const + { return &myDesired; } +#endif +protected: + double myTurnAmount; + double myObsDist; + double myAvoidVel; + double myTurnAmountParam; + bool myUseTableIRIfAvail; + int myTurning; // 1 for turning left, 0 for not turning, -1 for turning right + ArActionDesired myDesired; + ArSectors myQuadrants; + ArFunctorC myConnectCB; +}; + +#endif // ARACTIONAVOIDFRONT_H diff --git a/Legacy/Aria/include/ArActionAvoidSide.h b/Legacy/Aria/include/ArActionAvoidSide.h new file mode 100644 index 0000000..0280c41 --- /dev/null +++ b/Legacy/Aria/include/ArActionAvoidSide.h @@ -0,0 +1,62 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARACTIONAVOIDSIDE_H +#define ARACTIONAVOIDSIDE_H + +#include "ariaTypedefs.h" +#include "ArAction.h" + +/// Action to avoid impacts by firening into walls at a shallow angle +/** + This action watches the sensors to see if it is close to firening into a wall + at a shallow enough angle that other avoidance may not avoid. + + @ingroup ActionClasses +*/ +class ArActionAvoidSide : public ArAction +{ +public: + /// Constructor + AREXPORT ArActionAvoidSide(const char *name = "Avoid side", + double obstacleDistance = 300, + double turnAmount = 5); + /// Destructor + AREXPORT virtual ~ArActionAvoidSide(); + AREXPORT virtual ArActionDesired * fire(ArActionDesired currentDesired); + AREXPORT virtual ArActionDesired *getDesired(void) { return &myDesired; } +#ifndef SWIG + AREXPORT virtual const ArActionDesired *getDesired(void) const + { return &myDesired; } +#endif +protected: + double myObsDist; + double myTurnAmount; + bool myTurning; + ArActionDesired myDesired; + +}; + +#endif // ARACTIONAVOIDSIDE_H diff --git a/Legacy/Aria/include/ArActionBumpers.h b/Legacy/Aria/include/ArActionBumpers.h new file mode 100644 index 0000000..18764aa --- /dev/null +++ b/Legacy/Aria/include/ArActionBumpers.h @@ -0,0 +1,77 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ + +#ifndef ARACTIONBUMPERS_H +#define ARACTIONBUMPERS_H + +#include "ariaTypedefs.h" +#include "ArAction.h" + +/// Action to deal with if the bumpers trigger +/** + This class basically responds to the bumpers the robot has, what + the activity things the robot has is decided by the param file. If + the robot is going forwards and bumps into something with the front + bumpers, it will back up and turn. If the robot is going backwards + and bumps into something with the rear bumpers then the robot will + move forward and turn. + + @ingroup ActionClasses +*/ + +class ArActionBumpers : public ArAction +{ +public: + /// Constructor + AREXPORT ArActionBumpers(const char *name = "bumpers", + double backOffSpeed = 100, int backOffTime = 3000, + int turnTime = 3000, bool setMaximums = false); + /// Destructor + AREXPORT virtual ~ArActionBumpers(); + AREXPORT virtual ArActionDesired *fire(ArActionDesired currentDesired); + AREXPORT virtual ArActionDesired *getDesired(void) { return &myDesired; } +#ifndef SWIG + AREXPORT virtual const ArActionDesired *getDesired(void) const + { return &myDesired; } +#endif + AREXPORT double findDegreesToTurn(int bumpValue, int whichBumper); + AREXPORT virtual void activate(void); +protected: + ArActionDesired myDesired; + bool mySetMaximums; + double myBackOffSpeed; + int myBackOffTime; + int myTurnTime; + //int myStopTime; + bool myFiring; + double mySpeed; + double myHeading; + int myBumpMask; + ArTime myStartBack; + //ArTime myStoppedSince; +}; + +#endif // ARACTIONBUMPERS diff --git a/Legacy/Aria/include/ArActionColorFollow.h b/Legacy/Aria/include/ArActionColorFollow.h new file mode 100644 index 0000000..975b257 --- /dev/null +++ b/Legacy/Aria/include/ArActionColorFollow.h @@ -0,0 +1,131 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARACTIONCOLORFOLLOW_H +#define ARACTIONCOLORFOLLOW_H + +#include "ariaTypedefs.h" +#include "ariaUtil.h" +#include "ArFunctor.h" +#include "ArAction.h" +#include "ArACTS.h" +#include "ArPTZ.h" + +/// ArActionColorFollow is an action that moves the robot toward the +/// largest ACTS blob that appears in it's current field of view. +/// @ingroup ActionClasses +class ArActionColorFollow : public ArAction +{ + +public: + // Constructor + AREXPORT ArActionColorFollow(const char *name, + ArACTS_1_2 *acts, + ArPTZ *camera, + double speed = 200, + int width = 160, + int height = 120); + + // Destructor + AREXPORT virtual ~ArActionColorFollow(void); + + // The action + AREXPORT virtual ArActionDesired *fire(ArActionDesired currentDesired); + + // Set the ACTS channel that we want to get blob info out of + AREXPORT bool setChannel(int channel); + + // Set the camera that we will be controlling + AREXPORT void setCamera(ArPTZ *camera); + + // Toggle whether we should try to acquire a blob + // if one cannot be seen + AREXPORT void setAcquire(bool acquire); + + // Stop moving alltogether + AREXPORT void stopMovement(void); + + // Start moving + AREXPORT void startMovement(void); + + // Return the channel that we are looking for blobs on + AREXPORT int getChannel(); + + // Return whether or not we are trying to acquire a blob + // if we cannot see one + AREXPORT bool getAcquire(); + + // Return whether or not we are moving + AREXPORT bool getMovement(); + + // Return whether or not we can see a target + AREXPORT bool getBlob(); + + // The state of the action + enum TargetState + { + NO_TARGET, // There is no target in view + TARGET // There is a target in view + }; + + // The state of movement + enum MoveState + { + FOLLOWING, // Following a blob + ACQUIRING, // Searching for a blob + STOPPED // Sitting still + }; + + // The last seen location of the blob + enum LocationState + { + LEFT, // The blob is on the left side of the screen + RIGHT, // The blob is on the right side of the screen + CENTER // The blob is relatively close to the center + }; + AREXPORT virtual ArActionDesired *getDesired(void) { return &myDesired; } +#ifndef SWIG + AREXPORT virtual const ArActionDesired *getDesired(void) const + { return &myDesired; } +#endif +protected: + ArActionDesired myDesired; + ArACTS_1_2 *myActs; + ArPTZ *myCamera; + ArTime myLastSeen; + TargetState myState; + MoveState myMove; + LocationState myLocation; + bool myAcquire; + bool killMovement; + int myChannel; + int myMaxTime; + int myHeight; + int myWidth; + double mySpeed; +}; + + +#endif // ARACTIONCOLORFOLLOW_H diff --git a/Legacy/Aria/include/ArActionConstantVelocity.h b/Legacy/Aria/include/ArActionConstantVelocity.h new file mode 100644 index 0000000..b65992c --- /dev/null +++ b/Legacy/Aria/include/ArActionConstantVelocity.h @@ -0,0 +1,56 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARACTIONCONSTANTVELOCITY_H +#define ARACTIONCONSTANTVELOCITY_H + +#include "ariaTypedefs.h" +#include "ArAction.h" + +/// Action for going straight at a constant velocity +/** + This action simply goes straight at a constant velocity. + @ingroup ActionClasses +*/ +class ArActionConstantVelocity : public ArAction +{ +public: + /// Constructor + AREXPORT ArActionConstantVelocity(const char *name = "Constant Velocity", + double velocity = 400); + /// Destructor + AREXPORT virtual ~ArActionConstantVelocity(); + AREXPORT virtual ArActionDesired *fire(ArActionDesired currentDesired); + AREXPORT virtual ArActionDesired *getDesired(void) { return &myDesired; } +#ifndef SWIG + AREXPORT virtual const ArActionDesired *getDesired(void) const + { return &myDesired; } +#endif +protected: + double myVelocity; + ArActionDesired myDesired; +}; + +#endif // ARACTIONCONSTANTVELOCITY_H diff --git a/Legacy/Aria/include/ArActionDeceleratingLimiter.h b/Legacy/Aria/include/ArActionDeceleratingLimiter.h new file mode 100644 index 0000000..281b0d6 --- /dev/null +++ b/Legacy/Aria/include/ArActionDeceleratingLimiter.h @@ -0,0 +1,114 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARACTIONDECELERATINGLIMITER_H +#define ARACTIONDECELERATINGLIMITER_H + +#include "ariaTypedefs.h" +#include "ArAction.h" + +/// Action to limit the forwards motion of the robot based on range sensor readings +/** + This action uses the robot's range sensors (e.g. sonar, laser) to find a + maximum speed at which to travel + and will increase the deceleration so that the robot doesn't hit + anything. If it has to, it will trigger an estop to avoid a + collision. + + Note that this cranks up the deceleration with a strong strength, + but it checks to see if there is already something decelerating + more strongly... so you can put these actions lower in the priority list so + things will play together nicely. + @ingroup ActionClasses +**/ +class ArActionDeceleratingLimiter : public ArAction +{ +public: + enum LimiterType { + FORWARDS, ///< Limit forwards + BACKWARDS, ///< Limit backwards + LATERAL_LEFT, ///< Limit lateral left + LATERAL_RIGHT ///< Limit lateral right + + }; + /// Constructor + AREXPORT ArActionDeceleratingLimiter(const char *name = "limitAndDecel", + LimiterType type = FORWARDS); + /// Destructor + AREXPORT virtual ~ArActionDeceleratingLimiter(); + AREXPORT virtual ArActionDesired *fire(ArActionDesired currentDesired); + AREXPORT virtual ArActionDesired *getDesired(void) { return &myDesired; } +#ifndef SWIG + AREXPORT virtual const ArActionDesired *getDesired(void) const + { return &myDesired; } +#endif + /// Sets the parameters (don't use this if you're using the addToConfig) + AREXPORT void setParameters(double clearance = 100, + double sideClearanceAtSlowSpeed = 50, + double paddingAtSlowSpeed = 50, + double slowSpeed = 200, + double sideClearanceAtFastSpeed = 400, + double paddingAtFastSpeed = 300, + double fastSpeed = 1000, + double preferredDecel = 600, + bool useEStop = false, + double maxEmergencyDecel = 0); + /// Gets if this will control us when going forwards + LimiterType getType(void) { return myType; } + /// Sets if this will control us when going forwards + void setType(LimiterType type) { myType = type; } + /// Adds to the ArConfig given, in section, with prefix + AREXPORT void addToConfig(ArConfig *config, const char *section, + const char *prefix = NULL); + /// Sets if we're using locationDependent range devices or not + bool getUseLocationDependentDevices(void) + { return myUseLocationDependentDevices; } + /// Sets if we're using locationDependent range devices or not + void setUseLocationDependentDevices(bool useLocationDependentDevices) + { myUseLocationDependentDevices = useLocationDependentDevices; } + // sets if we should stop rotation too if this action has stopped the robot + void setStopRotationToo(bool stopRotationToo) + { myStopRotationToo = stopRotationToo; } +protected: + bool myLastStopped; + LimiterType myType; + double myClearance; + double mySideClearanceAtSlowSpeed; + double myPaddingAtSlowSpeed; + double mySlowSpeed; + double mySideClearanceAtFastSpeed; + double myPaddingAtFastSpeed; + double myFastSpeed; + double myPreferredDecel; + double myMaxEmergencyDecel; + bool myUseEStop; + bool myUseLocationDependentDevices; + bool myStopRotationToo; + +//unused? double myDecelerateDistance; + ArActionDesired myDesired; +}; + +#endif // ARACTIONSPEEDLIMITER_H diff --git a/Legacy/Aria/include/ArActionDesired.h b/Legacy/Aria/include/ArActionDesired.h new file mode 100644 index 0000000..fc0ee67 --- /dev/null +++ b/Legacy/Aria/include/ArActionDesired.h @@ -0,0 +1,878 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARACTIONDESIRED_H +#define ARACTIONDESIRED_H + +#include "ariaTypedefs.h" +#include "ariaUtil.h" + +/// Class used by ArActionDesired for each channel, internal +class ArActionDesiredChannel +{ +public: + AREXPORT static const double NO_STRENGTH; + AREXPORT static const double MIN_STRENGTH; + AREXPORT static const double MAX_STRENGTH; + + ArActionDesiredChannel() { reset(); myOverrideDoesLessThan = true; } + ~ArActionDesiredChannel() {} + void setOverrideDoesLessThan(bool overrideDoesLessThan) + { myOverrideDoesLessThan = overrideDoesLessThan; } + void setDesired(double desired, double desiredStrength, + bool allowOverride = false) + { + myDesired = desired; + myStrength = desiredStrength; + myAllowOverride = allowOverride; + if (myStrength > MAX_STRENGTH) + myStrength = MAX_STRENGTH; + if (myStrength < MIN_STRENGTH) + myStrength = NO_STRENGTH; + } + double getDesired(void) const { return myDesired; } + double getStrength(void) const { return myStrength; } + double getAllowOverride(void) const { return myAllowOverride; } + void reset(void) + { myDesired = 0; myStrength = NO_STRENGTH; myAllowOverride = true; } + void merge(ArActionDesiredChannel *desiredChannel) + { + double otherStrength = desiredChannel->getStrength(); + double oldStrength = myStrength; + if (myStrength + otherStrength > MAX_STRENGTH) + otherStrength = MAX_STRENGTH - myStrength; + myStrength = myStrength + otherStrength; + myAllowOverride = myAllowOverride && desiredChannel->getAllowOverride(); + // if we're allowing override just set myDesired to the least + // (or greatest) value + if (myAllowOverride && myStrength >= MIN_STRENGTH) + { + // if both have strength get the min/max + if (oldStrength >= MIN_STRENGTH && + desiredChannel->getStrength() >= MIN_STRENGTH) + { + if (myOverrideDoesLessThan) + myDesired = ArUtil::findMin(myDesired, + desiredChannel->getDesired()); + else if (!myOverrideDoesLessThan) + myDesired = ArUtil::findMax(myDesired, + desiredChannel->getDesired()); + } + // if only it has strength use it + else if (desiredChannel->getStrength() >= MIN_STRENGTH) + { + myDesired = desiredChannel->getDesired(); + } + // if only this has strength then we don't need to do anything + } + else if (myStrength >= MIN_STRENGTH) + myDesired = (((oldStrength * myDesired) + + (desiredChannel->getDesired() * otherStrength)) + / (myStrength)); + } + void startAverage(void) + { + myDesiredTotal = myDesired * myStrength; + myStrengthTotal = myStrength; + } + void addAverage(ArActionDesiredChannel *desiredChannel) + { + myAllowOverride = myAllowOverride && desiredChannel->getAllowOverride(); + // if we're allowing override then myDesired is just the least + // of the values thats going to come through... still compute + // the old way in case something doesn't want to override it + if (myAllowOverride) + { + // if both have strength get the min/max + if (myStrength >= MIN_STRENGTH && + desiredChannel->getStrength() >= MIN_STRENGTH) + { + if (myOverrideDoesLessThan) + myDesired = ArUtil::findMin(myDesired, + desiredChannel->getDesired()); + else if (!myOverrideDoesLessThan) + myDesired = ArUtil::findMax(myDesired, + desiredChannel->getDesired()); + } + // if only it has strength use it + else if (desiredChannel->getStrength() >= MIN_STRENGTH) + { + myDesired = desiredChannel->getDesired(); + } + // if only this has strength then we don't need to do anything + } + myDesiredTotal += (desiredChannel->getDesired() * + desiredChannel->getStrength()); + myStrengthTotal += desiredChannel->getStrength(); + } + void endAverage(void) + { + if (myStrengthTotal < MIN_STRENGTH) + { + myStrength = NO_STRENGTH; + return; + } + // if we're overriding we just use what myDesired already is + if (!myAllowOverride) + myDesired = (myDesiredTotal / myStrengthTotal); + myStrength = myStrengthTotal; + if (myStrength > MAX_STRENGTH) + myStrength = MAX_STRENGTH; + } + /// do some bounds checking + void checkLowerBound(const char *actionName, const char *typeName, + int lowerBound) + { + // if it has no strength, just return + if (myStrength < MIN_STRENGTH) + return; + + if (ArMath::roundInt(myDesired) < lowerBound) + { + ArLog::log(ArLog::Terse, + "ActionSanityChecking: '%s' tried to set %s to %g (which wound wind up less than %d and will be set to %d)", + actionName, typeName, myDesired, lowerBound, lowerBound); + myDesired = lowerBound; + return; + } + } + /// do some bounds checking + void checkUpperBound(const char *actionName, const char *typeName, + int upperBound) + { + // if it has no strength, just return + if (myStrength < MIN_STRENGTH) + return; + + if (ArMath::roundInt(myDesired) > upperBound) + { + ArLog::log(ArLog::Terse, + "ActionSanityChecking: '%s' tried to set %s to %g (which would wind up greater than %d and will be set to %d)", + actionName, typeName, myDesired, upperBound, upperBound); + myDesired = upperBound; + return; + } + } + + +protected: + double myDesired; + double myStrength; + bool myAllowOverride; + double myDesiredTotal; + double myStrengthTotal; + bool myOverrideDoesLessThan; +}; + +/// Contains values returned by ArAction objects expressing desired motion commands to resolver +/** + This class is use by actions to report what want movement commands they want. + The action resolver combines the ArActionDesired objects returned by different actions. + + A brief summary follows. For a fuller explanation of actions, see @ref actions. + + Different values are organized into different "channels". + Translational (front/back) and rotational (right/left) movements are separate + channels. Translational movement uses velocity, while rotational movement uses + change in heading from current heading. + Each channel has a strength value. + Both translational and rotational movement have maximum velocities as well, + that also have their own strengths. + + The strength value reflects how strongly an action wants to do the chosen + movement command, the resolver (ArResolver) will combine these strengths + and figure out what to do based on them. + + For all strength values there is a total of 1.0 combined strength avaliable. + The range for strength is from 0 to 1. This is simply a convention that + ARIA uses by default, if you don't like it, you could override this + class the ArResolver class. + + Note that for the different maximum/accel/decel values they take an + additional argument of whether just to use the slowest speed, + slowest accel, or fastest decel. By default these will just use + safer values (slowest speed, slowest accel, fastest decel)... you + can specify false on these for the old behavior. Note that if + you're safest values then the strength is largely ignored though it + is still tracked and must still be greater than MIN_STRENGTH to + work and it is still capped at MAX_STRENGTH). + + @sa @ref actions + +*/ +class ArActionDesired +{ +public: + AREXPORT static const double NO_STRENGTH; + AREXPORT static const double MIN_STRENGTH; + AREXPORT static const double MAX_STRENGTH; + /// Constructor + ArActionDesired() + { + myHeadingSet = false; + myTransDecelDes.setOverrideDoesLessThan(false); + myRotDecelDes.setOverrideDoesLessThan(false); + myMaxNegVelDes.setOverrideDoesLessThan(false); + } + /// Destructor + virtual ~ArActionDesired() {} + + /// Sets the velocity (mm/sec) and strength + /** + @param vel desired vel (mm/sec) + @param strength strength given to this, defaults to MAX_STRENGTH (1.0) + */ + virtual void setVel(double vel, double strength = MAX_STRENGTH) + { myVelDes.setDesired(vel, strength); } + /// Sets the delta heading (deg) and strength + /** + If there's already a rotVel set this WILL NOT work. + @param deltaHeading desired change in heading (deg) + @param strength strength given to this, defaults to MAX_STRENGTH (1.0) + */ + virtual void setDeltaHeading(double deltaHeading, + double strength = MAX_STRENGTH) + { myDeltaHeadingDes.setDesired(deltaHeading, strength); } + /// Sets the absolute heading (deg) + /** + If there's already a rotVel set this WILL NOT work. + This is a way to set the heading instead of using a delta, there is no + get for this, because accountForRobotHeading MUST be called (this should + be called by all resolvers, but if you want to call it you can, + thats fine). + @param heading desired heading (deg) + @param strength strength given to this, defaults to MAX_STRENGTH (1.0) + */ + virtual void setHeading(double heading, double strength = MAX_STRENGTH) + { myHeading = heading; myHeadingStrength = strength; myHeadingSet = true; } + + /// Sets the rotational velocity + /** + If there's already a delta heading or heading this WILL NOT work. + @param rotVel desired rotational velocity (deg/sec) + @param strength strength given to this, defaults to MAX_STRENGTH (1.0) + **/ + virtual void setRotVel(double rotVel, double strength = MAX_STRENGTH) + { myRotVelDes.setDesired(rotVel, strength); } + + /// Sets the maximum velocity (+mm/sec) and strength + /** + This sets the maximum positive velocity for this cycle. Check + the ArRobot class notes for more details. + + @param maxVel desired maximum velocity (+mm/sec) + @param strength strength given to this, defaults to MAX_STRENGTH + (1.0) + @param useSlowest if this is true (the default) everywhere + then the slowest maximum vel is what will be selected + **/ + virtual void setMaxVel(double maxVel, double strength = MAX_STRENGTH, + bool useSlowest = true) + { myMaxVelDes.setDesired(maxVel, strength, useSlowest); } + /// Sets the maximum velocity for going backwards (-mm/sec) and strength + /** + This sets the maximum negative velocity for this cycle. Check + the ArRobot class notes for more details. + + @param maxVel desired maximum velocity for going backwards (-mm/sec) + @param strength strength given to this, defaults to MAX_STRENGTH (1.0) + @param useSlowest if this is true (the default) everywhere + then the slowest max neg vel is what will be selected + **/ + virtual void setMaxNegVel(double maxVel, double strength = MAX_STRENGTH, + bool useSlowest = true) + { myMaxNegVelDes.setDesired(maxVel, strength, useSlowest); } + + /// Sets the translation acceleration (deg/sec/sec) and strength + /** + This sets the translation acceleration for this cycle (this is + sent down to the robot). Check the ArRobot class notes for more + details. + + @param transAccel desired translation acceleration (deg/sec/sec) + @param strength strength given to this, defaults to MAX_STRENGTH (1.0) + @param useSlowest if this is true (the default) everywhere then + the slowest accel is what will be selected + **/ + virtual void setTransAccel(double transAccel, + double strength = MAX_STRENGTH, + bool useSlowest = true) + { myTransAccelDes.setDesired(transAccel, strength, useSlowest); } + + /// Sets the translation deceleration (deg/sec/sec) and strength + /** + This sets the translation deceleration for this cycle (this is + sent down to the robot). Check the ArRobot class notes for more + details. + + @param transDecel desired translation deceleration (deg/sec/sec) + @param strength strength given to this, defaults to MAX_STRENGTH (1.0) + @param useFastestDecel if this is true (the default) everywhere + then the fastest decel is what will be selected + **/ + virtual void setTransDecel(double transDecel, double strength = MAX_STRENGTH, + bool useFastestDecel = true) + { myTransDecelDes.setDesired(transDecel, strength, useFastestDecel); } + + /// Sets the maximum rotational velocity (deg/sec) and strength + /** + This sets the maximum rotational velocity for this cycle (this is + sent down to the robot). Check the ArRobot class notes for more + details. + + @param maxVel desired maximum rotational velocity (deg/sec) + @param strength strength given to this, defaults to MAX_STRENGTH (1.0) + @param useSlowest if this is true (the default) everywhere + then the slowest rot vel is what will be selected + **/ + virtual void setMaxRotVel(double maxVel, double strength = MAX_STRENGTH, + bool useSlowest = true) + { myMaxRotVelDes.setDesired(maxVel, strength, useSlowest); } + + /// Sets the maximum rotational velocity (deg/sec) in the positive direction and strength + /** + This sets the maximum rotational velocity for this cycle (this is + sent down to the robot) in the positive direction. If the + setMaxRotVel is set to less than this that will be used instead. + Check the ArRobot class notes for more details. + + @param maxVel desired maximum rotational velocity in the positive + direction (deg/sec) + + @param strength strength given to this, defaults to MAX_STRENGTH (1.0) + + @param useSlowest if this is true (the default) everywhere + then the slowest rot vel is what will be selected + **/ + virtual void setMaxRotVelPos(double maxVel, double strength = MAX_STRENGTH, + bool useSlowest = true) + { myMaxRotVelPosDes.setDesired(maxVel, strength, useSlowest); } + + /// Sets the maximum rotational velocity (deg/sec) in the negative direction and strength + /** + This sets the maximum rotational velocity for this cycle (this is + sent down to the robot) in the negative direction. If the + setMaxRotVel is set to less than this that will be used instead. + Check the ArRobot class notes for more details. + + @param maxVel desired maximum rotational velocity in the negative + direction (deg/sec) + + @param strength strength given to this, defaults to MAX_STRENGTH (1.0) + + @param useSlowest if this is true (the default) everywhere + then the slowest rot vel is what will be selected + **/ + virtual void setMaxRotVelNeg(double maxVel, double strength = MAX_STRENGTH, + bool useSlowest = true) + { myMaxRotVelNegDes.setDesired(maxVel, strength, useSlowest); } + + /// Sets the rotational acceleration (deg/sec/sec) and strength + /** + This sets the rotational acceleration for this cycle (this is + sent down to the robot). Check the ArRobot class notes for more + details. + + @param rotAccel desired rotational acceleration (deg/sec/sec) + @param strength strength given to this, defaults to MAX_STRENGTH (1.0) + @param useSlowest if this is true (the default) everywhere + then the slowest rot accel is what will be selected + **/ + virtual void setRotAccel(double rotAccel, double strength = MAX_STRENGTH, + bool useSlowest = true) + { myRotAccelDes.setDesired(rotAccel, strength, useSlowest); } + + /// Sets the rotational deceleration (deg/sec/sec) and strength + /** + This sets the rotational deceleration for this cycle (this is + sent down to the robot). Check the ArRobot class notes for more + details. + + @param rotDecel desired rotational deceleration (deg/sec/sec) + @param strength strength given to this, defaults to MAX_STRENGTH (1.0) + @param useFastest if this is true (the default) everywhere + then the fastest rot decel is what will be selected + **/ + virtual void setRotDecel(double rotDecel, double strength = MAX_STRENGTH, + bool useFastest = true) + { myRotDecelDes.setDesired(rotDecel, strength, useFastest); } + + /// Sets the left lateral velocity (mm/sec) and strength + /** + Note that there is only one actual velocity for lat vel, but + instead of making people remember which way is left and right + there are two functions, setLeftLatVel and setRightLatVel... all + setRightLatVel does is flip the direction on the vel. You can + set a negative left lat vel and thats the same as setting a + positive right vel. You can do the same with setting a negative + right vel to get a positive left vel. + + @param latVel desired vel (mm/sec) + @param strength strength given to this, defaults to MAX_STRENGTH (1.0) + */ + virtual void setLeftLatVel(double latVel, double strength = MAX_STRENGTH) + { myLatVelDes.setDesired(latVel, strength); } + /// Sets the right lateral velocity (mm/sec) and strength + /** + Note that there is only one actual velocity for lat vel, but + instead of making people remember which way is left and right + there are two functions, setLeftLatVel and setRightLatVel... all + setRightLatVel does is flip the direction on the vel. You can + set a negative left lat vel and thats the same as setting a + positive right vel. You can do the same with setting a negative + right vel to get a positive left vel. + + @param latVel desired vel (mm/sec) + @param strength strength given to this, defaults to MAX_STRENGTH (1.0) + */ + virtual void setRightLatVel(double latVel, double strength = MAX_STRENGTH) + { myLatVelDes.setDesired(-latVel, strength); } + /// Sets the maximum lateral velocity (deg/sec) and strength + /** + This sets the maximum lateral velocity for this cycle. Check + the ArRobot class notes for more details. + + @param maxVel desired maximum lateral velocity (deg/sec) + @param strength strength given to this, defaults to MAX_STRENGTH (1.0) + @param useSlowest if this is true (the default) everywhere + then the slowest lat vel is what will be selected + **/ + virtual void setMaxLeftLatVel(double maxVel, double strength = MAX_STRENGTH, + bool useSlowest = true) + { myMaxLeftLatVelDes.setDesired(maxVel, strength, useSlowest); } + /// Sets the maximum lateral velocity (deg/sec) and strength + /** + This sets the maximum lateral velocity for this cycle. Check + the ArRobot class notes for more details. + + @param maxVel desired maximum lateral velocity (deg/sec) + @param strength strength given to this, defaults to MAX_STRENGTH (1.0) + @param useSlowest if this is true (the default) everywhere + then the slowest lat vel is what will be selected + **/ + virtual void setMaxRightLatVel(double maxVel, double strength = MAX_STRENGTH, + bool useSlowest = true) + { myMaxRightLatVelDes.setDesired(maxVel, strength, useSlowest); } + + /// Sets the lateral acceleration (deg/sec/sec) and strength + /** + This sets the lateral acceleration for this cycle (this is + sent down to the robot). Check the ArRobot class notes for more + details. + + @param latAccel desired lateral acceleration (deg/sec/sec) + @param strength strength given to this, defaults to MAX_STRENGTH (1.0) + @param useSlowest if this is true (the default) everywhere + then the slowest lat accel is what will be selected + **/ + virtual void setLatAccel(double latAccel, double strength = MAX_STRENGTH, + bool useSlowest = true) + { myLatAccelDes.setDesired(latAccel, strength, useSlowest); } + + /// Sets the lateral deceleration (deg/sec/sec) and strength + /** + This sets the lateral deceleration for this cycle (this is + sent down to the robot). Check the ArRobot class notes for more + details. + + @param latDecel desired lateral deceleration (deg/sec/sec) + @param strength strength given to this, defaults to MAX_STRENGTH (1.0) + @param useFastest if this is true (the default) everywhere + then the fastest lat decel is what will be selected + **/ + virtual void setLatDecel(double latDecel, double strength = MAX_STRENGTH, + bool useFastest = true) + { myLatDecelDes.setDesired(latDecel, strength, useFastest); } + + /// Resets the strengths to 0 + virtual void reset(void) + { + myVelDes.reset(); + myMaxVelDes.reset(); myMaxNegVelDes.reset(); + myTransAccelDes.reset(); myTransDecelDes.reset(); + + myRotVelDes.reset(); myDeltaHeadingDes.reset(); + myMaxRotVelDes.reset(); + myMaxRotVelPosDes.reset(); myMaxRotVelNegDes.reset(); + myRotAccelDes.reset(); myRotDecelDes.reset(); + myHeadingStrength = 0; + myHeadingSet = false; + + myLatVelDes.reset(); + myMaxLeftLatVelDes.reset(); myMaxRightLatVelDes.reset(); + myLatAccelDes.reset(); myLatDecelDes.reset(); + } + + /// Gets the translational velocity desired (mm/sec) + virtual double getVel(void) const + { return myVelDes.getDesired(); } + /// Gets the strength of the translational velocity desired + virtual double getVelStrength(void) const + { return myVelDes.getStrength(); } + /// Gets the heading desired (deg) + virtual double getHeading(void) const + { return myHeading; } + /// Gets the strength of the heading desired + virtual double getHeadingStrength(void) const + { return myHeadingStrength; } + /// Gets the delta heading desired (deg) + virtual double getDeltaHeading(void) const + { return myDeltaHeadingDes.getDesired(); } + /// Gets the strength of the delta heading desired + virtual double getDeltaHeadingStrength(void) const + { return myDeltaHeadingDes.getStrength(); } + /// Gets the rot vel that was set + virtual double getRotVel(void) const { return myRotVelDes.getDesired(); } + /// Gets the rot vel des (deg/sec) + virtual double getRotVelStrength(void) const + { return myRotVelDes.getStrength(); } + + /// Gets the desired maximum velocity (mm/sec) + virtual double getMaxVel(void) const + { return myMaxVelDes.getDesired(); } + /// Gets the maximum velocity strength + virtual double getMaxVelStrength(void) const + { return myMaxVelDes.getStrength(); } + /// Gets whether the slowest is being used or not + virtual double getMaxVelSlowestUsed(void) const + { return myMaxVelDes.getAllowOverride(); } + /// Gets the desired maximum negative velocity (-mm/sec) + virtual double getMaxNegVel(void) const + { return myMaxNegVelDes.getDesired(); } + /// Gets the desired maximum negative velocity strength + virtual double getMaxNegVelStrength(void) const + { return myMaxNegVelDes.getStrength(); } + /// Gets whether the slowest is being used or not + virtual double getMaxNegVelSlowestUsed(void) const + { return myMaxNegVelDes.getAllowOverride(); } + /// Gets the desired trans acceleration (mm/sec) + virtual double getTransAccel(void) const + { return myTransAccelDes.getDesired(); } + /// Gets the desired trans acceleration strength + virtual double getTransAccelStrength(void) const + { return myTransAccelDes.getStrength(); } + /// Gets whether the slowest accel is being used or not + virtual double getTransAccelSlowestUsed(void) const + { return myTransAccelDes.getAllowOverride(); } + /// Gets the desired trans deceleration (-mm/sec/sec) + virtual double getTransDecel(void) const + { return myTransDecelDes.getDesired(); } + /// Gets the desired trans deceleration strength + virtual double getTransDecelStrength(void) const + { return myTransDecelDes.getStrength(); } + /// Gets whether the fastest decel is being used or not + virtual double getTransDecelFastestUsed(void) const + { return myTransDecelDes.getAllowOverride(); } + + /// Gets the maximum rotational velocity + virtual double getMaxRotVel(void) const + { return myMaxRotVelDes.getDesired(); } + /// Gets the maximum rotational velocity strength + virtual double getMaxRotVelStrength(void) const + { return myMaxRotVelDes.getStrength(); } + /// Gets whether the slowest rot vel is being used or not + virtual double getMaxRotVelSlowestUsed(void) const + { return myMaxRotVelDes.getAllowOverride(); } + + /// Gets the maximum rotational velocity in the positive direction + virtual double getMaxRotVelPos(void) const + { return myMaxRotVelPosDes.getDesired(); } + /// Gets the maximum rotational velocity in the positive direction strength + virtual double getMaxRotVelPosStrength(void) const + { return myMaxRotVelPosDes.getStrength(); } + /// Gets whether the slowest rot vel in the positive direction is being used or not + virtual double getMaxRotVelPosSlowestUsed(void) const + { return myMaxRotVelPosDes.getAllowOverride(); } + + /// Gets the maximum rotational velocity in the negative direction + virtual double getMaxRotVelNeg(void) const + { return myMaxRotVelNegDes.getDesired(); } + /// Gets the maximum rotational velocity in the negative direction strength + virtual double getMaxRotVelNegStrength(void) const + { return myMaxRotVelNegDes.getStrength(); } + /// Gets whether the slowest rot vel in the negative direction is being used or not + virtual double getMaxRotVelNegSlowestUsed(void) const + { return myMaxRotVelNegDes.getAllowOverride(); } + + /// Gets the desired rotational acceleration (mm/sec) + virtual double getRotAccel(void) const + { return myRotAccelDes.getDesired(); } + /// Gets the desired rotational acceleration strength + virtual double getRotAccelStrength(void) const + { return myRotAccelDes.getStrength(); } + /// Gets whether the slowest rot accel is being used or not + virtual double getRotAccelSlowestUsed(void) const + { return myRotAccelDes.getAllowOverride(); } + /// Gets the desired rotational deceleration (-mm/sec/sec) + virtual double getRotDecel(void) const + { return myRotDecelDes.getDesired(); } + /// Gets the desired rotational deceleration strength + virtual double getRotDecelStrength(void) const + { return myRotDecelDes.getStrength(); } + /// Gets whether the fastest rot decel is being used or not + virtual double getRotDecelFastestUsed(void) const + { return myRotDecelDes.getAllowOverride(); } + + /// Gets the lat vel that was set + virtual double getLatVel(void) const { return myLatVelDes.getDesired(); } + /// Gets the lat vel des (deg/sec) + virtual double getLatVelStrength(void) const + { return myLatVelDes.getStrength(); } + /// Gets the maximum lateral velocity + virtual double getMaxLeftLatVel(void) const + { return myMaxLeftLatVelDes.getDesired(); } + /// Gets the maximum lateral velocity strength + virtual double getMaxLeftLatVelStrength(void) const + { return myMaxLeftLatVelDes.getStrength(); } + /// Gets whether the slowest lat vel is being used or not + virtual double getMaxLeftLatVelSlowestUsed(void) const + { return myMaxLeftLatVelDes.getAllowOverride(); } + /// Gets the maximum lateral velocity + virtual double getMaxRightLatVel(void) const + { return myMaxRightLatVelDes.getDesired(); } + /// Gets the maximum lateral velocity strength + virtual double getMaxRightLatVelStrength(void) const + { return myMaxRightLatVelDes.getStrength(); } + /// Gets whether the slowest lat vel is being used or not + virtual double getMaxRightLatVelSlowestUsed(void) const + { return myMaxRightLatVelDes.getAllowOverride(); } + /// Gets the desired lateral acceleration (mm/sec) + virtual double getLatAccel(void) const + { return myLatAccelDes.getDesired(); } + /// Gets the desired lateral acceleration strength + virtual double getLatAccelStrength(void) const + { return myLatAccelDes.getStrength(); } + /// Gets whether the slowest lat accel is being used or not + virtual double getLatAccelSlowestUsed(void) const + { return myLatAccelDes.getAllowOverride(); } + /// Gets the desired lateral deceleration (-mm/sec/sec) + virtual double getLatDecel(void) const + { return myLatDecelDes.getDesired(); } + /// Gets the desired lateral deceleration strength + virtual double getLatDecelStrength(void) const + { return myLatDecelDes.getStrength(); } + /// Gets whether the fastest lat decel is being used or not + virtual double getLatDecelFastestUsed(void) const + { return myLatDecelDes.getAllowOverride(); } + + + /// Merges the given ArActionDesired into this one (this one has precedence), + /// internal + /** + This merges in the two different action values, accountForRobotHeading + MUST be done before this is called (on both actions), since this merges + their delta headings, and the deltas can't be known unless the account + for angle is done. + @param actDesired the actionDesired to merge with this one + */ + virtual void merge(ArActionDesired *actDesired) + { + if (actDesired == NULL) + return; + myVelDes.merge(&actDesired->myVelDes); + // if we're already using rot or delt use that, otherwise use what it wants + if (myDeltaHeadingDes.getStrength() > NO_STRENGTH) + { + myDeltaHeadingDes.merge(&actDesired->myDeltaHeadingDes); + } + else if (myRotVelDes.getStrength() > NO_STRENGTH) + { + myRotVelDes.merge(&actDesired->myRotVelDes); + } + else + { + myDeltaHeadingDes.merge(&actDesired->myDeltaHeadingDes); + myRotVelDes.merge(&actDesired->myRotVelDes); + } + myMaxVelDes.merge(&actDesired->myMaxVelDes); + myMaxNegVelDes.merge(&actDesired->myMaxNegVelDes); + myMaxRotVelDes.merge(&actDesired->myMaxRotVelDes); + myMaxRotVelPosDes.merge(&actDesired->myMaxRotVelPosDes); + myMaxRotVelNegDes.merge(&actDesired->myMaxRotVelNegDes); + myTransAccelDes.merge(&actDesired->myTransAccelDes); + myTransDecelDes.merge(&actDesired->myTransDecelDes); + myRotAccelDes.merge(&actDesired->myRotAccelDes); + myRotDecelDes.merge(&actDesired->myRotDecelDes); + + myLatVelDes.merge(&actDesired->myLatVelDes); + myMaxLeftLatVelDes.merge(&actDesired->myMaxLeftLatVelDes); + myMaxRightLatVelDes.merge(&actDesired->myMaxRightLatVelDes); + myLatAccelDes.merge(&actDesired->myLatAccelDes); + myLatDecelDes.merge(&actDesired->myLatDecelDes); + } + /// Starts the process of avereraging together different desireds + /** + There is a three step process for averaging actionDesireds together, + first startAverage must be done to set up the process, then addAverage + must be done with each average that is desired, then finally endAverage + should be used, after that is done then the normal process of getting + the results out should be done. + */ + virtual void startAverage(void) + { + myVelDes.startAverage(); + myMaxVelDes.startAverage(); + myMaxNegVelDes.startAverage(); + myTransAccelDes.startAverage(); + myTransDecelDes.startAverage(); + + + myRotVelDes.startAverage(); + myDeltaHeadingDes.startAverage(); + myMaxRotVelDes.startAverage(); + myMaxRotVelPosDes.startAverage(); + myMaxRotVelNegDes.startAverage(); + myRotAccelDes.startAverage(); + myRotDecelDes.startAverage(); + + myLatVelDes.startAverage(); + myMaxLeftLatVelDes.startAverage(); + myMaxRightLatVelDes.startAverage(); + myLatAccelDes.startAverage(); + myLatDecelDes.startAverage(); + } + /// Adds another actionDesired into the mix to average + /** + For a description of how to use this, see startAverage. + @param actDesired the actionDesired to add into the average + */ + virtual void addAverage(ArActionDesired *actDesired) + { + if (actDesired == NULL) + return; + myVelDes.addAverage(&actDesired->myVelDes); + + myMaxVelDes.addAverage(&actDesired->myMaxVelDes); + myMaxNegVelDes.addAverage(&actDesired->myMaxNegVelDes); + myTransAccelDes.addAverage(&actDesired->myTransAccelDes); + myTransDecelDes.addAverage(&actDesired->myTransDecelDes); + + // if we're using one of rot or delta heading use that, + // otherwise use whatever they're using + if (myRotVelDes.getStrength() > NO_STRENGTH) + { + myRotVelDes.addAverage( + &actDesired->myRotVelDes); + } + else if (myDeltaHeadingDes.getStrength() > NO_STRENGTH) + { + myDeltaHeadingDes.addAverage( + &actDesired->myDeltaHeadingDes); + } + else + { + myRotVelDes.addAverage( + &actDesired->myRotVelDes); + myDeltaHeadingDes.addAverage( + &actDesired->myDeltaHeadingDes); + } + myMaxRotVelDes.addAverage(&actDesired->myMaxRotVelDes); + myMaxRotVelPosDes.addAverage(&actDesired->myMaxRotVelPosDes); + myMaxRotVelNegDes.addAverage(&actDesired->myMaxRotVelNegDes); + myRotAccelDes.addAverage(&actDesired->myRotAccelDes); + myRotDecelDes.addAverage(&actDesired->myRotDecelDes); + + myLatVelDes.addAverage(&actDesired->myLatVelDes); + myMaxLeftLatVelDes.addAverage(&actDesired->myMaxLeftLatVelDes); + myMaxRightLatVelDes.addAverage(&actDesired->myMaxRightLatVelDes); + myLatAccelDes.addAverage(&actDesired->myLatAccelDes); + myLatDecelDes.addAverage(&actDesired->myLatDecelDes); + } + /// Ends the process of avereraging together different desireds + /** + For a description of how to use this, see startAverage. + */ + virtual void endAverage(void) + { + myVelDes.endAverage(); + myMaxVelDes.endAverage(); + myMaxNegVelDes.endAverage(); + myTransAccelDes.endAverage(); + myTransDecelDes.endAverage(); + + myRotVelDes.endAverage(); + myDeltaHeadingDes.endAverage(); + myMaxRotVelDes.endAverage(); + myMaxRotVelPosDes.endAverage(); + myMaxRotVelNegDes.endAverage(); + myRotAccelDes.endAverage(); + myRotDecelDes.endAverage(); + + myLatVelDes.endAverage(); + myMaxLeftLatVelDes.endAverage(); + myMaxRightLatVelDes.endAverage(); + myLatAccelDes.endAverage(); + myLatDecelDes.endAverage(); + } + /// Accounts for robot heading, mostly internal + /** + This accounts for the robots heading, and transforms the set heading + on this actionDesired into a delta heading so it can be merged and + averaged and the like + @param robotHeading the heading the real actual robot is at now + */ + virtual void accountForRobotHeading(double robotHeading) + { + if (myHeadingSet) + setDeltaHeading(ArMath::subAngle(myHeading, robotHeading), + myHeadingStrength); + myHeadingSet = false; + } + /// Logs what is desired + AREXPORT virtual void log(void) const; + /// Gets whether anything is desired (should only really be used in relation to logging) + AREXPORT virtual bool isAnythingDesired(void) const; + /// Do a sanity check on the action (this is set up this way so the + /// action name can be passed in) + AREXPORT virtual void sanityCheck(const char *actionName); + +protected: + double myHeading; + double myHeadingStrength; + bool myHeadingSet; + + ArActionDesiredChannel myVelDes; + ArActionDesiredChannel myMaxVelDes; + ArActionDesiredChannel myMaxNegVelDes; + ArActionDesiredChannel myTransAccelDes; + ArActionDesiredChannel myTransDecelDes; + + ArActionDesiredChannel myRotVelDes; + ArActionDesiredChannel myDeltaHeadingDes; + ArActionDesiredChannel myMaxRotVelDes; + ArActionDesiredChannel myMaxRotVelPosDes; + ArActionDesiredChannel myMaxRotVelNegDes; + ArActionDesiredChannel myRotAccelDes; + ArActionDesiredChannel myRotDecelDes; + + ArActionDesiredChannel myLatVelDes; + ArActionDesiredChannel myMaxLeftLatVelDes; + ArActionDesiredChannel myMaxRightLatVelDes; + ArActionDesiredChannel myLatAccelDes; + ArActionDesiredChannel myLatDecelDes; +}; + + +#endif diff --git a/Legacy/Aria/include/ArActionDriveDistance.h b/Legacy/Aria/include/ArActionDriveDistance.h new file mode 100644 index 0000000..d1f6951 --- /dev/null +++ b/Legacy/Aria/include/ArActionDriveDistance.h @@ -0,0 +1,108 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARACTIONDRIVEDISTANCE_H +#define ARACTIONDRIVEDISTANCE_H + +#include "ariaTypedefs.h" +#include "ariaUtil.h" +#include "ArAction.h" + +/// This action goes to a given ArPose very naively + +/** + This action naively drives a fixed distance. The action stops the + robot when it has travelled the appropriate distance. It + travels at 'speed' mm/sec. + + You can give it a distance with setDistance(), cancel its movement + with cancelDistance(), and see if it got there with + haveAchievedDistance(). + + You can tell it to go backwards by calling setDistance with a + negative value. + + This doesn't avoid obstacles or anything, you could add have an + limiting ArAction at a higher priority to try to do this (so you + don't smash things). (For truly intelligent navigation, see + the ARNL or SONARNL software libraries.) + @ingroup ActionClasses +**/ + + +class ArActionDriveDistance : public ArAction +{ +public: + AREXPORT ArActionDriveDistance(const char *name = "driveDistance", + double speed = 400, double deceleration = 200); + AREXPORT virtual ~ArActionDriveDistance(); + + /// Sees if the goal has been achieved + AREXPORT bool haveAchievedDistance(void); + /// Cancels the goal the robot has + AREXPORT void cancelDistance(void); + /// Sets a new goal and sets the action to go there + AREXPORT void setDistance(double distance, bool useEncoders = true); + /// Gets whether we're using the encoder position or the normal position + bool usingEncoders(void) { return myUseEncoders; } + /// Sets the speed the action will travel at (mm/sec) + void setSpeed(double speed = 400) { mySpeed = speed; } + /// Gets the speed the action will travel at (mm/sec) + double getSpeed(void) { return mySpeed; } + /// Sets the deceleration the action will use (mm/sec/sec) + void setDeceleration(double deceleration = 200) + { myDeceleration = deceleration; } + /// Gets the deceleration the action will use (mm/sec/sec) + double getDeceleration(void) { return myDeceleration; } + /// Sets if we're printing or not + void setPrinting(bool printing) { myPrinting = printing; } + AREXPORT virtual ArActionDesired *fire(ArActionDesired currentDesired); + AREXPORT virtual ArActionDesired *getDesired(void) { return &myDesired; } +#ifndef SWIG + AREXPORT virtual const ArActionDesired *getDesired(void) const + { return &myDesired; } +#endif +protected: + double myDistance; + bool myUseEncoders; + double mySpeed; + double myDeceleration; + ArActionDesired myDesired; + bool myPrinting; + double myLastVel; + + double myDistTravelled; + ArPose myLastPose; + + enum State + { + STATE_NO_DISTANCE, + STATE_ACHIEVED_DISTANCE, + STATE_GOING_DISTANCE + }; + State myState; +}; + +#endif // ARACTIONDRIVE diff --git a/Legacy/Aria/include/ArActionGoto.h b/Legacy/Aria/include/ArActionGoto.h new file mode 100644 index 0000000..f70bc31 --- /dev/null +++ b/Legacy/Aria/include/ArActionGoto.h @@ -0,0 +1,122 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARACTIONGOTO_H +#define ARACTIONGOTO_H + +#include "ariaTypedefs.h" +#include "ariaUtil.h" +#include "ArAction.h" + +/// This action goes to a given ArPose very naively + +/** + This action naively drives straight towards a given ArPose. the + action stops when it gets to be a certain distance (closeDist) + from the goal pose. It travels at the given speed (mm/sec). + + You can give it a new goal with setGoal(), clear the current goal + with cancelGoal(), and see if it got there with haveAchievedGoal(). + Once the goal is reached, this action stops requesting any action. + + This doesn't avoid obstacles or anything, you could have an avoid + routine at a higher priority to avoid on the way there... but for + real and intelligent looking navigation you should use something + like ARNL, or build on these actions. + @ingroup ActionClasses +**/ + + +class ArActionGoto : public ArAction +{ +public: + AREXPORT ArActionGoto(const char *name = "goto", + ArPose goal = ArPose(0.0, 0.0, 0.0), + double closeDist = 100, double speed = 400, + double speedToTurnAt = 150, double turnAmount = 7); + AREXPORT virtual ~ArActionGoto(); + + /** Sees if the goal has been achieved. The goal is achieved when + * the robot's repordet position is within a certain distance + * (given in the constructor or in setCloseDist) from the goal pose. */ + AREXPORT bool haveAchievedGoal(void); + + /** Cancels the goal; this action will stop requesting movement. However, + * any currently requested motion (either previously requested by this + * action or by another action) will continue to be used. Use an ArActionStop + * action (activate it, or set it at a lower priority) to stop the robot. + */ + AREXPORT void cancelGoal(void); + + /// Sets a new goal and sets the action to go there + AREXPORT void setGoal(ArPose goal); + + /// Gets the goal the action has + AREXPORT ArPose getGoal(void) { return myGoal; } + + /// Set the distance which is close enough to the goal (mm); + AREXPORT void setCloseDist(double closeDist) { myCloseDist = closeDist; } + /// Gets the distance which is close enough to the goal (mm) + AREXPORT double getCloseDist(void) { return myCloseDist; } + /// Sets the speed the action will travel to the goal at (mm/sec) + AREXPORT void setSpeed(double speed) { mySpeed = speed; } + /// Gets the speed the action will travel to the goal at (mm/sec) + AREXPORT double getSpeed(void) { return mySpeed; } + + /** Called by the action resover; request movement towards goal if we + * have one. + * @param currentDesired Current desired action from the resolver + */ + AREXPORT virtual ArActionDesired *fire(ArActionDesired currentDesired); + + /** Used by the action resolvel; return current desired action. */ + AREXPORT virtual ArActionDesired *getDesired(void) { return &myDesired; } +#ifndef SWIG + AREXPORT virtual const ArActionDesired *getDesired(void) const + { return &myDesired; } +#endif +protected: + ArPose myGoal; + double myCloseDist; + double mySpeed; + double mySpeedToTurnAt; + double myDirectionToTurn; + double myCurTurnDir; + double myTurnAmount; + ArActionDesired myDesired; + bool myTurnedBack; + bool myPrinting; + ArPose myOldGoal; + + enum State + { + STATE_NO_GOAL, + STATE_ACHIEVED_GOAL, + STATE_GOING_TO_GOAL + }; + State myState; +}; + +#endif // ARACTIONGOTO diff --git a/Legacy/Aria/include/ArActionGotoStraight.h b/Legacy/Aria/include/ArActionGotoStraight.h new file mode 100644 index 0000000..adfbe4c --- /dev/null +++ b/Legacy/Aria/include/ArActionGotoStraight.h @@ -0,0 +1,127 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARACTIONGOTOSTRAIGHT_H +#define ARACTIONGOTOSTRAIGHT_H + +#include "ariaTypedefs.h" +#include "ariaUtil.h" +#include "ArAction.h" + +/// This action goes to a given ArPose very naively + +/** + This action naively drives straight towards a given ArPose. The + action stops the robot when it has travelled the distance that that + pose is away. It travels at 'speed' mm/sec. + + You can give it a new goal pose with setGoal(), cancel its movement + with cancelGoal(), and see if it got there with haveAchievedGoal(). + + For arguments to the goals and encoder goals you can tell it to go + backwards by calling them with the backwards parameter true. If + you set the justDistance to true it will only really care about + having driven the distance, if false it'll try to get to the spot + you wanted within close distance. + + This doesn't avoid obstacles or anything, you could add have an obstacle + avoidance ArAction at a higher priority to try to do this. (For + truly intelligent navigation, see the ARNL and SONARNL software libraries.) + @ingroup ActionClasses +**/ + + +class ArActionGotoStraight : public ArAction +{ +public: + AREXPORT ArActionGotoStraight(const char *name = "goto", + double speed = 400); + AREXPORT virtual ~ArActionGotoStraight(); + + /// Sees if the goal has been achieved + AREXPORT bool haveAchievedGoal(void); + /// Cancels the goal the robot has + AREXPORT void cancelGoal(void); + /// Sets a new goal and sets the action to go there + AREXPORT void setGoal(ArPose goal, bool backwards = false, + bool justDistance = true); + /// Sets the goal in a relative way + AREXPORT void setGoalRel(double dist, double deltaHeading, + bool backwards = false, bool justDistance = true); + /// Gets the goal the action has + ArPose getGoal(void) { return myGoal; } + /// Gets whether we're using the encoder goal or the normal goal + bool usingEncoderGoal(void) { return myUseEncoderGoal; } + /// Sets a new goal and sets the action to go there + AREXPORT void setEncoderGoal(ArPose encoderGoal, bool backwards = false, + bool justDistance = true); + /// Sets the goal in a relative way + AREXPORT void setEncoderGoalRel(double dist, double deltaHeading, + bool backwards = false, + bool justDistance = true); + /// Gets the goal the action has + ArPose getEncoderGoal(void) { return myEncoderGoal; } + /// Sets the speed the action will travel to the goal at (mm/sec) + void setSpeed(double speed) { mySpeed = speed; } + /// Gets the speed the action will travel to the goal at (mm/sec) + double getSpeed(void) { return mySpeed; } + /// Sets how close we have to get if we're not in just distance mode + void setCloseDist(double closeDist = 100) { myCloseDist = closeDist; } + /// Gets how close we have to get if we're not in just distance mode + double getCloseDist(void) { return myCloseDist; } + /// Sets whether we're backing up there or not (set in the setGoals) + bool getBacking(void) { return myBacking; } + AREXPORT virtual ArActionDesired *fire(ArActionDesired currentDesired); + AREXPORT virtual ArActionDesired *getDesired(void) { return &myDesired; } +#ifndef SWIG + AREXPORT virtual const ArActionDesired *getDesired(void) const + { return &myDesired; } +#endif +protected: + ArPose myGoal; + bool myUseEncoderGoal; + ArPose myEncoderGoal; + double mySpeed; + bool myBacking; + ArActionDesired myDesired; + bool myPrinting; + double myDist; + double myCloseDist; + + bool myJustDist; + + double myDistTravelled; + ArPose myLastPose; + + enum State + { + STATE_NO_GOAL, + STATE_ACHIEVED_GOAL, + STATE_GOING_TO_GOAL + }; + State myState; +}; + +#endif // ARACTIONGOTO diff --git a/Legacy/Aria/include/ArActionGroup.h b/Legacy/Aria/include/ArActionGroup.h new file mode 100644 index 0000000..0cd95dd --- /dev/null +++ b/Legacy/Aria/include/ArActionGroup.h @@ -0,0 +1,77 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARACTIONGROUP_H +#define ARACTIONGROUP_H + +#include "ariaTypedefs.h" + +#include + +class ArRobot; +class ArAction; + +/// Group a set of ArAction objects together +/** + This class is used to collect a group of related ArActions together, + and easily turn them on and off in aggregate. The group list may also + be retrieved for performing any other operation you wish (e.g. to delete + or get information about them.) + + @see @ref actions overview + @see ArAction + @see @ref actionGroupExample.cpp + @ingroup OptionalClasses + @ingroup ActionClasses +**/ +class ArActionGroup +{ +public: + /// Constructor + AREXPORT ArActionGroup(ArRobot * robot); + /// Destructor, it also deletes the actions in its group + AREXPORT virtual ~ArActionGroup(); + /// Adds an action to this group's robot, and associates the action with this group. + AREXPORT virtual void addAction(ArAction *action, int priority); + /// Removes the action from this group's robot and dissasociates it from this group. + AREXPORT virtual void remAction(ArAction *action); + /// Activates all the actions in this group + AREXPORT virtual void activate(void); + /// Activates all the actions in this group and deactivates all others + AREXPORT virtual void activateExclusive(void); + /// Deactivates all the actions in this group + AREXPORT virtual void deactivate(void); + /// Removes all the actions in this group from the robot + AREXPORT virtual void removeActions(void); + /// Delets all the actions in this group (doesn't delete them right now) + AREXPORT virtual void deleteActions(void); + /// Gets the action list (use this to delete actions after doing removeActions) + AREXPORT virtual std::list *getActionList(void); +protected: + std::list myActions; + ArRobot *myRobot; +}; + +#endif // ARACTIONGROUP_H diff --git a/Legacy/Aria/include/ArActionGroups.h b/Legacy/Aria/include/ArActionGroups.h new file mode 100644 index 0000000..6a72393 --- /dev/null +++ b/Legacy/Aria/include/ArActionGroups.h @@ -0,0 +1,209 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARACTIONGROUPS_H +#define ARACTIONGROUPS_H + +#include "ariaTypedefs.h" +#include "ArActionGroup.h" +#include "ArActionColorFollow.h" +#include "ArACTS.h" +#include "ArPTZ.h" + +class ArActionStop; +class ArActionInput; +class ArActionJoydrive; +class ArActionDeceleratingLimiter; +class ArActionRatioInput; +class ArRatioInputKeydrive; +class ArRatioInputJoydrive; +class ArRatioInputRobotJoydrive; + +/// Action group to use to drive the robot with input actions (keyboard, joystick, etc.) +/** + This class is just useful for teleoping the robot under your own + joystick and keyboard control... Note that you the predefined + ArActionGroups in ARIA are made only to be used exclusively... only + one can be active at once. + + This class is largely now obsolete (it is used by ArServerModeDrive + but that is now obsolete and was replaced by a class that just + makes its own action group) + + ArActionGroupRatioDrive is better. +**/ +class ArActionGroupInput : public ArActionGroup +{ +public: + AREXPORT ArActionGroupInput(ArRobot *robot); + AREXPORT virtual ~ArActionGroupInput(); + AREXPORT void setVel(double vel); + AREXPORT void setRotVel(double rotVel); + AREXPORT void setHeading(double heading); + AREXPORT void deltaHeadingFromCurrent(double delta); + AREXPORT void clear(void); + AREXPORT ArActionInput *getActionInput(void); +protected: + ArActionInput *myInput; +}; + +/// Action group to stop the robot +/** + This class is just useful for having the robot stopped... Note that + you the predefined ArActionGroups in ARIA are made only to be used + exclusively... they won't combine. +**/ +class ArActionGroupStop : public ArActionGroup +{ +public: + AREXPORT ArActionGroupStop(ArRobot *robot); + AREXPORT virtual ~ArActionGroupStop(); + AREXPORT ArActionStop *getActionStop(void); +public: + ArActionStop *myActionStop; +}; + +/// Action group to teleopoperate the robot using ArActionJoydrive, and the Limiter actions to avoid collisions. +/** + This class is just useful for teleoping the robot and having these + actions read the joystick and keyboard... Note that you the + predefined ArActionGroups in ARIA are made only to be used + exclusively... only one can be active at once. +**/ +class ArActionGroupTeleop : public ArActionGroup +{ +public: + AREXPORT ArActionGroupTeleop(ArRobot *robot); + AREXPORT virtual ~ArActionGroupTeleop(); + AREXPORT void setThrottleParams(int lowSpeed, int highSpeed); +protected: + ArActionJoydrive *myJoydrive; +}; + +/// Action group to teleoperate the robot using ArActionJoydrive, but without any Limiter actions to avoid collisions. +/** + This class is just useful for teleoping the robot in an unguarded + and unsafe manner and having these actions read the joystick and + keyboard... Note that you the predefined ArActionGroups in ARIA are + made only to be used exclusively... only one can be active at once. +**/ +class ArActionGroupUnguardedTeleop : public ArActionGroup +{ +public: + AREXPORT ArActionGroupUnguardedTeleop(ArRobot *robot); + AREXPORT virtual ~ArActionGroupUnguardedTeleop(); + AREXPORT void setThrottleParams(int lowSpeed, int highSpeed); +protected: + ArActionJoydrive *myJoydrive; +}; + +/// Action group to make the robot wander, avoiding obstacles. +/** + This class is useful for having the robot wander... Note that + you the predefined ArActionGroups in ARIA are made only to be used + exclusively... only one can be active at once. +**/ +class ArActionGroupWander : public ArActionGroup +{ +public: + AREXPORT ArActionGroupWander(ArRobot *robot, int forwardVel = 400, int avoidFrontDist = 450, int avoidVel = 200, int avoidTurnAmt = 15); + AREXPORT virtual ~ArActionGroupWander(); +}; + +/// Follows a blob of color +/** + This class has the robot follow a blob of color... Note that you the + predefined ArActionGroups in ARIA are made only to be used + exclusively... only one can be active at once. +**/ + +class ArActionGroupColorFollow : public ArActionGroup +{ +public: + AREXPORT ArActionGroupColorFollow(ArRobot *robot, ArACTS_1_2 *acts, ArPTZ *camera); + AREXPORT virtual ~ArActionGroupColorFollow(); + AREXPORT void setCamera(ArPTZ *camera); + AREXPORT void setChannel(int channel); + AREXPORT void startMovement(); + AREXPORT void stopMovement(); + AREXPORT void setAcquire(bool acquire); + AREXPORT int getChannel(); + AREXPORT bool getAcquire(); + AREXPORT bool getMovement(); + AREXPORT bool getBlob(); +protected: + ArActionColorFollow *myColorFollow; +}; + +/// Use keyboard and joystick input to to drive the robot, with Limiter actions to avoid obstacles. +/** + This class is just useful for teleoping the robot under your own + joystick and keyboard control... Note that you the predefined + ArActionGroups in ARIA are made only to be used exclusively (one at + a time)... only one can be active at once. +**/ +class ArActionGroupRatioDrive : public ArActionGroup +{ +public: + AREXPORT ArActionGroupRatioDrive(ArRobot *robot); + AREXPORT virtual ~ArActionGroupRatioDrive(); + AREXPORT ArActionRatioInput *getActionRatioInput(void); + AREXPORT void addToConfig(ArConfig *config, const char *section); +protected: + ArActionDeceleratingLimiter *myDeceleratingLimiterForward; + ArActionDeceleratingLimiter *myDeceleratingLimiterBackward; + ArActionDeceleratingLimiter *myDeceleratingLimiterLateralLeft; + ArActionDeceleratingLimiter *myDeceleratingLimiterLateralRight; + ArActionRatioInput *myInput; + ArRatioInputKeydrive *myKeydrive; + ArRatioInputJoydrive *myJoydrive; + ArRatioInputRobotJoydrive *myRobotJoydrive; + +}; + + +/// Use keyboard and joystick input to to drive the robot, but without Limiter actions to avoid obstacles. +/** + This class is just useful for teleoping the robot under your own + joystick and keyboard control... Note that you the predefined + ArActionGroups in ARIA are made only to be used exclusively (one at + a time)... only one can be active at once. +**/ +class ArActionGroupRatioDriveUnsafe : public ArActionGroup +{ +public: + AREXPORT ArActionGroupRatioDriveUnsafe(ArRobot *robot); + AREXPORT virtual ~ArActionGroupRatioDriveUnsafe(); + AREXPORT ArActionRatioInput *getActionRatioInput(void); + AREXPORT void addToConfig(ArConfig *config, const char *section); +protected: + ArActionRatioInput *myInput; + ArRatioInputKeydrive *myKeydrive; + ArRatioInputJoydrive *myJoydrive; + ArRatioInputRobotJoydrive *myRobotJoydrive; + +}; + +#endif // ARACTIONGROUPS_H diff --git a/Legacy/Aria/include/ArActionIRs.h b/Legacy/Aria/include/ArActionIRs.h new file mode 100644 index 0000000..d5d6f1f --- /dev/null +++ b/Legacy/Aria/include/ArActionIRs.h @@ -0,0 +1,77 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARACTIONIRS_H +#define ARACTIONIRS_H + +#include "ariaTypedefs.h" +#include "ArAction.h" +#include "ArRobotParams.h" +#include + +/// Action to back up if short-range IR sensors trigger +/** + * If the robot has front-mounted binary (triggered/not triggered) IR sensors, + * this action will respond to a sensor trigger by backing up and perhaps + * turning, similar to bumpers. This action assumes that if an IR triggers, the + * robot caused it by moving forward into or under an obstacle, and backing up + * is a good reaction. + +* @ingroup ActionClasses + */ + +class ArActionIRs : public ArAction +{ +public: + /// Constructor + AREXPORT ArActionIRs(const char *name = "IRs", + double backOffSpeed = 100, int backOffTime = 5000, + int turnTime = 3000, bool setMaximums = false); + /// Destructor + AREXPORT virtual ~ArActionIRs(); + AREXPORT virtual ArActionDesired *fire(ArActionDesired currentDesired); + AREXPORT virtual void setRobot(ArRobot *robot); + AREXPORT virtual ArActionDesired *getDesired(void) { return &myDesired; } +#ifndef SWIG + AREXPORT virtual const ArActionDesired *getDesired(void) const + { return &myDesired; } +#endif +protected: + ArActionDesired myDesired; + bool mySetMaximums; + double myBackOffSpeed; + int myBackOffTime; + int myTurnTime; + int myStopTime; + bool myFiring; + double mySpeed; + double myHeading; + ArTime myStartBack; + ArTime stoppedSince; + ArRobotParams myParams; + std::vector cycleCounters; +}; + +#endif // ARACTIONIRS diff --git a/Legacy/Aria/include/ArActionInput.h b/Legacy/Aria/include/ArActionInput.h new file mode 100644 index 0000000..1f23034 --- /dev/null +++ b/Legacy/Aria/include/ArActionInput.h @@ -0,0 +1,69 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARACTIONINPUT_H +#define ARACTIONINPUT_H + +#include "ariaTypedefs.h" +#include "ArAction.h" + +/// Action for taking input from outside to control the robot +/** + This action sets up how we want to drive + @ingroup ActionClasses +*/ +class ArActionInput : public ArAction +{ +public: + /// Constructor + AREXPORT ArActionInput(const char *name = "Input"); + /// Destructor + AREXPORT virtual ~ArActionInput(); + /// Set velocity (cancels deltaVel) + AREXPORT void setVel(double vel); + /// Increment/decrement the heading from current + AREXPORT void deltaHeadingFromCurrent(double delta); + /// Sets a rotational velocity + AREXPORT void setRotVel(double rotVel); + /// Sets a heading + AREXPORT void setHeading(double heading); + /// Clears it so its not using vel or heading + AREXPORT void clear(void); + AREXPORT virtual ArActionDesired *fire(ArActionDesired currentDesired); + AREXPORT virtual ArActionDesired *getDesired(void) { return &myDesired; } +#ifndef SWIG + AREXPORT virtual const ArActionDesired *getDesired(void) const + { return &myDesired; } +#endif +protected: + enum RotRegime { NONE, ROTVEL, DELTAHEADING, SETHEADING }; + RotRegime myRotRegime; + double myRotVal; + bool myUsingVel; + double myVelSet; + ArActionDesired myDesired; +}; + +#endif // ARACTIONSTOP_H diff --git a/Legacy/Aria/include/ArActionJoydrive.h b/Legacy/Aria/include/ArActionJoydrive.h new file mode 100644 index 0000000..dffb234 --- /dev/null +++ b/Legacy/Aria/include/ArActionJoydrive.h @@ -0,0 +1,102 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARACTIONJOYDRIVE_H +#define ARACTIONJOYDRIVE_H + +#include "ariaTypedefs.h" +#include "ArAction.h" +#include "ArJoyHandler.h" + +/// This action will use the joystick for input to drive the robot +/** + This class creates its own ArJoyHandler to get input from the + joystick. Then it will scale the speed between 0 and the given max + for velocity and turning, up and down on the joystick go + forwards/backwards while right and left go right and left. You + must press in one of the two joystick buttons for the class to pay + attention to the joystick. + + @note The joystick does not save calibration information, so you + must calibrate the joystick before each time you use it. To do + this, press the button for at least a half a second while the + joystick is in the middle. Then let go of the button and hold the + joystick in the upper left for at least a half second and then in + the lower right corner for at least a half second. + + @ingroup ActionClasses +**/ +class ArActionJoydrive : public ArAction +{ +public: + /// Constructor + AREXPORT ArActionJoydrive(const char * name = "joydrive", + double transVelMax = 400, + double turnAmountMax = 15, + bool stopIfNoButtonPressed = true, + bool useOSCalForJoystick = true); + /// Destructor + AREXPORT virtual ~ArActionJoydrive(); + AREXPORT virtual ArActionDesired *fire(ArActionDesired currentDesired); + /// Whether the joystick is initalized or not + AREXPORT bool joystickInited(void); + /// Set Speeds + AREXPORT void setSpeeds(double transVelMax, double turnAmountMax); + /// Set if we'll stop if no button is pressed, otherwise just do nothing + AREXPORT void setStopIfNoButtonPressed(bool stopIfNoButtonPressed); + /// Get if we'll stop if no button is pressed, otherwise just do nothing + AREXPORT bool getStopIfNoButtonPressed(void); + /// Sets the params on the throttle (throttle unused unless you call this) + AREXPORT void setThrottleParams(double lowSpeed, double highSpeed); + /// Sets whether to use OSCalibration the joystick or not + AREXPORT void setUseOSCal(bool useOSCal); + /// Gets whether OSCalibration is being used for the joystick or not + AREXPORT bool getUseOSCal(void); + /// Gets the joyHandler + AREXPORT ArJoyHandler *getJoyHandler(void) { return myJoyHandler; } + AREXPORT virtual ArActionDesired *getDesired(void) { return &myDesired; } +#ifndef SWIG + AREXPORT virtual const ArActionDesired *getDesired(void) const { return &myDesired; } +#endif +protected: + bool myUseThrottle; + double myLowThrottle; + double myHighThrottle; + // action desired + ArActionDesired myDesired; + // joystick handler + ArJoyHandler *myJoyHandler; + // full spped + double myTransVelMax; + // full amount to turn + double myTurnAmountMax; + // if we want to stop when no button is presesd + bool myStopIfNoButtonPressed; + // if we're using os cal for the joystick + bool myUseOSCal; + bool myPreviousUseOSCal; +}; + +#endif //ARACTIONJOYDRIVE_H diff --git a/Legacy/Aria/include/ArActionKeydrive.h b/Legacy/Aria/include/ArActionKeydrive.h new file mode 100644 index 0000000..dbc9900 --- /dev/null +++ b/Legacy/Aria/include/ArActionKeydrive.h @@ -0,0 +1,103 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARACTIONKEYDRIVE_H +#define ARACTIONKEYDRIVE_H + +#include "ariaTypedefs.h" +#include "ArAction.h" +#include "ArFunctor.h" + +class ArRobot; + +/// This action will use the keyboard arrow keys for input to drive the robot +/// @ingroup ActionClasses +class ArActionKeydrive : public ArAction +{ +public: + /// Constructor + AREXPORT ArActionKeydrive(const char *name = "keydrive", + double transVelMax = 400, + double turnAmountMax = 24, + double velIncrement = 25, + double turnIncrement = 8); + /// Destructor + AREXPORT virtual ~ArActionKeydrive(); + AREXPORT virtual ArActionDesired *fire(ArActionDesired currentDesired); + /// For setting the maximum speeds + AREXPORT void setSpeeds(double transVelMax, double turnAmountMax); + /// For setting the increment amounts + AREXPORT void setIncrements(double velIncrement, double turnIncrement); + AREXPORT virtual ArActionDesired *getDesired(void) { return &myDesired; } +#ifndef SWIG + AREXPORT virtual const ArActionDesired *getDesired(void) const + { return &myDesired; } +#endif + AREXPORT virtual void setRobot(ArRobot *robot); + AREXPORT virtual void activate(void); + AREXPORT virtual void deactivate(void); + /// Takes the keys this action wants to use to drive + AREXPORT void takeKeys(void); + /// Gives up the keys this action wants to use to drive + AREXPORT void giveUpKeys(void); + /// Internal, callback for up arrow + AREXPORT void up(void); + /// Internal, callback for down arrow + AREXPORT void down(void); + /// Internal, callback for left arrow + AREXPORT void left(void); + /// Internal, callback for right arrow + AREXPORT void right(void); + /// Internal, callback for space key + AREXPORT void space(void); + +protected: + ArFunctorC myUpCB; + ArFunctorC myDownCB; + ArFunctorC myLeftCB; + ArFunctorC myRightCB; + ArFunctorC mySpaceCB; + // action desired + ArActionDesired myDesired; + // full speed + double myTransVelMax; + // full amount to turn + double myTurnAmountMax; + // amount to increment vel by on an up arrow or decrement on a down arrow + double myVelIncrement; + // amount to increment turn by on a left arrow or right arrow + double myTurnIncrement; + // amount we want to speed up + double myDeltaVel; + // amount we want to turn + double myTurnAmount; + // what speed we want to go + double myDesiredSpeed; + // if our speeds been reset + bool mySpeedReset; +}; + + +#endif // ARACTIONKEYDRIVE_H diff --git a/Legacy/Aria/include/ArActionLimiterBackwards.h b/Legacy/Aria/include/ArActionLimiterBackwards.h new file mode 100644 index 0000000..c4daf74 --- /dev/null +++ b/Legacy/Aria/include/ArActionLimiterBackwards.h @@ -0,0 +1,68 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARACTIONBACKWARDSSPEEDLIMITER_H +#define ARACTIONBACKWARDSSPEEDLIMITER_H + +#include "ariaTypedefs.h" +#include "ArAction.h" + +/// Action to limit the backwards motion of the robot based on range sensor readings +/** + This class limits the backwards motion of the robot according to range sensor + readings (e.g. sonar, laser), and the parameters given. When the range + sensor (e.g. sonar or laser) detects rearward obstacles closer than the given parameters, + this action requests that the robot decelerate or stop any current backwards movement. + @ingroup ActionClasses +*/ +class ArActionLimiterBackwards : public ArAction +{ +public: + /// Constructor + AREXPORT ArActionLimiterBackwards(const char *name = "speed limiter", + double stopDistance = -250, + double slowDistance = -600, + double maxBackwardsSpeed = -250, + double widthRatio = 1.5, + bool avoidLocationDependentObstacles = true); + /// Destructor + AREXPORT virtual ~ArActionLimiterBackwards(); + AREXPORT virtual ArActionDesired *fire(ArActionDesired currentDesired); + AREXPORT virtual ArActionDesired *getDesired(void) { return &myDesired; } +#ifndef SWIG + AREXPORT virtual const ArActionDesired *getDesired(void) const + { return &myDesired; } +#endif +protected: + double myStopDist; + double mySlowDist; + double myMaxBackwardsSpeed; + double myWidthRatio; + bool myAvoidLocationDependentObstacles; + ArActionDesired myDesired; +}; + +#endif // ARACTIONBACKWARDSSPEEDLIMITER_H + diff --git a/Legacy/Aria/include/ArActionLimiterForwards.h b/Legacy/Aria/include/ArActionLimiterForwards.h new file mode 100644 index 0000000..0e98e39 --- /dev/null +++ b/Legacy/Aria/include/ArActionLimiterForwards.h @@ -0,0 +1,69 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARACTIONSPEEDLIMITER_H +#define ARACTIONSPEEDLIMITER_H + +#include "ariaTypedefs.h" +#include "ArAction.h" + +/// Action to limit the forwards motion of the robot based on range sensor readings. +/** + This action uses the sensors to find a maximum forwared speed to travel at; when the range + sensor (e.g. sonar or laser) detects obstacles closer than the given parameters, + this action requests that the robot decelerate or stop. + @ingroup ActionClasses +*/ +class ArActionLimiterForwards : public ArAction +{ +public: + /// Constructor + AREXPORT ArActionLimiterForwards(const char *name = "speed limiter", + double stopDistance = 250, + double slowDistance = 1000, + double slowSpeed = 200, + double widthRatio = 1); + /// Destructor + AREXPORT virtual ~ArActionLimiterForwards(); + AREXPORT virtual ArActionDesired *fire(ArActionDesired currentDesired); + AREXPORT virtual ArActionDesired *getDesired(void) { return &myDesired; } +#ifndef SWIG + AREXPORT virtual const ArActionDesired *getDesired(void) const + { return &myDesired; } +#endif + AREXPORT void setParameters(double stopDistance = 250, + double slowDistance = 1000, + double slowSpeed = 200, + double widthRatio = 1); +protected: + bool myLastStopped; + double myStopDist; + double mySlowDist; + double mySlowSpeed; + double myWidthRatio; + ArActionDesired myDesired; +}; + +#endif // ARACTIONSPEEDLIMITER_H diff --git a/Legacy/Aria/include/ArActionLimiterRot.h b/Legacy/Aria/include/ArActionLimiterRot.h new file mode 100644 index 0000000..9c37b6c --- /dev/null +++ b/Legacy/Aria/include/ArActionLimiterRot.h @@ -0,0 +1,79 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARACTIONLIMITERROT_H +#define ARACTIONLIMITERROT_H + +#include "ariaTypedefs.h" +#include "ArAction.h" + +/// Action to limit the forwards motion of the robot based on range sensor readings +/** + This action uses the robot's range sensors (e.g. sonar, laser) to find a + maximum speed at which to travel + and will increase the deceleration so that the robot doesn't hit + anything. If it has to, it will trigger an estop to avoid a + collision. + + Note that this cranks up the deceleration with a strong strength, + but it checks to see if there is already something decelerating + more strongly... so you can put these actions lower in the priority list so + things will play together nicely. + + @ingroup ActionClasses +**/ +class ArActionLimiterRot : public ArAction +{ +public: + /// Constructor + AREXPORT ArActionLimiterRot(const char *name = "limitRot"); + /// Destructor + AREXPORT virtual ~ArActionLimiterRot(); + AREXPORT virtual ArActionDesired *fire(ArActionDesired currentDesired); + AREXPORT virtual ArActionDesired *getDesired(void) { return &myDesired; } +#ifndef SWIG + AREXPORT virtual const ArActionDesired *getDesired(void) const + { return &myDesired; } +#endif + /// Sets the parameters (don't use this if you're using the addToConfig) + AREXPORT void setParameters(bool checkRadius = false, + double inRadiusSpeed = 0); + /// Adds to the ArConfig given, in section, with prefix + AREXPORT void addToConfig(ArConfig *config, const char *section, + const char *prefix = NULL); + /// Sets if we're using locationDependent range devices or not + bool getUseLocationDependentDevices(void) + { return myUseLocationDependentDevices; } + /// Sets if we're using locationDependent range devices or not + void setUseLocationDependentDevices(bool useLocationDependentDevices) + { myUseLocationDependentDevices = useLocationDependentDevices; } +protected: + bool myCheckRadius; + double myInRadiusSpeed; + bool myUseLocationDependentDevices; + ArActionDesired myDesired; +}; + +#endif // ARACTIONSPEEDLIMITER_H diff --git a/Legacy/Aria/include/ArActionLimiterTableSensor.h b/Legacy/Aria/include/ArActionLimiterTableSensor.h new file mode 100644 index 0000000..5963b3b --- /dev/null +++ b/Legacy/Aria/include/ArActionLimiterTableSensor.h @@ -0,0 +1,59 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARACTIONLIMITERTABLESNSOR_H +#define ARACTIONLIMITERTABLESNSOR_H + +#include "ariaTypedefs.h" +#include "ArAction.h" + +/// Action to limit speed (and stop) based on whether the "table"-sensors see anything +/** + This action limits speed to 0 if the table-sensors see anything in front + of the robot. The action will only work if the robot has table sensors, + meaning that the robots parameter file has them listed as true. + + @ingroup ActionClasses +*/ +class ArActionLimiterTableSensor : public ArAction +{ +public: + /// Constructor + AREXPORT ArActionLimiterTableSensor(const char *name = "TableSensorLimiter"); + /// Destructor + AREXPORT virtual ~ArActionLimiterTableSensor(); + AREXPORT virtual ArActionDesired *fire(ArActionDesired currentDesired); + AREXPORT virtual ArActionDesired *getDesired(void) { return &myDesired; } +#ifndef SWIG + AREXPORT virtual const ArActionDesired *getDesired(void) const + { return &myDesired; } +#endif +protected: + ArActionDesired myDesired; +}; + + + +#endif // ARACTIONLIMITERTABLESNSOR_H diff --git a/Legacy/Aria/include/ArActionMovementParameters.h b/Legacy/Aria/include/ArActionMovementParameters.h new file mode 100644 index 0000000..ecc9275 --- /dev/null +++ b/Legacy/Aria/include/ArActionMovementParameters.h @@ -0,0 +1,92 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARACTIONMOVEMENTPARAMTERS_H +#define ARACTIONMOVEMENTPARAMTERS_H + +#include "ariaTypedefs.h" +#include "ArAction.h" +#include "ArMapObject.h" + +/// This is a class for setting max velocities and accels and decels via ArConfig parameters (see addToConfig()) or manually (using setParameters()) +/** + @ingroup ActionClasses + **/ +class ArActionMovementParameters : public ArAction +{ +public: + /// Constructor + AREXPORT ArActionMovementParameters(const char *name = "MovementParameters", + bool overrideFaster = true, + bool addLatVelIfAvailable = true); + /// Destructor + AREXPORT virtual ~ArActionMovementParameters(); + AREXPORT virtual ArActionDesired *fire(ArActionDesired currentDesired); + AREXPORT virtual ArActionDesired *getDesired(void) { return &myDesired; } +#ifndef SWIG + AREXPORT virtual const ArActionDesired *getDesired(void) const + { return &myDesired; } +#endif + /// Sees if this action is enabled (separate from activating it) + AREXPORT bool isEnabled(void) { return myEnabled; } + /// Enables this action (separate from activating it) + AREXPORT void enable(void) { myEnabled = true; } + /// Enables this action in a way that'll work from the sector callbacks + AREXPORT void enableOnceFromSector(ArMapObject *mapObject) + { myEnableOnce = true; } + /// Disables this action (separate from deactivating it) + AREXPORT void disable(void) { myEnabled = false; } + /// Sets the parameters (don't use this if you're using the addToConfig) + AREXPORT void setParameters(double maxVel = 0, double maxNegVel = 0, + double transAccel = 0, double transDecel = 0, + double rotVelMax = 0, double rotAccel = 0, + double rotDecel = 0, double latVelMax = 0, + double latAccel = 0, double latDecel = 0); + /// Adds to the ArConfig given, in section, with prefix + AREXPORT void addToConfig(ArConfig *config, const char *section, + const char *prefix = NULL); +protected: + bool myEnabled; + bool myEnableOnce; + bool myOverrideFaster; + bool myAddLatVelIfAvailable; + + double myMaxVel; + double myMaxNegVel; + double myTransAccel; + double myTransDecel; + double myMaxRotVel; + double myRotAccel; + double myRotDecel; + double myMaxLatVel; + double myLatAccel; + double myLatDecel; + + ArActionDesired myDesired; + + +}; + +#endif // ARACTIONMOVEMENTPARAMTERS_H diff --git a/Legacy/Aria/include/ArActionMovementParametersDebugging.h b/Legacy/Aria/include/ArActionMovementParametersDebugging.h new file mode 100644 index 0000000..67977be --- /dev/null +++ b/Legacy/Aria/include/ArActionMovementParametersDebugging.h @@ -0,0 +1,94 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARACTIONMOVEMENTPARAMTERSDEBUGGING_H +#define ARACTIONMOVEMENTPARAMTERSDEBUGGING_H + +#include "ariaTypedefs.h" +#include "ArAction.h" +#include "ArMapObject.h" + +/// This is a class for setting max velocities and accels and decels via ArConfig parameters (see addToConfig()); +/** + @ingroup ActionClasses + **/ +class ArActionMovementParametersDebugging : public ArAction +{ +public: + /// Constructor + AREXPORT ArActionMovementParametersDebugging(const char *name = "MovementParametersDebugging"); + /// Destructor + AREXPORT virtual ~ArActionMovementParametersDebugging(); + AREXPORT virtual ArActionDesired *fire(ArActionDesired currentDesired); + AREXPORT virtual ArActionDesired *getDesired(void) { return &myDesired; } +#ifndef SWIG + AREXPORT virtual const ArActionDesired *getDesired(void) const + { return &myDesired; } +#endif + /// Sees if this action is enabled (separate from activating it) + AREXPORT bool isEnabled(void) { return myEnabled; } + /// Enables this action (separate from activating it) + AREXPORT void enable(void) { myEnabled = true; } + /// Enables this action in a way that'll work from the sector callbacks + AREXPORT void enableOnceFromSector(ArMapObject *mapObject) + { myEnableOnce = true; } + /// Disables this action (separate from deactivating it) + AREXPORT void disable(void) { myEnabled = false; } + /// Adds to the ArConfig given, in section, with prefix + AREXPORT void addToConfig(ArConfig *config, const char *section, + const char *prefix = NULL); +protected: + bool myEnabled; + bool myEnableOnce; + + bool mySetMaxVel; + double myMaxVel; + bool mySetMaxNegVel; + double myMaxNegVel; + bool mySetTransAccel; + double myTransAccel; + bool mySetTransDecel; + double myTransDecel; + bool mySetMaxRotVel; + double myMaxRotVel; + bool mySetRotAccel; + double myRotAccel; + bool mySetRotDecel; + double myRotDecel; + bool mySetMaxLeftLatVel; + double myMaxLeftLatVel; + bool mySetMaxRightLatVel; + double myMaxRightLatVel; + bool mySetLatAccel; + double myLatAccel; + bool mySetLatDecel; + double myLatDecel; + + ArActionDesired myDesired; + + +}; + +#endif // ARACTIONMOVEMENTPARAMTERS_H diff --git a/Legacy/Aria/include/ArActionRatioInput.h b/Legacy/Aria/include/ArActionRatioInput.h new file mode 100644 index 0000000..d18e40e --- /dev/null +++ b/Legacy/Aria/include/ArActionRatioInput.h @@ -0,0 +1,142 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARACTIONRATIOINPUT_H +#define ARACTIONRATIOINPUT_H + +#include "ariaTypedefs.h" +#include "ArAction.h" + +/// Action that requests motion based on abstract ratios provided by diferent input sources +/** + This action interprets input drive commands as three abstract ratios, + translation, rotation, and throttle. (In this way it mimics many joysticks.) + The translation speed input ranges from -100 to 100, where -100 requests maximum + backwards speed, and 100 requests maximum forward speed, 0 requests no + translational speed, and values in between request a linear percentage of the maximum. + Similarly, rotation speed input ranges from -100 to 100, + where -100 indicates maximum rightwards or clockwise rotation, 100 indicates + maximum leftwards or counter-clockwise rotation, 0 requests no rotation, and + values in between request a linear percentage of the maximum. The throttle + input scales the other speed, and ranges from 0 (no motion) to 100 (maximum motion). + + Seperate objects (e.g. ArRatioInputKeydrive, ArRatioInputJoydrive, ArRAtionInputRobotJoydrive) + are used to provide input. + + When this action is activated it resets all its input ratios to 0 + (including throttle). + + Configuration parameters are used to map the maximum ratios to actual robot speeds. + These are set be default to the robot's maximum configured velocities at startup but you can + override them with ArConfig parameters (and call addToConfig()) or setParameters(). + + @ingroup ActionClasses + + @see ArRatioInputKeydrive + @see ArRatioInputJoydrive + @see ArRatioInputRobotJoydrive + **/ +class ArActionRatioInput : public ArAction +{ +public: + /// Constructor + AREXPORT ArActionRatioInput(const char *name = "RatioInput"); + /// Destructor + AREXPORT virtual ~ArActionRatioInput(); + /// Set ratios + AREXPORT void setRatios(double transRatio, double rotRatio, + double throttleRatio, double latRatio = 0); + /// Sets the trans ratio (from -100 (full backwards) to 100 (full forwards) + AREXPORT void setTransRatio(double transRatio); + /// Sets the rot ratio (from -100 (full right) to 100 (full left) + AREXPORT void setRotRatio(double rotRatio); + /// Sets the lat ratio (from -100 (one way) to 100 (the other)) + AREXPORT void setLatRatio(double latRatio); + /// Sets the throttle ratio (from 0 (stopped) to 100 (full throttle) + AREXPORT void setThrottleRatio(double throttleRatio); + /// Gets the trans ratio (from -100 (full backwards) to 100 (full forwards) + double getTransRatio(void) { return myTransRatio; } + /// Gets the rot ratio (from -100 (full right) to 100 (full left) + double getRotRatio(void) { return myRotRatio; } + /// Gets the throttle ratio (from 0 (stopped) to 100 (full throttle) + double getThrottleRatio(void) { return myThrottleRatio; } + /// Adds a callback that is called from this actions fire call + AREXPORT void addFireCallback(int priority, ArFunctor *functor); + /// Removes a callback that was called from this actions fire callback + AREXPORT void remFireCallback(ArFunctor *functor); + /// Adds a callback that is called when this action is activated + AREXPORT void addActivateCallback(ArFunctor *functor, + ArListPos::Pos position = ArListPos::LAST); + /// Removes a callback that was called when this action is activated + AREXPORT void remActivateCallback(ArFunctor *functor); + /// Adds a callback that is called when this action is deactivated + AREXPORT void addDeactivateCallback(ArFunctor *functor, + ArListPos::Pos position = ArListPos::LAST); + /// Removes a callback that was called when this action is deactivated + AREXPORT void remDeactivateCallback(ArFunctor *functor); + /// Sets the parameters + AREXPORT void setParameters(double fullThrottleForwards, + double fullThrottleBackwards, + double rotAtFullForwards, + double rotAtFullBackwards, + double rotAtStopped, + double latAtFullForwards = 0, + double latAtFullBackwards = 0, + double latAtStopped = 0); + /// Adds to a section in a config + AREXPORT void addToConfig(ArConfig *config, const char *section); + AREXPORT virtual ArActionDesired *fire(ArActionDesired currentDesired); + AREXPORT virtual ArActionDesired *getDesired(void) { return &myDesired; } +#ifndef SWIG + AREXPORT virtual const ArActionDesired *getDesired(void) const + { return &myDesired; } +#endif + AREXPORT virtual void activate(void); + AREXPORT virtual void deactivate(void); +protected: + std::multimap myFireCallbacks; + std::list myActivateCallbacks; + std::list myDeactivateCallbacks; + // if we're printing extra information or not + bool myPrinting; + double myTransDeadZone; + double myRotDeadZone; + double myLatDeadZone; + double myFullThrottleForwards; + double myFullThrottleBackwards; + double myRotAtFullForwards; + double myRotAtFullBackwards; + double myRotAtStopped; + double myLatAtFullForwards; + double myLatAtFullBackwards; + double myLatAtStopped; + double myTransRatio; + double myRotRatio; + double myThrottleRatio; + double myLatRatio; + ArActionDesired myDesired; +}; + +#endif // ARACTIONSTOP_H diff --git a/Legacy/Aria/include/ArActionRobotJoydrive.h b/Legacy/Aria/include/ArActionRobotJoydrive.h new file mode 100644 index 0000000..663ac81 --- /dev/null +++ b/Legacy/Aria/include/ArActionRobotJoydrive.h @@ -0,0 +1,87 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARACTIONROBOTJOYDRIVE_H +#define ARACTIONROBOTJOYDRIVE_H + +#include "ariaTypedefs.h" +#include "ArAction.h" + +class ArRobotPacket; + +/// This action will use the joystick for input to drive the robot +/** + This class creates its own ArJoyHandler to get input from the + joystick. Then it will scale the speed between 0 and the given max + for velocity and turning, up and down on the joystick go + forwards/backwards while right and left go right and left. You + must press in one of the two joystick buttons for the class to pay + attention to the joystick. + + NOTE: The joystick does not save calibration information, so you + must calibrate the joystick before each time you use it. To do + this, press the button for at least a half a second while the + joystick is in the middle. Then let go of the button and hold the + joystick in the upper left for at least a half second and then in + the lower right corner for at least a half second. + + @ingroup ActionClasses +**/ +class ArActionRobotJoydrive : public ArAction +{ +public: + /// Constructor + AREXPORT ArActionRobotJoydrive(const char * name = "robotJoyDrive", + bool requireDeadmanPushed = true); + /// Destructor + AREXPORT virtual ~ArActionRobotJoydrive(); + AREXPORT virtual ArActionDesired *fire(ArActionDesired currentDesired); + AREXPORT virtual ArActionDesired *getDesired(void) { return &myDesired; } +#ifndef SWIG + AREXPORT virtual const ArActionDesired *getDesired(void) const + { return &myDesired; } +#endif + AREXPORT virtual void setRobot(ArRobot *robot); +protected: + AREXPORT bool handleJoystickPacket(ArRobotPacket *packet); + AREXPORT void connectCallback(void); + // whether we require the deadman to be pushed to drive + bool myRequireDeadmanPushed; + + bool myDeadZoneLast; + int myButton1; + int myButton2; + int myJoyX; + int myJoyY; + int myThrottle; + ArTime myPacketReceivedTime; + // action desired + ArActionDesired myDesired; + ArRetFunctor1C myHandleJoystickPacketCB; + ArFunctorC myConnectCB; +}; + +#endif //ARACTIONROBOTJOYDRIVE_H diff --git a/Legacy/Aria/include/ArActionStallRecover.h b/Legacy/Aria/include/ArActionStallRecover.h new file mode 100644 index 0000000..8ddb2db --- /dev/null +++ b/Legacy/Aria/include/ArActionStallRecover.h @@ -0,0 +1,101 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARACTIONSTALLRECOVER_H +#define ARACTIONSTALLRECOVER_H + +#include "ariaTypedefs.h" +#include "ArAction.h" + +class ArResolver; + +/// Action to recover from a stall +/** + This action tries to recover if one of the wheels has stalled, it has a + series of actions it tries in order to get out of the stall. + @ingroup ActionClasses +*/ +class ArActionStallRecover : public ArAction +{ +public: + /// Constructor + AREXPORT ArActionStallRecover(const char * name = "stall recover", + double obstacleDistance = 225, int cyclesToMove = 50, + double speed = 150, double degreesToTurn = 45, + bool enabled = true); + /// Destructor + AREXPORT virtual ~ArActionStallRecover(); + AREXPORT virtual ArActionDesired *fire(ArActionDesired currentDesired); + AREXPORT virtual ArActionDesired *getDesired(void) + { return &myActionDesired; } +#ifndef SWIG + AREXPORT virtual const ArActionDesired *getDesired(void) const + { return &myActionDesired; } +#endif + AREXPORT void addToConfig(ArConfig* config, const char* sectionName, ArPriority::Priority priority = ArPriority::NORMAL); + AREXPORT virtual void activate(void); +protected: + // these are internal things, don't touch unless you know what you are doing + void doit(void); // does whatever should be done + void addSequence(int sequence); + int myDoing; // what we're doing, uses the stuff from the enum What + int myState; // holds the state + int myCount; // count down variable, -1 if first time in this state + int mySideStalled; // 1 for left, 2 for right, 3 for both + + enum State + { + STATE_NOTHING = 0, // waiting + STATE_GOING // do something + }; + + enum What + { + BACK=0x1, // back up + FORWARD=0x2, // go forward + TURN=0x4, // turn away from obstacles + TURN_LEFT=0x8, // turn left + TURN_RIGHT=0x10, // turn right + MOVEMASK = BACK | FORWARD, + TURNMASK = TURN | TURN_LEFT | TURN_RIGHT + }; + + std::map mySequence; // list of things to do as stall continues + int mySequenceNum; + int mySequencePos; + time_t myLastFired; + double myObstacleDistance; + int myCyclesToMove; + bool myEnabled; + double mySpeed; + int myCyclesToTurn; + double myDegreesToTurn; + double myDesiredHeading; + ArActionDesired myActionDesired; + + ArResolver *myResolver; +}; + +#endif //ARACTIONSTALLRECOVER_H diff --git a/Legacy/Aria/include/ArActionStop.h b/Legacy/Aria/include/ArActionStop.h new file mode 100644 index 0000000..45223e2 --- /dev/null +++ b/Legacy/Aria/include/ArActionStop.h @@ -0,0 +1,54 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARACTIONSTOP_H +#define ARACTIONSTOP_H + +#include "ariaTypedefs.h" +#include "ArAction.h" + +/// Action for stopping the robot +/** + This action simply sets the robot to a 0 velocity and a deltaHeading of 0. + @ingroup ActionClasses +*/ +class ArActionStop : public ArAction +{ +public: + /// Constructor + AREXPORT ArActionStop(const char *name = "stop"); + /// Destructor + AREXPORT virtual ~ArActionStop(); + AREXPORT virtual ArActionDesired *fire(ArActionDesired currentDesired); + AREXPORT virtual ArActionDesired *getDesired(void) { return &myDesired; } +#ifndef SWIG + AREXPORT virtual const ArActionDesired *getDesired(void) const + { return &myDesired; } +#endif +protected: + ArActionDesired myDesired; +}; + +#endif // ARACTIONSTOP_H diff --git a/Legacy/Aria/include/ArActionTriangleDriveTo.h b/Legacy/Aria/include/ArActionTriangleDriveTo.h new file mode 100644 index 0000000..ff7217f --- /dev/null +++ b/Legacy/Aria/include/ArActionTriangleDriveTo.h @@ -0,0 +1,283 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARACTIONTRIANGLEDRIVETO +#define ARACTIONTRIANGLEDRIVETO + +#include "ariaTypedefs.h" +#include "ArAction.h" +#include "ArLineFinder.h" + +/// Action to drive up to a triangle target (e.g. docking station) found from an ArLineFinder +/** + * This action uses ArLineFinder to find continuous "lines" in + * laser range finder data that meet at an angle, forming the point of a + * triangular shape, towards which the robot is driven and aligned. + * If an ArLineFinder object is not given in the constructor, then it will + * search for an ArRangeDevice on the ArRobot with a name "laser" and create its + * own ArLineFinder object using that range device. + + The parameters describing the shape of the triangle target may be set with setTriangleParams(). The default values are for a trianrgle target consisting of two lines of at least 254 mm. meeting + at a 135 degree angle. This is the shape of the triangular + target on docking stations. Targets also may easily be constructed out of any material well-sensed by the SICK Laser, such as wood, cardboard, or metal. + + If setTwoStageApproach() is called with true + (default) it will first drive to a half meter away from the desired + spot (distFromVertex from the point of the vertex along the + bisection of the angle between segments) and then after it reachs + that point it will turn in towards the vertex and drive to the + final spot. If setTwoStageApproach() is called with false it'll just drive to + the final spot. It will stop at closeDist away unless a large turn + is required where it'll stop 2 * closeDist away. It drives in at + the speed given in the constructor. If the robot is closer to the vertex + than it should be for the approach it'll skip the approach, if the + robot is closer to the vertex than to the final spot it will back + up (if its facing away from the vertex it won't see the vertex). + + If you want the action to drive straight to the vertex instead of + to a point in front of it call setGotoVertex() with a true + argument... It will no longer do this if finalDistFromVertex is + 0... you would do this if you want to drive until a bumper is hit + for instance. + + If you want the action to position using the front of the robot + then use setPositionFront(). + + @ingroup ActionClasses + **/ + +class ArActionTriangleDriveTo : public ArAction +{ +public: + /// Constructor + AREXPORT ArActionTriangleDriveTo(const char *name = "triangleDriveTo", + double finalDistFromVertex = 400, + double approachDistFromVertex = 1000, + double speed = 200, + double closeDist = 100, + double acquireTurnSpeed = 30); + /// Destructor + AREXPORT virtual ~ArActionTriangleDriveTo(); + /// Sets if we will turn to see if we can acquire the triangle + void setAcquire(bool acquire = false) { myAcquire = acquire; } + /// Gets if we will turn to see if we can acquire the triangle + bool getAcquire(void) { return myAcquire; } + /// Sets the final distance from vertex + void setFinalDistFromVertex(double dist) { myFinalDistFromVertex = dist; } + /// Sets the final distance from vertex + double getFinalDistFromVertex(void) { return myFinalDistFromVertex; } + /// Sets the parameter of the triangle we're looking for + void setTriangleParams(double line1Length = 254, + double angleBetween = 135, + double line2Length = 254) + { myLine1Length = line1Length; myAngleBetween = angleBetween; myLine2Length = line2Length; } + AREXPORT void setParameters(double finalDistFromVertex = 400, + double approachDistFromVertex = 1000, + double speed = 200, + double closeDist = 100, + double acquireTurnSpeed = 30); + + /// Gets whether we adjust the vertex or not + bool getAdjustVertex(void) { return myAdjustVertex; } + /// Sets whether we adjust the vertex or not + void setAdjustVertex(bool adjustVertex) { myAdjustVertex = adjustVertex; } + /// Sets the vertex offset + void setVertexOffset(int localXOffset, int localYOffset, double thOffset) + { myLocalXOffset = localXOffset; myLocalYOffset = localYOffset; + myThOffset = thOffset; } + /// Sets if we should use the legacy vertex mode or not + void setUseLegacyVertexOffset(bool useLegacyVertexOffset) + { myUseLegacyVertexOffset = useLegacyVertexOffset; } + /// Gets if we are use the legacy vertex mode or not + bool getUseLegacyVertexOffset(void) { return myUseLegacyVertexOffset; } + /// Gets whether it always goto the vertex and not the point in front + bool getGotoVertex(void) { return myGotoVertex; } + /// Sets whether it always goto the vertex and not the point in front + void setGotoVertex(bool gotoVertex) + { myGotoVertex = gotoVertex; } + /// Sets the distance to the triangle at which we start ignoring it + void setIgnoreTriangleDist(double dist = 250, + bool useIgnoreInGotoVertexMode = false) + { myIgnoreTriangleDist = dist; + myUseIgnoreInGoto = useIgnoreInGotoVertexMode; } + /// Gets the distance to the triangle at which we start ignoring it + double getIgnoreTriangleDist(void) { return myIgnoreTriangleDist; } + /// Gets if we're ignoring the triangle in goto vertex mode + bool getUseIgnoreInGotoVertexMode(void) { return myUseIgnoreInGoto; } + /// How long to keep going without having seen the vertex (0 is no timeout) + void setVertexUnseenStopMSecs(int vertexUnseenStopMSecs = 4000) + { myVertexUnseenStopMSecs = vertexUnseenStopMSecs; } + /// How long to keep going without having seen the vertex (0 is no timeout) + int getVertexUnseenStopMSecs(void) { return myVertexUnseenStopMSecs; } + /// Sets the maximum distance between points in a line + void setMaxDistBetweenLinePoints(int maxDistBetweenLinePoints = 0) + { myMaxDistBetweenLinePoints = maxDistBetweenLinePoints; } + /// Sets the maximum lateral distance from the robot to the triangle line + void setMaxLateralDist(int maxLateralDist = 0) + { myMaxLateralDist = maxLateralDist; } + /// Sets the maximum angle misalignment from the robot to the triangle line + void setMaxAngleMisalignment(int maxAngleMisalignment = 0) + { myMaxAngleMisalignment = maxAngleMisalignment; } + enum State { + STATE_INACTIVE, ///< we aren't trying + STATE_ACQUIRE, ///< finding the target + STATE_SEARCHING, ///< Turning trying to find the target + STATE_GOTO_APPROACH, ///< driving to the approach point + STATE_ALIGN_APPROACH, ///< aligning to the target the first time + STATE_GOTO_VERTEX, ///< driving to the vertex + STATE_GOTO_FINAL, ///< driving to the final point + STATE_ALIGN_FINAL, ///< aligning to the target the final time + STATE_SUCCEEDED, ///< pointing at the target + STATE_FAILED ///< if we're not acquiring and we lost the vertex we fail + }; + /// Gets the state + State getState(void) { return myState; } + /// Gets if we've seen the vertex ever for this attempted drive (it gets reset in searching, but that's the only time, so will only be set once an activation by default (unless setAcquire is called) + bool getVertexSeen(void) { return myVertexSeen; } + /// Sets the line finder to use + AREXPORT void setLineFinder(ArLineFinder *lineFinder); + /// Sets the line finder used + AREXPORT ArLineFinder *getLineFinder(void) { return myLineFinder; } + + /// Sets whether we're logging the driving or not + void setLogging(bool logging) { myPrinting = logging; } + /// Gets whether we're logging the driving or not + bool setLogging(void) { return myPrinting; } + AREXPORT virtual void activate(void); + AREXPORT virtual void deactivate(void); + AREXPORT virtual void setRobot(ArRobot *robot); + AREXPORT virtual ArActionDesired *fire(ArActionDesired currentDesired); + AREXPORT virtual ArActionDesired *getDesired(void) { return &myDesired; } +#ifndef SWIG + AREXPORT virtual const ArActionDesired *getDesired(void) const + { return &myDesired; } +#endif + +#ifndef SWIG + /** + This is for some internal debugging, don't try to use it, it won't + work in windows (memory allocation issues). If there's desire for + a feature like this I can add it later. + @internal + **/ + class Data + { + public: + Data() + { myFinalSet = false; myApproachSet = false; myLinesAndVertexSet = false; + myVertexSeenThisCycle = false; myVertexSeen = false; } + ~Data() {} + void setLinesAndVertex(std::map *lines, + ArPose vertex) + { + myLines.clear(); + std::map::iterator it; + for (it = lines->begin(); it != lines->end(); it++) + { + myLines.push_front(*(*it).second); + } + myVertex = vertex; + myLinesAndVertexSet = true; + } + void setFinal(ArPose final) { myFinalSet = true; myFinal = final; } + void setApproach(ArPose approach) + { myApproachSet = true; myApproach = approach; } + void setVertexSeenThisCycle(bool vertexSeenThisCycle) + { myVertexSeenThisCycle = vertexSeenThisCycle; } + void setVertexSeen(bool vertexSeen) + { myVertexSeen = vertexSeen; } + + + bool myLinesAndVertexSet; + std::list myLines; + ArPose myVertex; + bool myFinalSet; + ArPose myFinal; + bool myApproachSet; + ArPose myApproach; + bool myVertexSeenThisCycle; + bool myVertexSeen; + }; + /** Internal use only, sets if we're saving data or not + * @internal + */ + void setSaveData(bool saveData) { mySaveData = saveData; } + /** Internal use only, gets if we're saving data or not + * @internal + */ + bool getSaveData(void) { return mySaveData; } + /** Interal use only, gets the data we've saved + * @internal + */ + Data *getData(void); +#endif // ifndef SWIG +protected: + // Find our triangle, Internal function + AREXPORT void findTriangle(bool initial, bool goStraight = false); + // Finds a pose this dist from the vertex along the line from the vertex + AREXPORT ArPose findPoseFromVertex(double distFromVertex); + // where the vertex was in encoder coords + ArPose myVertex; + + ArRangeDevice *myLaser; + //ArLaser *myLaser; + ArMutex myDataMutex; + bool mySaveData; + Data *myData; + std::map *myLines; + unsigned int myGotLinesCounter; + bool myVertexSeen; + bool myPrinting; + ArTime myVertexSeenLast; + State myState; + double myOriginalAngle; + bool myAcquire; + double myFinalDistFromVertex; + double myApproachDistFromVertex; + double mySpeed; + double myCloseDist; + double myAcquireTurnSpeed; + bool myTwoStageApproach; + double myLine1Length; + double myAngleBetween; + double myLine2Length; + int myVertexUnseenStopMSecs; + ArActionDesired myDesired; + ArLineFinder *myLineFinder; + bool myOwnLineFinder; + bool myAdjustVertex; + bool myGotoVertex; + int myLocalXOffset; + int myLocalYOffset; + double myThOffset; + bool myUseLegacyVertexOffset; + double myIgnoreTriangleDist; + bool myUseIgnoreInGoto; + int myMaxDistBetweenLinePoints; + int myMaxLateralDist; + int myMaxAngleMisalignment; +}; + +#endif // ARACTIONTRIANGLEDRIVETO diff --git a/Legacy/Aria/include/ArActionTurn.h b/Legacy/Aria/include/ArActionTurn.h new file mode 100644 index 0000000..cf17fd2 --- /dev/null +++ b/Legacy/Aria/include/ArActionTurn.h @@ -0,0 +1,68 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARACTIONTURN +#define ARACTIONTURN + +#include "ariaTypedefs.h" +#include "ArAction.h" + +/// Action to turn when the behaviors with more priority have limited the speed +/** + This action is basically made so that you can just have a ton of + limiters of different kinds and types to keep speed under control, + then throw this into the mix to have the robot wander. Note that + the turn amount ramps up to turnAmount starting at 0 at + speedStartTurn and hitting the full amount at speedFullTurn. + + @ingroup ActionClasses +**/ +class ArActionTurn : public ArAction +{ +public: + /// Constructor + AREXPORT ArActionTurn(const char *name = "turn", + double speedStartTurn = 200, + double speedFullTurn = 100, + double turnAmount = 15); + /// Destructor + AREXPORT virtual ~ArActionTurn(); + AREXPORT virtual ArActionDesired *fire(ArActionDesired currentDesired); + AREXPORT virtual ArActionDesired *getDesired(void) { return &myDesired; } +#ifndef SWIG + AREXPORT virtual const ArActionDesired *getDesired(void) const + { return &myDesired; } +#endif +protected: + double mySpeedStart; + double mySpeedFull; + double myTurnAmount; + double myTurning; + + ArActionDesired myDesired; + +}; + +#endif // ARACTIONTURN diff --git a/Legacy/Aria/include/ArAnalogGyro.h b/Legacy/Aria/include/ArAnalogGyro.h new file mode 100644 index 0000000..5976312 --- /dev/null +++ b/Legacy/Aria/include/ArAnalogGyro.h @@ -0,0 +1,222 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARANALOGGYRO_H +#define ARANALOGGYRO_H + +#include "ariaTypedefs.h" +#include "ariaUtil.h" +#include "ArFunctor.h" + +class ArRobot; +class ArRobotPacket; + +/// Use onboard gyro to improve the heading in an ArRobot object's pose value +/** + The gyro is an accessory connected to the robot's microcontroller. + The gyro's purpose is to improve large errors due to wheel + slippage, wheels coming off the ground, and other factors like this + (or for the skid steer of an AT). The gyro also happens to provide + temperature readings as well. + + When an ArAnalogGyro object is created, it registers callbacks with the + robot, and automatic heading correction will begin when new data arrives + from the robot. + If you delete the object, it will remove itself from the robot. + + The readings come back from the gyro over the robot microcontroller's analog ports. + The microcontroller then sends the readings to us just before + sending us the standard packet. ArAnalogGyro uses these readings to + calculate a better heading of the robot (integrating the velocities to + give position). Then when the standard packet comes in, ArRobot calls + an encoder correction callback in ArAnalogGyro which does a simple + Kalman filter and fuses the encoder information's heading with the gyro's heading + to compute the most probable heading which it then returns to the + ArRobot object to use as its heading. + + The robot's normal dead reconing angle is fairly good if you have properly + inflated tires (if you have pneumatic tires) and if you have + the revcount parameter sent correctly. See the robot operation manual for + how to change the revcount parameter. + + Gyro readings are affected by temperature (a temperature value + is reported along with the gyro data in the packets from the + microcontroller). The gyro will auto calibrate itself to the + center of the range (which may have drifted due to temperature) + whenever the robot is stationary for more than one second (that is, if its + translational and rotational velocities are less than 1 + and if the gyro readings are also within .5% of the average). The + scaling factor (between change of voltage and amount of turn) + doesn't seem to change due to temperature, though it can vary among + different gyro devices. (This scaling factor can be accessed with + getScalingFactor() and setScalingFactor().) + The default value used here was within 3% of correct most of the time. + The default resides in the parameter file for the robot that is loaded or used when a + connection is made. If you want to tune this more you can, by + finding a different scale factor. (There is just one so there + doesn't have to be alot of calibration in flash that is lost if + parameters are loaded from a file.) + + General notes on gyros and inertial correction: The purpose of the gyro is to + correct for wheel slippage and large errors. It is not to totally correct + for all errors, but to bring the errors into smaller zones that + software can correct for more easily (such as by localization). + We have found that if gyros or inertial measurement devices are used to attempt to + correct for all error, the result can be not very robust, and include + many problematic assumptions. For this reason, we have found that + it is best to integrate this one simple gyro to simply improve robot odometry, + rather than a complicated and expensive IMU. + + @ingroup OptionalClasses + +*/ +class ArAnalogGyro +{ +public: + /// Constructor + AREXPORT ArAnalogGyro(ArRobot *robot); + /// Destructor + AREXPORT virtual ~ArAnalogGyro(); + /// Gets if we really have a gyro or not + AREXPORT bool isActive(void) { return myIsActive; } + /// Lets the gyro correct readings + AREXPORT void activate(void); + /// Stops the gyro from correcting readings (still accumulates) + AREXPORT void deactivate(void); + /// If we have a gyro only mode + bool hasGyroOnlyMode(void) { return myHasGyroOnlyMode; } + /// If we're using gyro only mode + bool isGyroOnlyActive(void) { return myIsGyroOnlyActive; } + /// Activates it and puts it in gyro only mode + AREXPORT void activateGyroOnly(void); + /// If this class actually has data or not (if it has no data, the + /// robot is all there is) + bool hasNoInternalData(void) { return myHasNoData; } + /// Returns true if any amount of gyro data has yet been received, false if no readings have yet been received from the robot. + AREXPORT bool haveGottenData(void) { return myHaveGottenData; } + /// Gets a heading calculated from past gyro readings + AREXPORT double getHeading(void) const { return myHeading; } + /// Gets the temperature the gyro has + AREXPORT int getTemperature(void) const { return myTemperature; } + /// Set the parameters of the Kalman filter model + /** + @param gyroSigma the amount its off statically + + @param inertialVar the proportional amount it is off + + @param rotVar the amount the rotation is off proportionally + + @param transVar the amount the translation throws off the heading + proportionally + **/ + AREXPORT void setFilterModel(double gyroSigma, double inertialVar, + double rotVar, double transVar) + { myGyroSigma = gyroSigma; myInertialVarianceModel = inertialVar; + myRotVarianceModel = rotVar; myTransVarianceModel = transVar; }; + + /// Returns the number of readings taken in the last second + AREXPORT int getPacCount(void) { return myPacCount; } + + /// Gets the most recently calculated average rotational velocity (over one + //second) + AREXPORT double getAverage(void) const { return myLastAverage; } + /// Gets the time the last average was taken + AREXPORT ArTime getAverageTaken(void) const { return myLastAverageTaken; } + /// Gets the scaling factor used for multiplying the reading values received (default 1.626) + AREXPORT double getScalingFactor(void) const { return myScalingFactor; } + /// Sets the scaling factor used for multiplying the readings + AREXPORT void setScalingFactor(double factor) { myScalingFactor = factor; } + + /// Internal packet handler for the gyro packets + AREXPORT bool handleGyroPacket(ArRobotPacket *packet); + /// internal function for correcting the encoder readings with the gyro data + AREXPORT double encoderCorrect(ArPoseWithTime deltaPose); + /// Internal connection callback; delays for a short amount of time to give the gyro enough time to stabilize before we try to use it + AREXPORT void stabilizingCallback(void); + /// Internal user task callback + AREXPORT void userTaskCallback(void); + /// Sets whether we log anomalies or not (temporary function for debugging) + void setLogAnomalies(bool logAnomalies) { myLogAnomalies = logAnomalies; } +protected: + // whether we're correcting readings or not + bool myIsActive; + // whether we're really getting readings or not + bool myHaveGottenData; + // our double for our scaling factor + double myScalingFactor; + // if we've gotten a reading this cycle + bool myReadingThisCycle; + // whether we're logging anomalies or not + bool myLogAnomalies; + // counting data + int myPacCount; + int myPacCurrentCount; + time_t myTimeLastPacket; + + // data for averaging + ArTime myAverageStarted; + double myLastAverage; + ArTime myLastAverageTaken; + double myAverageTotal; + int myAverageCount; + + + // constants for kalman filtering + double myGyroSigma; + double myInertialVarianceModel; + double myRotVarianceModel; // deg2/deg + double myTransVarianceModel; // deg2/meter + + // for if our gyro packets aren't aligned with our sips how much + // we've changed since we last got to correct one + double myAccumulatedDelta; + + double myHeading; + int myTemperature; + double myLastHeading; + ArRobot *myRobot; + ArRetFunctor1C myHandleGyroPacketCB; + ArRetFunctor1C myEncoderCorrectCB; + ArFunctorC myStabilizingCB; + ArFunctorC myUserTaskCB; + + /// Gyro type + enum GyroType + { + GYRO_NONE, ///< No gyro + GYRO_ANALOG_COMPUTER, ///< Analog gyro used by computer + GYRO_ANALOG_CONTROLLER ///< Analog gyro used by microcontroller + }; + GyroType myGyroType; + bool myHasNoData; + bool myHasGyroOnlyMode; + bool myIsGyroOnlyActive; + + bool myGyroWorking; +}; + +#endif // ARANALOGGYRO_H + + diff --git a/Legacy/Aria/include/ArArg.h b/Legacy/Aria/include/ArArg.h new file mode 100644 index 0000000..ff4e3c2 --- /dev/null +++ b/Legacy/Aria/include/ArArg.h @@ -0,0 +1,172 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARARG_H +#define ARARG_H + +#include "ariaTypedefs.h" +#include "ariaUtil.h" +#include "ArFunctor.h" + +class ArArgumentBuilder; + +/// Argument class, mostly for actions, could be used for other things +/** + This is designed to be easy to add another type to the arguments... + All you have to do to do so, is add an enum to the Type enum, add a + newType getNewType(void), add a void setNewType(newType nt), and add + a case statement for the newType to ArArg::print. You should probably also + add an @see newType to the documentation for ArArg::getType. + +*/ +class ArArg +{ +public: + typedef enum + { + INVALID, ///< An invalid argument, the argument wasn't created correctly + INT, ///< Integer argument + DOUBLE, ///< Double argument + STRING, ///< String argument + BOOL, ///< Boolean argument + POSE, ///< ArPose argument + FUNCTOR, ///< Argument that handles things with functors + DESCRIPTION_HOLDER, ///< Argument that just holds a description + + LAST_TYPE = DESCRIPTION_HOLDER ///< Last value in the enumeration + } Type; + + + enum { + TYPE_COUNT = LAST_TYPE + 1 ///< Number of argument types + }; + + /// Default empty contructor + AREXPORT ArArg(); + /// Constructor for making an integer argument + AREXPORT ArArg(const char * name, int *pointer, + const char * description = "", + int minInt = INT_MIN, + int maxInt = INT_MAX); + /// Constructor for making a double argument + AREXPORT ArArg(const char * name, double *pointer, + const char * description = "", + double minDouble = -HUGE_VAL, + double maxDouble = HUGE_VAL); + /// Constructor for making a boolean argument + AREXPORT ArArg(const char * name, bool *pointer, + const char * description = ""); + /// Constructor for making a position argument + AREXPORT ArArg(const char * name, ArPose *pointer, + const char * description = ""); + /// Constructor for making an argument of a string + AREXPORT ArArg(const char *name, char *pointer, + const char *description, + size_t maxStrLen); + /// Constructor for making an argument that has functors to handle things + AREXPORT ArArg(const char *name, + ArRetFunctor1 *setFunctor, + ArRetFunctor *> *getFunctor, + const char *description); + /// Constructor for just holding a description (for ArConfig) + AREXPORT ArArg(const char *description); + /// Copy constructor + AREXPORT ArArg(const ArArg & arg); + /// Assignment operator + AREXPORT ArArg &operator=(const ArArg &arg); + /// Destructor + AREXPORT virtual ~ArArg(); + + /// Gets the type of the argument + AREXPORT Type getType(void) const; + /// Gets the name of the argument + AREXPORT const char *getName(void) const; + /// Gets the long description of the argument + AREXPORT const char *getDescription(void) const; + /// Sets the argument value, for int arguments + AREXPORT bool setInt(int val); + /// Sets the argument value, for double arguments + AREXPORT bool setDouble(double val); + /// Sets the argument value, for bool arguments + AREXPORT bool setBool(bool val); + /// Sets the argument value, for ArPose arguments + AREXPORT bool setPose(ArPose pose); + /// Sets the argument value for ArArgumentBuilder arguments + AREXPORT bool setString(const char *str); + /// Sets the argument by calling the setFunctor callback + AREXPORT bool setArgWithFunctor(ArArgumentBuilder *argument); + /// Gets the argument value, for int arguments + AREXPORT int getInt(void) const; + /// Gets the argument value, for double arguments + AREXPORT double getDouble(void) const; + /// Gets the argument value, for bool arguments + AREXPORT bool getBool(void) const; + /// Gets the argument value, for pose arguments + AREXPORT ArPose getPose(void) const; + /// Gets the argument value, for string arguments + AREXPORT const char *getString(void) const; + /// Gets the argument value, which is a list of argumentbuilders here + AREXPORT const std::list *getArgsWithFunctor(void) const; + /// Logs the type, name, and value of this argument + AREXPORT void log(void) const; + /// Gets the minimum int value + AREXPORT int getMinInt(void) const; + /// Gets the maximum int value + AREXPORT int getMaxInt(void) const; + /// Gets the minimum double value + AREXPORT double getMinDouble(void) const; + /// Gets the maximum double value + AREXPORT double getMaxDouble(void) const; + /// Gets if the config priority is set + AREXPORT bool getConfigPrioritySet(void) const; + /// Gets the priority (only used by ArConfig) + AREXPORT ArPriority::Priority getConfigPriority(void) const; + /// Sets the priority (only used by ArConfig) + AREXPORT void setConfigPriority(ArPriority::Priority priority); + +private: + /// Internal helper function + AREXPORT void clear(void); + +protected: + + ArArg::Type myType; + std::string myName; + std::string myDescription; + int *myIntPointer; + int myMinInt, myMaxInt; + double *myDoublePointer; + double myMinDouble, myMaxDouble; + bool *myBoolPointer; + ArPose *myPosePointer; + char *myStringPointer; + size_t myMaxStrLen; + bool myConfigPrioritySet; + ArPriority::Priority myConfigPriority; + ArRetFunctor1 *mySetFunctor; + ArRetFunctor *> *myGetFunctor; +}; + +#endif // ARARGUMENT_H diff --git a/Legacy/Aria/include/ArArgumentBuilder.h b/Legacy/Aria/include/ArArgumentBuilder.h new file mode 100644 index 0000000..2acd01b --- /dev/null +++ b/Legacy/Aria/include/ArArgumentBuilder.h @@ -0,0 +1,266 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARARGUMENTBUILDER_H +#define ARARGUMENTBUILDER_H + +#include "ariaTypedefs.h" + +/// This class is to build arguments for things that require argc and argv +/// @ingroup ImportantClasses +class ArArgumentBuilder +{ +public: + /// Constructor + AREXPORT ArArgumentBuilder(size_t argvLen = 512, + char extraSpaceChar = '\0', + bool ignoreNormalSpaces = false, + bool isPreCompressQuotes = false); + /// Copy Constructor + AREXPORT ArArgumentBuilder(const ArArgumentBuilder &builder); + + AREXPORT ArArgumentBuilder &operator=(const ArArgumentBuilder &builder); + + /// Destructor + AREXPORT virtual ~ArArgumentBuilder(); +#ifndef SWIG + /** @brief Adds the given string, with varargs, separates if there are spaces + * @swignote Not available + */ + AREXPORT void add(const char *str, ...); +#endif + /// Adds the given string, without varargs (wrapper for java) + AREXPORT void addPlain(const char *str, int position = -1); + /// Adds the given string, without varargs and without touching the str + AREXPORT void addPlainAsIs(const char *str, int position = -1); + /// Adds the given string thats divided + AREXPORT void addStrings(char **argv, int argc, int position = -1); + /// Adds the given string thats divided + AREXPORT void addStrings(int argc, char **argv, int position = -1); + /// Adds the given string thats divided (but doesn't touch the strings) + AREXPORT void addStringsAsIs(int argc, char **argv, int position = -1); + /// Gets the original string of the input + AREXPORT const char *getFullString(void) const; + /// Sets the full string (this is so you can have a more raw full string) + AREXPORT void setFullString(const char *str); + /// Gets the extra string of the input, used differently by different things + AREXPORT const char *getExtraString(void) const; + /// Sets the extra string of the input, used differently by different things + AREXPORT void setExtraString(const char *str); + /// Prints out the arguments + AREXPORT void log(void) const; + /// Gets the argc + AREXPORT size_t getArgc(void) const; + /// Gets the argv + AREXPORT char** getArgv(void) const; + /// Gets a specific argument as a string + AREXPORT const char* getArg(size_t whichArg) const; + + /// Sees if an argument is a bool + AREXPORT bool isArgBool(size_t whichArg) const; + + /// Gets the value of an argument as a boolean + /** + * Valid boolean values are "true" and "false", and "1" and "0". + * There are two ways to to verify that the specified argument is a bool. + * Either call isArgBool() before calling this method, or specify a non-NULL + * ok parameter value. The latter is somewhat more efficient since the + * argument string is checked only once. + * + * @param whichArg the size_t index of the arg to retrieve; must be >= 0 + * and less than getArgc() + * @param ok an optional pointer to a bool that will be set to true if the + * arg was successfully retrieved or to false if an error occurred + * @return bool the retrieved argument value; valid only if ok or isArgBool + * is true + **/ + AREXPORT bool getArgBool(size_t whichArg, + bool *ok = NULL) const; + + /// Sees if an argument is an int + /** + * @param whichArg the size_t index of the arg to retrieve; must be >= 0 + * and less than getArgc() + * @param forceHex if true this makes it find the int in base 16 instead of 10 + */ + AREXPORT bool isArgInt(size_t whichArg, bool forceHex = false) const; + + /// Gets the value of an argument as an integer + /** + * There are two ways to to verify that the specified argument is an integer. + * Either call isArgInt() before calling this method, or specify a non-NULL + * ok parameter value. The latter is somewhat more efficient because the + * digit status of each character is checked only once. + * + * @param whichArg the size_t index of the arg to retrieve; must be >= 0 + * and less than getArgc() + * @param ok an optional pointer to a bool that will be set to true if the + * arg was successfully retrieved or to false if an error occurred + * @param forceHex if true this makes it find the int in base 16 instead of 10 + * @return int the retrieved argument value; valid only if ok or isArgInt + * is true + **/ + AREXPORT int getArgInt(size_t whichArg, + bool *ok = NULL, bool forceHex = false) const; + + /// Sees if an argument is a long long int + AREXPORT bool isArgLongLongInt(size_t whichArg) const; + + /// Gets the value of an argument as a long long integer + /** + * There are two ways to to verify that the specified argument is an integer. + * Either call isArgInt() before calling this method, or specify a non-NULL + * ok parameter value. The latter is somewhat more efficient because the + * digit status of each character is checked only once. + * + * @param whichArg the size_t index of the arg to retrieve; must be >= 0 + * and less than getArgc() + * @param ok an optional pointer to a bool that will be set to true if the + * arg was successfully retrieved or to false if an error occurred + * @return int the retrieved argument value; valid only if ok or isArgInt + * is true + **/ + AREXPORT int getArgLongLongInt(size_t whichArg, + bool *ok = NULL) const; + + /// Sees if an argument is a double + AREXPORT bool isArgDouble(size_t whichArg) const; + + /// Gets the value of an argument as a double + /** + * There are two ways to to verify that the specified argument is a double. + * Either call isArgDouble() before calling this method, or specify a non-NULL + * ok parameter value. The latter is somewhat more efficient because the + * digit status of each character is checked only once. + * + * @param whichArg the size_t index of the arg to retrieve; must be >= 0 + * and less than getArgc() + * @param ok an optional pointer to a bool that will be set to true if the + * arg was successfully retrieved or to false if an error occurred + * @return double the retrieved argument value; valid only if ok or + * isArgDouble is true + **/ + AREXPORT double getArgDouble(size_t whichArg, + bool *ok = NULL) const; + + /// Delete a particular arg, you MUST finish adding before you can remove + AREXPORT void removeArg(size_t which, + bool isRebuildFullString = false); + /// Combines quoted arguments into one + AREXPORT void compressQuoted(bool stripQuotationMarks = false); + + /// Turn on this flag to reduce the number of verbose log messages. + AREXPORT void setQuiet(bool isQuiet); + +protected: + AREXPORT void internalAdd(const char *str, int position = -1); + AREXPORT void internalAddAsIs(const char *str, int position = -1); + AREXPORT void rebuildFullString(); + + /// Characters that may be used to separate arguments; bitwise flags so QUOTE can be combined with spaces + enum ArgSeparatorType { + SPACE = 1, // Normal space character + SPECIAL = SPACE << 1, // The special "extra" space character, if any + ANY_SPACE = SPACE | SPECIAL, // Either normal space or special extra space + QUOTE = SPECIAL << 1, // Double-quote, must be used in combination with spaces + }; + + /// Determines whether the current buffer position marks the start of an argument + /** + * This method should only be called when an argument is not currently being + * parsed (i.e. the previous character was a space). + * @param buf the char * buffer that is being parsed; must be non-NULL + * @param len the maximum number of characters in the buffer + * @param index the int buffer position of the character to be tested + * @param endArgFlagsOut a pointer to an output int that will indicate which separators + * will mark the end of the argument. If quotes are being pre-processed, and the + * current argument starts with space-quote, then the argument must end with a quote-space. + **/ + bool isStartArg(const char *buf, + int len, + int index, + int *endArgFlagsOut); + + /// Determines whether the current buffer position marks the end of an argument + /** + * This method should only be called when an argument is currently being + * parsed (i.e. isStartArg returned true). + * @param buf the char * buffer that is being parsed; must be non-NULL + * @param len the maximum number of characters in the buffer + * @param indexInOut the input/output int buffer position of the character to be tested; + * if the argument ends with a quote-space, then the index will be incremented to mark + * the space; otherwise, it will remain unchanged + * @param endArgFlags an int that indicates which separators mark the end of the + * argument. If quotes are being pre-processed, and the current argument started + * with space-quote, then the argument must end with a quote-space. + **/ + bool isEndArg(const char *buf, + int len, + int &indexInOut, + int endArgFlags); + + /// Determines whether the specified character is an acceptable space (either normal or extra) + bool isSpace(char c); + + size_t getArgvLen(void) const { return myArgvLen; } + // how many arguments we had originally (so we can delete 'em) + size_t myOrigArgc; + // how many arguments we have + size_t myArgc; + // argument list + char **myArgv; + // argv length + size_t myArgvLen; + // the extra string (utility thing) + std::string myExtraString; + // the full string + std::string myFullString; + // whether this is our first add or not + bool myFirstAdd; + // a character to alternately treat as a space + char myExtraSpace; + // if we should ignore normal spaces + bool myIgnoreNormalSpaces; + /// Whether to treat double-quotes as arg delimiters (preserving spaces within) + bool myIsPreCompressQuotes; + + bool myIsQuiet; +}; + +// ---------------------------------------------------------------------------- + +/// Comparator that returns true if arg1's full string is less than arg2's. +struct ArArgumentBuilderCompareOp +{ +public: + + /// Compares arg1's full string to arg2's. + bool operator() (ArArgumentBuilder* arg1, ArArgumentBuilder* arg2) const; + +}; // end struct ArArgumentBuilderCompareOp + + + +#endif // ARARGUMENTBUILDER_H diff --git a/Legacy/Aria/include/ArArgumentParser.h b/Legacy/Aria/include/ArArgumentParser.h new file mode 100644 index 0000000..eb96956 --- /dev/null +++ b/Legacy/Aria/include/ArArgumentParser.h @@ -0,0 +1,184 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARARGUMENTPARSER_H +#define ARARGUMENTPARSER_H + +#include "ariaTypedefs.h" +#include "ArArgumentBuilder.h" + +/// Parse and store program command-line arguments for use by other ARIA classes. +/** + This class is made for parsing arguments from the argv and argc variables + passed into a program's main() function by the operating system, from + an ArArgumentBuilder object, or just from a string (e.g. provided by WinMain() + in a Windows MFC program.) + + It will also load default argument values if you call + loadDefaultArguments(). Aria::init() adds the file /etc/Aria.args and the + environment variable ARIAARGS as locations for argument defaults, so + loadDefaultArguments() will always search those. You can + use this mechanism to avoid needing to always supply command line parameters + to all programs. For example, if you use different serial ports than the defaults + for the robot and laser, you can put a -robotPort or -laserPort argument in + /etc/Aria.args for all programs that call loadDefaultArguments() to use. + You can add other files or environment variables + to the list of default argument locations with + addDefaultArgumentFile() and addDefaultArgumentEnv(). + + Note that the wasReallySet behavior has changed. It used to set + the variable to false or to true, now it will only set it to false + if 'setWasReallySetOnlyTrue' is set to false. By default that is + set to false, but you can just set it to true after you make the + parser with no ill effects since all of the built in Aria parsers + will play nicely with this value, setting it to true or false while + they parse but then setting it to whatever it was when they + started. This change in behavior is so that checking for two + things (like -robotPort and -rp) can work without a lot of extra + work. + + @ingroup ImportantClasses +**/ +class ArArgumentParser +{ +public: + /// Constructor, takes the argc argv + AREXPORT ArArgumentParser(int *argc, char **argv); + /// Constructor, takes an argument builder + AREXPORT ArArgumentParser(ArArgumentBuilder *builder); + /// Destructor + AREXPORT ~ArArgumentParser(); + /// If we should only set wasReallySet to true + AREXPORT void setWasReallySetOnlyTrue(bool wasReallySetOnlyTrue); + /// If we only set wasReallySet to true + AREXPORT bool getWasReallySetOnlyTrue(void); + /// Returns true if the argument was found + AREXPORT bool checkArgument(const char *argument); + /// Returns the word/argument after given argument + AREXPORT char *checkParameterArgument(const char *argument, + bool returnFirst = false); + /// Returns the word/argument after given argument + AREXPORT bool checkParameterArgumentString(const char *argument, + const char **dest, + bool *wasReallySet = NULL, + bool returnFirst = false); + /// Returns the integer after given argument + AREXPORT bool checkParameterArgumentInteger(const char *argument, int *dest, + bool *wasReallySet = NULL, + bool returnFirst = false); + /// Returns the word/argument after given argument + AREXPORT bool checkParameterArgumentBool(const char *argument, bool *dest, + bool *wasReallySet = NULL, + bool returnFirst = false); + /// Returns the floating point number after given argument + AREXPORT bool checkParameterArgumentFloat(const char *argument, float *dest, + bool *wasReallySet = NULL, bool returnFirst = false); + /// Returns the floating point number after given argument + AREXPORT bool checkParameterArgumentDouble(const char *argument, double *dest, + bool *wasReallySet = NULL, bool returnFirst = false); + /// Adds a string as a default argument + AREXPORT void addDefaultArgument(const char *argument, int position = -1); + /// Adds a string as a default argument as is (without touching + /// spaces or what not) + AREXPORT void addDefaultArgumentAsIs(const char *argument, + int position = -1); + /// Adds args from default files and environmental variables + AREXPORT void loadDefaultArguments(int positon = 1); + /// Checks for the help strings and warns about unparsed arguments + AREXPORT bool checkHelpAndWarnUnparsed(unsigned int numArgsOkay = 0); + /// Gets how many arguments are left in this parser + AREXPORT size_t getArgc(void) const; + /// Gets the argv + AREXPORT char** getArgv(void) const; + /// Gets the argument builder, if one is being used (may be NULL) + AREXPORT const ArArgumentBuilder *getArgumentBuilder(void) const + { return myBuilder; } + /// Gets a specific argument + AREXPORT const char* getArg(size_t whichArg) const; + /// Prints out the arguments left in this parser + AREXPORT void log(void) const; + /// Gets the arguments this parser started with (if possible, NULL otherwise) + AREXPORT const char *getStartingArguments(void) const; + /// Internal function to remove an argument that was parsed + AREXPORT void removeArg(size_t which); + /// Adds another file or environmental variable to the list of defaults + AREXPORT static void addDefaultArgumentFile(const char *file); + /// Adds another file or environmental variable to the list of defaults + AREXPORT static void addDefaultArgumentEnv(const char *env); + /// Logs the default argument locations + AREXPORT static void logDefaultArgumentLocations(void); +#ifndef SWIG + /** @brief Returns true if the argument was found + * @swigomit + */ + AREXPORT bool checkArgumentVar(const char *argument, ...); + /** @brief Returns the word/argument after given argument + * @swigomit + */ + AREXPORT char *checkParameterArgumentVar(const char *argument, ...); + /** @brief Returns the word/argument after given argument + * @swigomit + */ + AREXPORT bool checkParameterArgumentStringVar(bool *wasReallySet, + const char **dest, + const char *argument, ...); + /** @brief Returns the word/argument after given argument + * @swigomit + */ + AREXPORT bool checkParameterArgumentBoolVar(bool *wasReallySet, bool *dest, + const char *argument, ...); + /** @brief Returns the integer after given argument + * @swigomit + */ + AREXPORT bool checkParameterArgumentIntegerVar(bool *wasReallySet, int *dest, + const char *argument, ...); + /** @brief Returns the float after given argument + * @swigomit + */ + AREXPORT bool checkParameterArgumentFloatVar(bool *wasReallySet, + float *dest, + const char *argument, ...); + /** @brief Returns the double after given argument + * @swigomit + */ + AREXPORT bool checkParameterArgumentDoubleVar(bool *wasReallySet, + double *dest, + const char *argument, ...); +#endif +protected: + static std::list ourDefaultArgumentLocs; + static std::list ourDefaultArgumentLocIsFile; + bool myOwnBuilder; + ArArgumentBuilder *myBuilder; + bool myUsingBuilder; + char **myArgv; + int *myArgc; + bool myHelp; + char myEmptyArg[1]; + bool myReallySetOnlyTrue; +}; + + +#endif // ARARGUMENTPARSER_H diff --git a/Legacy/Aria/include/ArBasePacket.h b/Legacy/Aria/include/ArBasePacket.h new file mode 100644 index 0000000..b1c2025 --- /dev/null +++ b/Legacy/Aria/include/ArBasePacket.h @@ -0,0 +1,226 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARBASEPACKET_H +#define ARBASEPACKET_H + + +#include +#include "ariaTypedefs.h" + +/// Base packet class +/** This class is a base class for specific packet types implemented by base + classes. In most cases, you would not instantiate this class directly, but instead + use a subclass. However, ArBasePacket contains many of the functions used to + access the packet's data. + + A packet is a sequence of values stored in a buffer. The contents + of a packet's data buffer is read from a device or other program or written to the + device (for example, a serial port or TCP port + using an ArDeviceConnection or using ArNetworking), optionally preceded + by a header with some identifying data and a length, and optionally followed by a + footer with a checksum of the data. (If the + header length of a particular packet type is 0, no header is written or expected on read, and likewise + with footer.) + + Values are added to the buffer or removed from the buffer in sequence. + The "bufTo" methods are used to remove values from the buffer, and the + "ToBuf" methods are used to add values to the buffer. There are different + methods for different sized values. + + ArBasePacket keeps a current position index in the buffer, which is the position + at which new values are added or values are removed. + + A buffer may be statically allocated externally and supplied to the + constructor + (also give a buffer size to determine the maximum amount of data that can be + placed in that bufer), + or automatically and dynamically allocated by ArBasePacket as needed + (the default behavior). + + When it is time to write out a packet, call finalizePacket() to set + up the footer if neccesary. + To reuse a packet, use empty() to reset the buffer; new data will + then be added to the beginning of the buffer again. +*/ +class ArBasePacket +{ +public: + + /// Constructor + AREXPORT ArBasePacket(ArTypes::UByte2 bufferSize = 0, + ArTypes::UByte2 headerLength = 0, + char * buf = NULL, + ArTypes::UByte2 footerLength = 0); + + /// Copy constructor + AREXPORT ArBasePacket(const ArBasePacket &other); + + /// Assignment operator + AREXPORT ArBasePacket &operator=(const ArBasePacket &other); + + /// Destructor + AREXPORT virtual ~ArBasePacket(); + + /// resets the length for more data to be added + AREXPORT virtual void empty(void); + + /// MakeFinals the packet in preparation for sending, must be done + AREXPORT virtual void finalizePacket(void) {} + + /// ArLogs the hex and decimal values of each byte of the packet, and possibly extra metadata as well + AREXPORT virtual void log(void); + /// ArLogs the hex value of each byte in the packet + AREXPORT virtual void printHex(void); + + /// Returns whether the packet is valid, i.e. no error has occurred when reading/writing. + AREXPORT virtual bool isValid(void); + + /// Resets the valid state of the packet. + AREXPORT virtual void resetValid(); + + // Utility functions to write different data types to a buffer. They will + // increment the length. + + /// Puts ArTypes::Byte into packets buffer + AREXPORT virtual void byteToBuf(ArTypes::Byte val); + /// Puts ArTypes::Byte2 into packets buffer + AREXPORT virtual void byte2ToBuf(ArTypes::Byte2 val); + /// Puts ArTypes::Byte4 into packets buffer + AREXPORT virtual void byte4ToBuf(ArTypes::Byte4 val); + + /// Puts ArTypes::UByte into packets buffer + AREXPORT virtual void uByteToBuf(ArTypes::UByte val); + /// Puts ArTypes::UByte2 into packet buffer + AREXPORT virtual void uByte2ToBuf(ArTypes::UByte2 val); + /// Puts ArTypes::UByte 4 into packet buffer + AREXPORT virtual void uByte4ToBuf(ArTypes::UByte4 val); + + /// Puts a NULL-terminated string into packet buffer + AREXPORT virtual void strToBuf(const char *str); + + /** + * @brief Copies the given number of bytes from str into packet buffer + * @deprecated use strToBufPadded(), strToBuf(), or dataToBuf() instead + **/ + AREXPORT virtual void strNToBuf(const char *str, int length); + /// Copies length bytes from str, if str ends before length, pads data with 0s + AREXPORT virtual void strToBufPadded(const char *str, int length); + /// Copies length bytes from data into packet buffer + AREXPORT virtual void dataToBuf(const char *data, int length); + /// Copies length bytes from data into packet buffer + AREXPORT virtual void dataToBuf(const unsigned char *data, int length); + + // Utility functions to read differet data types from a bufer. Each read + // will increment the myReadLength. + /// Gets a ArTypes::Byte from the buffer + AREXPORT virtual ArTypes::Byte bufToByte(void); + /// Gets a ArTypes::Byte2 from the buffer + AREXPORT virtual ArTypes::Byte2 bufToByte2(void); + /// Gets a ArTypes::Byte4 from the buffer + AREXPORT virtual ArTypes::Byte4 bufToByte4(void); + + /// Gets a ArTypes::UByte from the buffer + AREXPORT virtual ArTypes::UByte bufToUByte(void); + /// Gets a ArTypes::UByte2 from the buffer + AREXPORT virtual ArTypes::UByte2 bufToUByte2(void); + /// Gets a ArTypes::UByte4 from the buffer + AREXPORT virtual ArTypes::UByte4 bufToUByte4(void); + + /// Gets a string from the buffer + AREXPORT virtual void bufToStr(char *buf, int len); + /// Gets length bytes from buffer and puts them into data + AREXPORT virtual void bufToData(char * data, int length); + /// Gets length bytes from buffer and puts them into data + AREXPORT virtual void bufToData(unsigned char * data, int length); + + /// Restart the reading process + AREXPORT virtual void resetRead(void); + + // Accessors + + /// Gets the total length of the packet + virtual ArTypes::UByte2 getLength(void) const { return myLength; } + /// Gets the length of the data in the packet + virtual ArTypes::UByte2 getDataLength(void) const { return myLength - myHeaderLength - myFooterLength; } + + /// Gets how far into the packet that has been read + virtual ArTypes::UByte2 getReadLength(void) const { return myReadLength; } + /// Gets how far into the data of the packet that has been read + virtual ArTypes::UByte2 getDataReadLength(void) const { return myReadLength - myHeaderLength; } + /// Gets the length of the header + virtual ArTypes::UByte2 getHeaderLength(void) const + { return myHeaderLength; } + /// Gets the length of the header + virtual ArTypes::UByte2 getFooterLength(void) const + { return myFooterLength; } + + /// Gets the maximum length packet + virtual ArTypes::UByte2 getMaxLength(void) const { return myMaxLength; } + + /// Gets a const pointer to the buffer the packet uses + AREXPORT virtual const char * getBuf(void) const; + + /// Gets a pointer to the buffer the packet uses + AREXPORT virtual char * getBuf(void); + + /// Sets the buffer the packet is using + AREXPORT virtual void setBuf(char *buf, ArTypes::UByte2 bufferSize); + /// Sets the maximum buffer size (if new size is <= current does nothing) + AREXPORT virtual void setMaxLength(ArTypes::UByte2 bufferSize); + /// Sets the length of the packet + AREXPORT virtual bool setLength(ArTypes::UByte2 length); + /// Sets the read length + AREXPORT virtual void setReadLength(ArTypes::UByte2 readLength); + /// Sets the length of the header + AREXPORT virtual bool setHeaderLength(ArTypes::UByte2 length); + /// Makes this packet a duplicate of another packet + AREXPORT virtual void duplicatePacket(ArBasePacket *packet); +protected: + // internal function to make sure we have enough length left to read in the packet + AREXPORT bool isNextGood(int bytes); + + /// Returns true if there is enough room in the packet to add the specified number of bytes + AREXPORT bool hasWriteCapacity(int bytes); + + // internal data + ArTypes::UByte2 myHeaderLength; + ArTypes::UByte2 myFooterLength; + ArTypes::UByte2 myMaxLength; + + ArTypes::UByte2 myReadLength; + bool myOwnMyBuf; + + // Actual packet data + char *myBuf; + ArTypes::UByte2 myLength; + + // Whether no error has occurred in reading/writing the packet. + bool myIsValid; + +}; + + +#endif // ARPACKET_H diff --git a/Legacy/Aria/include/ArBatteryConnector.h b/Legacy/Aria/include/ArBatteryConnector.h new file mode 100644 index 0000000..85ea0be --- /dev/null +++ b/Legacy/Aria/include/ArBatteryConnector.h @@ -0,0 +1,193 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARBATTERYCONNECTOR_H +#define ARBATTERYCONNECTOR_H + +#include "ariaTypedefs.h" +#include "ArSerialConnection.h" +#include "ArTcpConnection.h" +#include "ArArgumentBuilder.h" +#include "ArArgumentParser.h" +#include "ariaUtil.h" +#include "ArRobotConnector.h" + +class ArBatteryMTX; +class ArRobot; + + + +/// Connect to robot and battery based on run-time availablitily and command-line arguments +/** + + ArBatteryConnector makes a battery connection either through a serial port + connection, or through a TCP + port (for the simulator or for robots with Ethernet-serial bridge + devices instead of onboard computers). + Normally, it first attempts a TCP connection on + @a localhost port 8101, to use a simulator if running. If the simulator + is not running, then it normally then connects using the serial port + Various connection + parameters are configurable through command-line arguments or in the robot + parameter file. (Though the internal interface used by ARIA to do this is also + available if you need to use it: See addBattery(); otherwise don't use + addBattery(), setupBattery(), etc.). + + When you create your ArBatteryConnector, pass it command line parameters via + either the argc and argv variables from main(), or pass it an + ArArgumentBuilder or ArArgumentParser object. (ArArgumentBuilder + is able to obtain command line parameters from a Windows program + that uses WinMain() instead of main()). + ArBatteryConnector registers a callback with the global Aria class. Use + Aria::parseArgs() to parse all command line parameters to the program, and + Aria::logOptions() to print out information about all registered command-line parameters. + + The following command-line arguments are checked: + @verbinclude ArBatteryConnector_options + + To connect to any batteries that were set up in the robot parameter file or + via command line arguments, call connectBatteries(). If successful, + connectBatteries() will return true and add an entry for each battery connected + in the ArRobot object's list of batteries. These ArBatteryMTX objects can be + accessed from your ArRobot object via ArRobot::findBattery() or ArRobot::getBatteryMap(). + + + @since 2.8.0 + + **/ +class ArBatteryConnector +{ +public: + /// Constructor that takes argument parser + AREXPORT ArBatteryConnector(ArArgumentParser *parser, + ArRobot *robot, ArRobotConnector *robotConnector, + bool autoParseArgs = true, + ArLog::LogLevel infoLogLevel = ArLog::Verbose); + /// Destructor + AREXPORT ~ArBatteryConnector(void); + /// Connects all the batteries the robot has that should be auto connected + AREXPORT bool connectBatteries(bool continueOnFailedConnect = false, + bool addConnectedBatteriesToRobot = true, + bool addAllBatteriesToRobot = false, + bool turnOnBatteries = true, + bool powerCycleBatteryOnFailedConnect = true); + /// Sets up a battery to be connected + AREXPORT bool setupBattery(ArBatteryMTX *battery, + int batteryNumber = 1); + /// Connects the battery synchronously (will take up to a minute) + AREXPORT bool connectBattery(ArBatteryMTX *battery, + int batteryNumber = 1, + bool forceConnection = true); + /// Adds a battery so parsing will get it + AREXPORT bool addBattery(ArBatteryMTX *battery, + int batteryNumber = 1); + /// Function to parse the arguments given in the constructor + AREXPORT bool parseArgs(void); + /// Function to parse the arguments given in an arbitrary parser + AREXPORT bool parseArgs(ArArgumentParser *parser); + /// Log the options the simple connector has + AREXPORT void logOptions(void) const; + /// Internal function to get the battery (only useful between parseArgs and connectBatteries) + AREXPORT ArBatteryMTX *getBattery(int batteryNumber); + + /// Internal function to replace the battery (only useful between parseArgs and connectBatteries) but not the battery data + AREXPORT bool replaceBattery(ArBatteryMTX *battery, int batteryNumber); + +protected: +/// Class that holds information about the battery data +class BatteryData +{ + public: + BatteryData (int number, ArBatteryMTX *battery) { + myNumber = number; + myBattery = battery; + myConn = NULL; + myConnect = false; myConnectReallySet = false; + myPort = NULL; + myPortType = NULL; + myType = NULL; + myRemoteTcpPort = 0; myRemoteTcpPortReallySet = false; + myBaud = NULL; + myAutoConn = NULL; + } + virtual ~BatteryData() {} + /// The number of this battery + int myNumber; + /// The actual pointer to this battery + ArBatteryMTX *myBattery; + // our connection + ArDeviceConnection *myConn; + // if we want to connect the battery + bool myConnect; + // if myConnect was really set + bool myConnectReallySet; + // the port we want to connect the battery on + const char *myPort; + // the type of port we want to connect to the battery on + const char *myPortType; + // battery Type + const char *myType; + // wheather to auto conn + const char *myAutoConn; + // battery tcp port if we're doing a remote host + int myRemoteTcpPort; + // if our remote battery tcp port was really set + bool myRemoteTcpPortReallySet; + /// the baud we want to use + const char *myBaud; +}; + std::map myBatteries; + + /// Parses the battery arguments + AREXPORT bool parseBatteryArgs(ArArgumentParser *parser, + BatteryData *batteryData); + /// Logs the battery command line option help text. + AREXPORT void logBatteryOptions(BatteryData *batterydata, bool header = true, bool metaOpts = true) const; + // Sets the battery parameters + bool internalConfigureBattery(BatteryData *batteryData); + + std::string myBatteryTypes; + + // our parser + ArArgumentParser *myParser; + bool myOwnParser; + // if we should autoparse args or toss errors + bool myAutoParseArgs; + bool myParsedArgs; + + ArRobot *myRobot; + ArRobotConnector *myRobotConnector; + + // variables to hold if we're logging or not + bool myBatteryLogPacketsReceived; + bool myBatteryLogPacketsSent; + + ArLog::LogLevel myInfoLogLevel; + + ArRetFunctorC myParseArgsCB; + ArConstFunctorC myLogOptionsCB; +}; + +#endif // ARLASERCONNECTOR_H diff --git a/Legacy/Aria/include/ArBatteryMTX.h b/Legacy/Aria/include/ArBatteryMTX.h new file mode 100644 index 0000000..232f73c --- /dev/null +++ b/Legacy/Aria/include/ArBatteryMTX.h @@ -0,0 +1,560 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARBATTERYMTX_H +#define ARBATTERYMTX_H + +#include "ariaTypedefs.h" +#include "ArRangeDevice.h" +#include "ArFunctor.h" +#include "ArRobot.h" +#include "ArRobotPacket.h" +#include "ArRobotConnector.h" + + + +// Packets are in the format of +// 2 bytes header (0xfa 0xba) +// 1 byte length +// 1 byte command +// xx bytes command specific / args +// 2 bytes checksum +// + + +/** + @since 2.8.0 +*/ +class ArBatteryMTX : public ArASyncTask +{ +public: + /// Constructor + AREXPORT ArBatteryMTX( + int batteryBoardNum = 0, + const char * name = "MTXBattery", + ArDeviceConnection *conn = NULL, + ArRobot *robot = NULL); + /// Destructor + AREXPORT virtual ~ArBatteryMTX(); + // Grabs the new readings from the robot and adds them to the buffers + // (Primarily for internal use.) + //AREXPORT void processReadings(void); + + int getBoardNum(void) + { return myBoardNum; } + + /// Sets the robot pointer, also attaches its process function to the + /// robot as a Sensor Interpretation task. + AREXPORT virtual void setRobot(ArRobot *robot); + + /// Very Internal call that gets the packet sender, shouldn't be used + ArRobotPacketSender *getPacketSender(void) + { return mySender; } + /// Very Internal call that gets the packet sender, shouldn't be used + ArRobotPacketReceiver *getPacketReceiver(void) + { return myReceiver; } + + /// Sets the device this instance receives packets from + AREXPORT void setDeviceConnection(ArDeviceConnection *conn); + /// Gets the device this instance receives packets from + AREXPORT ArDeviceConnection *getDeviceConnection(void); + + AREXPORT int getAsyncConnectState(void); + + ArRobotPacket getCellPacket() + { return myCellPacket; } + + AREXPORT virtual bool blockingConnect(bool sendTracking, bool recvTracking); + AREXPORT virtual bool disconnect(void); + virtual bool isConnected(void) { return myIsConnected; } + virtual bool isTryingToConnect(void) + { + if (myStartConnect) + return true; + else if (myTryingToConnect) + return true; + else + return false; + } + + /// Lock this device + virtual int lockDevice() { return(myDeviceMutex.lock());} + /// Try to lock this device + virtual int tryLockDevice() {return(myDeviceMutex.tryLock());} + /// Unlock this device + virtual int unlockDevice() {return(myDeviceMutex.unlock());} + + AREXPORT void logBatteryInfo(ArLog::LogLevel level = ArLog::Normal); + AREXPORT void logCellInfo(ArLog::LogLevel level = ArLog::Normal); + void log(ArLog::LogLevel level = ArLog::Normal) + { + logBatteryInfo(level); + logCellInfo(level); + } + + AREXPORT bool sendPowerOff(); + AREXPORT bool sendPowerOffCancel(); + AREXPORT bool sendStopCharging(); + AREXPORT bool sendStartCharging(); + AREXPORT bool sendSetPowerOffDelay(unsigned int msDelay); + AREXPORT bool sendSetRealTimeClock(unsigned int secSinceEpoch); + AREXPORT bool sendResetCellData(); + AREXPORT bool sendSetReserveValue(unsigned short hundredthOfPercent); + AREXPORT bool sendSetBalanceValue(unsigned short hundredthOfPercent); + AREXPORT bool sendEmergencyPowerOff(); + AREXPORT bool sendSystemInfo(unsigned char dataValue); + AREXPORT bool sendCellInfo(unsigned char dataValue); + AREXPORT bool sendBasicInfo(unsigned char dataValue); + + AREXPORT void updateSystemInfo(unsigned char *buf); + AREXPORT void updateCellInfo(unsigned char *buf); + AREXPORT void updateBasicInfo(unsigned char *buf); + + // need to figure out how to pass back the system and cell info + //AREXPORT bool fetchSystemInfo(); + //AREXPORT bool fetchCellInfo(); + + // basic info + /// Charge estimate (in percentage, 0-100) + double getChargeEstimate(void) const + { return myChargeEstimate; } + /// Current draw (amps, negative is charging) + double getCurrentDraw(void) const + { return myCurrentDraw; } + /// volts + double getPackVoltage(void) const + { return myPackVoltage; } + int getStatusFlags(void) const + { return myStatusFlags; } + int getErrorFlags(void) const + { return myErrorFlags; } + + bool onCharger(void) const + { return myOnCharger; } + ArRobot::ChargeState getChargeState(void) const + { return myChargeState; } + int getChargeStateAsInt(void) const + { return myChargeState; } + + // system info + int getId(void) const + { return myId; } + int getFirmwareVersion(void) const + { return myFirmwareVersion; } + int getSerialNumber(void) const + { return mySerialNumber; } + //int getCurrentTime(void) const + // { return myCurrentTime; } + long long getCurrentTime(void) const + { return myCurrentTime; } + long long getLastChargeTime(void) const + { return myLastChargeTime; } + int getChargeRemainingEstimate(void) const + { return myChargeRemainingEstimate; } + int getCapacityEstimate(void) const + { return myCapacityEstimate; } + double getDelay(void) const + { return myDelay; } + int getCycleCount(void) const + { return myCycleCount; } + double getTemperature(void) const + { return myTemperature; } + double getPaddleVolts(void) const + { return myPaddleVolts; } + double getVoltage(void) const + { return myVoltage; } + double getFuseVoltage(void) const + { return myFuseVoltage; } + double getChargeCurrent(void) const + { return myChargeCurrent; } + double getDisChargeCurrent(void) const + { return myDisChargeCurrent; } + double getCellImbalance(void) const + { return myCellImbalance; } + double getImbalanceQuality(void) const + { return myImbalanceQuality; } + double getReserveChargeValue(void) const + { return myReserveChargeValue; } + + // cell info + int getNumCells(void) const + { return myNumCells; } + + + int getCellFlag(int cellNum) const + { + std::map::const_iterator iter = + myCellNumToInfoMap.find(cellNum); + if (iter == myCellNumToInfoMap.end()) + return -1; + else { + CellInfo *info = iter->second; + return(info->myCellFlags); + } } + + int getCellCapacity(int cellNum) const + { + std::map::const_iterator iter = + myCellNumToInfoMap.find(cellNum); + if (iter == myCellNumToInfoMap.end()) + return -1; + else { + CellInfo *info = iter->second; + return(info->myCellCapacity); + } } + + int getCellCharge(int cellNum) const + { + std::map::const_iterator iter = + myCellNumToInfoMap.find(cellNum); + if (iter == myCellNumToInfoMap.end()) + return -1; + else { + CellInfo *info = iter->second; + return(info->myCellCharge); + } } + + double getCellVoltage(int cellNum) const + { + std::map::const_iterator iter = + myCellNumToInfoMap.find(cellNum); + if (iter == myCellNumToInfoMap.end()) + return -1; + else { + CellInfo *info = iter->second; + return(info->myCellVoltage); + } } + + /// Request a continous stream of packets + AREXPORT void requestContinuousSysInfoPackets(void); + /// Stop the stream of packets + AREXPORT void stopSysInfoPackets(void); + /// See if we've requested packets + AREXPORT bool haveRequestedSysInfoPackets(void); + + /// Request a continous stream of packets + AREXPORT void requestContinuousCellInfoPackets(void); + /// Stop the stream of packets + AREXPORT void stopCellInfoPackets(void); + /// See if we've requested packets + AREXPORT bool haveRequestedCellInfoPackets(void); + + AREXPORT virtual const char *getName(void) const; + + void setInfoLogLevel(ArLog::LogLevel infoLogLevel) + { myInfoLogLevel = infoLogLevel; } + + /// Gets the default port type for the battery + const char *getDefaultPortType(void) { return myDefaultPortType.c_str(); } + + /// Gets the default port type for the battery + const char *getDefaultTcpPort(void) { return myDefaultTcpPort.c_str(); } + + /// Sets the numter of seconds without a response until connection assumed lost + virtual void setConnectionTimeoutSeconds(double seconds) + { ArLog::log(ArLog::Normal, + "%s::setConnectionTimeoutSeconds: Setting timeout to %g secs", + getName(), seconds); + myTimeoutSeconds = seconds; } + /// Gets the number of seconds without a response until connection assumed lost + virtual double getConnectionTimeoutSeconds(void) + {return myTimeoutSeconds; } + /// check for lost connections + AREXPORT bool checkLostConnection(void); + /// disconnect + AREXPORT void disconnectOnError(void); + /// Gets the time data was last receieved + ArTime getLastReadingTime(void) { return myLastReading; } + /// Gets the number of battery readings received in the last second + AREXPORT int getReadingCount(void); + // Function called in sensorInterp to indicate that a + // reading was received + AREXPORT virtual void internalGotReading(void); + + /// Adds a callback for when disconnection happens because of an error + void addDisconnectOnErrorCB(ArFunctor *functor, + int position = 51) + { myDisconnectOnErrorCBList.addCallback(functor, position); } + + /// Removes a callback for when disconnection happens because of an error + void remDisconnectOnErrorCB(ArFunctor *functor) + { myDisconnectOnErrorCBList.remCallback(functor); } + + + /// Adds a callback for when the battery is powering off + void addBatteryPoweringOffCB(ArFunctor *functor, + int position = 51) + { myBatteryPoweringOffCBList.addCallback(functor, position); } + + /// Removes a callback for when the battery is powering off + void remBatteryPoweringOffCB(ArFunctor *functor) + { myBatteryPoweringOffCBList.remCallback(functor); } + + /// Adds a callback for when the battery is powering off + void addBatteryPoweringOffCancelledCB(ArFunctor *functor, + int position = 51) + { myBatteryPoweringOffCancelledCBList.addCallback(functor, position); } + + /// Removes a callback for when the battery is powering off + void remBatteryPoweringOffCancelledCB(ArFunctor *functor) + { myBatteryPoweringOffCancelledCBList.remCallback(functor); } + + // myStatusFlags + enum StatusFlags { + STATUS_ON_CHARGER=0x0001, + STATUS_CHARGING=0x0002, + STATUS_BALANCING_ENGAGED=0x0004, + STATUS_CHARGER_ON=0x0008, + STATUS_BATTERY_POWERING_OFF=0x0010, + STATUS_MASTER_SWITCH_ON=0x0020, + STATUS_CHARGE_SWITCH_ON=0x0040, + STATUS_COMMANDED_SHUTDOWN=0x0080, + STATUS_OFF_BUTTON_PRESSED=0x0100, + STATUS_ON_BUTTON_PRESSED=0x0200, + STATUS_USER_BUTTON_PRESSED=0x0400 + }; + + // myErrorFlags (if this is updated also change the code in interpBasicInfo + enum ErrorFlags { + ERROR_BATTERY_OVERVOLTAGE=0x0001, + ERROR_BATTERY_UNDERVOLTAGE=0x0002, + ERROR_OVERCURRENT=0x0004, + ERROR_BLOWNFUSE=0x0008, + ERROR_RTC_ERROR=0x0010, + ERROR_OVER_TEMPERATURE=0x0020, + ERROR_MASTER_SWITCH_FAULT=0x0040, + ERROR_SRAM_ERROR=0x0080, + ERROR_CHARGER_OUT_OF_VOLTAGE_RANGE=0x0100, + ERROR_CHARGER_CIRCUIT_FAULT=0x0200 + }; + +enum Headers { + HEADER1=0xfa, + HEADER2=0xba + }; + + +protected: + ArDeviceConnection *myConn; + int myAsyncConnectState; + std::string myName; + std::string myDefaultPortType; + std::string myDefaultTcpPort; + + double myTimeoutSeconds; + bool myRobotRunningAndConnected; + + ArTime myLastReading; + + // packet count + time_t myTimeLastReading; + int myReadingCurrentCount; + int myReadingCount; + + ArCallbackList myDisconnectOnErrorCBList; + ArCallbackList myBatteryPoweringOffCBList; + ArCallbackList myBatteryPoweringOffCancelledCBList; + + ArRobot *myRobot; + ArFunctorC myProcessCB; + + AREXPORT virtual void batterySetName(const char *name); + AREXPORT virtual void * runThread(void *arg); + + + AREXPORT bool getSystemInfo(); + AREXPORT bool getCellInfo(); + AREXPORT bool getBasicInfo(); + + void interpBasicInfo(void); + void interpErrors(void); + void checkAndSetCurrentErrors(ErrorFlags errorFlag, const char *errorString); + + // PS - need this because of debug log - battery won't send continuous cell + ArRobotPacket myCellPacket; + + void sensorInterp(void); + void failedToConnect(void); + void clear(void); + bool myIsConnected; + bool myTryingToConnect; + bool myStartConnect; + + bool myOnCharger; + ArRobot::ChargeState myChargeState; + + int myBoardNum; + unsigned char myVersion; + + ArLog::LogLevel myLogLevel; + + //ArBatteryMTXPacketReceiver myReceiver; + + + ArRobotPacketReceiver *myReceiver; + ArRobotPacketSender *mySender; + + ArMutex myPacketsMutex; + ArMutex myDataMutex; + ArMutex myDeviceMutex; + + ArLog::LogLevel myInfoLogLevel; + + //std::list myPackets; + std::list myPackets; + + ArTime myPrevBatteryIntTime; + + bool myRequestedSysInfoBatteryPackets; + bool myRequestedCellInfoBatteryPackets; + + bool mySendTracking; + bool myRecvTracking; + +// Protocol Commands + + +enum Commands { + BASIC_INFO=0x00, + SYSTEM_INFO=0x01, + CELL_INFO=0x02, + POWER_OFF_REQUEST=0x10, + POWER_OFF_CANCEL=0x11, + STOP_CHARGING=0x12, + START_CHARGING=0x13, + SET_POWER_OFF_DELAY=0x20, + SET_REAL_TIME_CLOCK=0x21, + RESET_CELL_DATA=0x22, + SET_RESERVE_VALUE=0x23, + SET_BALANCE_VALUE=0x24, + EMERGENCY_OFF=0xff + }; + +// SYSTEM_INFO and CELL_INFO Data +enum Data { + STOP_SENDING=0x00, + SEND_ONCE=0x01, + SEND_CONTINUOUS=0x02 + }; + +// Length fields - +enum Sizes { + BASIC_INFO_SIZE=16, + SYSTEM_INFO_SIZE=60, + CELL_INFO_SIZE=95 // this is for 8 cells + }; + + // System Info + unsigned char myId; + unsigned char myFirmwareVersion; + unsigned int mySerialNumber; + long long myCurrentTime; + //unsigned int myCurrentTime; + //unsigned int myLastChargeTime; + long long myLastChargeTime; + unsigned int myChargeRemainingEstimate; + unsigned int myCapacityEstimate; + unsigned int myRawDelay; + double myDelay; + unsigned int myCycleCount; + unsigned short myRawTemperature; + double myTemperature; + unsigned short myRawPaddleVolts; + double myPaddleVolts; + unsigned short myRawVoltage; + double myVoltage; + unsigned short myRawFuseVoltage; + double myFuseVoltage; + unsigned short myRawChargeCurrent; + double myChargeCurrent; + unsigned short myRawDisChargeCurrent; + double myDisChargeCurrent; + unsigned short myRawCellImbalance; + double myCellImbalance; + unsigned short myRawImbalanceQuality; + double myImbalanceQuality; + unsigned short myRawReserveChargeValue; + double myReserveChargeValue; + + // end system info + + // Cell Info + + // myCellFlags defines + + enum CellFlags { + BALANCER_IS_ON=0x01, + OVER_VOLTAGE=0x02, + UNDER_VOLTAGE=0x04 + }; + + + struct CellInfo { + unsigned char myCellFlags; + unsigned short myRawCellVoltage; + double myCellVoltage; + unsigned short myCellCharge; + unsigned short myCellCapacity; + }; + + unsigned char myNumCells; + std::map myCellNumToInfoMap; + + // end cell info + + // Basic Info + + unsigned short myRawChargeEstimate; + double myChargeEstimate; + unsigned short myRawCurrentDraw; + double myCurrentDraw; + unsigned short myRawPackVoltage; + double myPackVoltage; + unsigned short myStatusFlags; + unsigned short myErrorFlags; + + bool myHaveSetRTC; + + int myLastStatusFlags; + + bool myFirstErrorFlagsCheck; + unsigned short myLastErrorFlags; + std::string myErrorString; + int myErrorCount; + std::string myLastErrorString; + int myLastErrorCount; + + + + // end basic info + + ArFunctorC mySensorInterpTask; + ArRetFunctorC myAriaExitCB; + +}; + + + +#endif // ARBATTERYMTX_H diff --git a/Legacy/Aria/include/ArBumpers.h b/Legacy/Aria/include/ArBumpers.h new file mode 100644 index 0000000..1948c28 --- /dev/null +++ b/Legacy/Aria/include/ArBumpers.h @@ -0,0 +1,64 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARBUMPERS_H +#define ARBUMPERS_H + +#include "ariaTypedefs.h" +#include "ArRangeDevice.h" + + +/// A class that treats the robot's bumpers as a range device. +/** + The class treats bumpers like a range device. When a bumper + is bumped, it reports the approximate position of the bump + in a buffer. The positions are kept current for a specified + length of time. + + @ingroup DeviceClasses +*/ +class ArBumpers : public ArRangeDevice +{ +public: + AREXPORT ArBumpers(size_t currentBufferSize = 30, + size_t cumulativeBufferSize = 30, + const char *name = "bumpers", + int maxSecondsToKeepCurrent = 15, + double angleRange = 135); + AREXPORT virtual ~ArBumpers(void); + + AREXPORT virtual void setRobot(ArRobot *robot); + AREXPORT void processReadings(void); + AREXPORT void addBumpToBuffer(int bumpValue, int whichBumper); + +protected: + ArFunctorC myProcessCB; + ArRobot *myRobot; + int myBumpMask; + double myAngleRange; +}; + + +#endif // ARBUMPERS_H diff --git a/Legacy/Aria/include/ArCameraCollection.h b/Legacy/Aria/include/ArCameraCollection.h new file mode 100644 index 0000000..41c609d --- /dev/null +++ b/Legacy/Aria/include/ArCameraCollection.h @@ -0,0 +1,506 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARCAMERACOLLECTION_H +#define ARCAMERACOLLECTION_H + +#include +#include +#include + +#include "ArConfigArg.h" +#include "ArFunctor.h" +#include "ArMutex.h" + +class ArCameraCollectionItem; +class ArCameraParameterSource; + +/// Maintains information about all of the robot's cameras. +/** + * ArCameraCollection is a repository for information about each of the + * cameras that are installed on the robot. It enables clients to adjust + * to robots with varying camera configurations. + *

+ * Three main types of information are maintained for each camera: + *

    + *
  • Overview Information: This includes the name and type of the camera, + * along with text strings suitable for display. Note that each camera + * must be assigned a unique name. Furthermore, the overview information + * must be added to the collection before any of the other types of + * information are added.
  • + * + *
  • Command Information: Each camera may respond to any number + * of generic commands (such as pan/tilt/zoom, or get camera picture). + * The command information defines which commands are supported for + * each camera, and also defines a unique "camera command name" for + * each generic command. (The "camera command name", for example, + * may be used as a network packet name. It must be unique across + * all of the robot's cameras.) Commands which are commonly + * supported are defined in ArCameraCommands, but additional ones may + * be added.
  • + * + *
  • Parameter Information: Parameters, or settings, may be defined + * for each camera. A framework has been built into the collection to + * allow clients to view/edit the parameters. Changes are relayed to + * the originator (source) of the parameter, which is responsible for + * actually adjusting the camera hardware.
  • + *
+ *

+ * Callbacks may be installed on the collection to be notified whenever + * the collection is modified. This notification only occurs when + * cameras, commands, or parameters are added or removed. (The editing + * of parameters is merely passed to the parameter source.) + *

+ * ArCameraCollection is thread-safe. + + @ingroup OptionalClasses +**/ +class ArCameraCollection +{ +public: + + /// Constructor + AREXPORT ArCameraCollection(); + + /// Destructor + AREXPORT virtual ~ArCameraCollection(); + + // --------------------------------------------------------------------------- + + /// Adds a new camera to the collection. + /** + * @param cameraName the char * name of the camera; must be unique + * and non-NULL + * @param cameraType the char * type of the camera (e.g. VCC4 or Omni) + * @param displayName the char * string to be displayed for the + * camera name; if NULL, then the cameraName is used instead + * @param displayType the char * string to be displayed for the + * camera type; if NULL, then the cameraType is used instead + * @return bool true if the camera was successfully added; false, + * otherwise. + **/ + AREXPORT virtual bool addCamera(const char *cameraName, + const char *cameraType, + const char *displayName, + const char *displayType); + + /// Removes the specified camera from the collection. + /** + * @param cameraName the char * name of the camera to be removed + * @return bool true if the camera was successfully removed; false, + * otherwise. + **/ + AREXPORT virtual bool removeCamera(const char *cameraName); + + /// Adds the specified command to the camera. + /** + * @param cameraName the char * name of the camera to which the + * command is to be added. The camera must have already been + * installed in the collection via the addCamera() method. + * @param command the char * identifier of the command that is being + * added. Common commands (currently recognized by MobileEyes) + * are defined in ArCameraCommands. + * @param cameraCommandName the corresponding char * command + * (i.e. network packet) name that is actually handled by the + * camera. The cameraCommandName must be non-NULL and unique + * across all robot cameras. + * @param requestInterval the int number of milliseconds between + * client requests for repeating commands; if -1, then the + * command is not repeating. + * @return bool true if the command was successfully added; + * false if an error occurred. + **/ + AREXPORT virtual bool addCameraCommand(const char *cameraName, + const char *command, + const char *cameraCommandName, + int requestInterval = -1); + + + /// Removes the specified command from the camera. + /** + * @param cameraName the char * name of the camera from which the + * command is to be removed. + * @param command the char * identifier of the command that is being + * removed. + * @return bool true if the command was successfully removed; + * false if an error occurred. + **/ + AREXPORT virtual bool removeCameraCommand(const char *cameraName, + const char *command); + + + /// Adds the specified parameter to the camera. + /** + * @param cameraName the char * name of the camera to which the + * parameter is to be added. The camera must have already been + * installed in the collection via the addCamera() method. + * @param source the ArCameraParameterSource * that is to be notified + * when the parameter value is changed; if NULL, then no notification + * @param param the ArConfigArg parameter to be added; the parameter + * name must be unique for this camera. (Parameter names may be + * reused across different cameras though.) + * @return bool true if the parameter was successfully added to the + * camera; false if an error occurred + **/ + AREXPORT virtual bool addParameter(const char *cameraName, + ArCameraParameterSource *source, + const ArConfigArg ¶m); + + + /// Removes the specified parameter from the camera. + /** + * @param cameraName the char * name of the camera from which the + * parameter is to be removed. + * @param paramName the char * name of the parameter to be removed + * @return bool true if the parameter was successfully removed from the + * camera; false if an error occurred + **/ + AREXPORT virtual bool removeParameter(const char *cameraName, + const char *paramName); + + // --------------------------------------------------------------------------- + + /// Returns the names of the cameras that are in the collection. + /** + * @param outList the std::list into which the names are output; + * any previous contents of the outList are cleared. + **/ + AREXPORT virtual void getCameraNames(std::list &outList); + + + /// Returns the type of the specified camera. + /** + * @param cameraName the unique char * name of the camera + * @return char * the type of the specified camera; NULL if the camera was + * not found in the collection + **/ + AREXPORT virtual const char *getCameraType(const char *cameraName); + + /// Returns the display name of the specified camera. + /** + * @param cameraName the unique char * name of the camera + * @return char * the string to be displayed as the name of the specified camera; + * NULL if the camera was not found in the collection + **/ + AREXPORT virtual const char *getDisplayName(const char *cameraName); + + /// Returns the display type of the specified camera. + /** + * @param cameraName the unique char * name of the camera + * @return char * the string to be displayed as the type of the specified camera; + * NULL if the camera was not found in the collection + **/ + AREXPORT virtual const char *getDisplayType(const char *cameraName); + + // --------------------------------------------------------------------------- + + /// Returns the generic commands that are supported by the specified camera. + /** + * @param cameraName the unique char * name of the camera + * @param outList the std::list into which the commands are output; + * any previous contents of the outList are cleared. + **/ + AREXPORT virtual void getCameraCommands(const char *cameraName, + std::list &outList); + + /// Returns the specific camera command (/ network packet) name for the generic command. + /** + * @param cameraName the unique char * name of the camera + * @param command the char * name of the generic command to be retrieved + * @return char * the unique command (or network packet) name for the generic + * command on the specified camera; NULL, if the camera does not support the + * generic command + **/ + AREXPORT virtual const char *getCommandName(const char *cameraName, + const char *command); + + /// Returns the default request interval for the specified camera command. + /** + * @param cameraName the unique char * name of the camera + * @param command the char * name of the generic command + * @return int the default number of milliseconds between command requests; + * if -1, then the command is not for refreshing data + **/ + AREXPORT virtual int getRequestInterval(const char *cameraName, + const char *command); + + // --------------------------------------------------------------------------- + + /// Returns the names of the parameters for the specified camera. + /** + * @param cameraName the unique char * name of the camera + * @param outList the std::list into which the parameter names are + * output; any previous contents of the outList are cleared. + **/ + AREXPORT virtual void getParameterNames(const char *cameraName, + std::list &outList); + + /// Returns the specified camera parameter. + /** + * @param cameraName the unique char * name of the camera + * @param parameterName the unique char * name of the parameter to be retrieved + * @param paramOut the ArConfigArg into which the parameter is copied + * @return bool true if the parameter was successfully found; false, otherwise. + **/ + AREXPORT virtual bool getParameter(const char *cameraName, + const char *parameterName, + ArConfigArg ¶mOut); + + /// Updates the specified camera parameter. + /** + * @param cameraName the unique char * name of the camera + * @param param the ArConfigArg to be set; the parameter must have been + * previously added to the camera with the addParameter() method + * @return bool true if the parameter was found and set; false, otherwise. + **/ + AREXPORT virtual bool setParameter(const char *cameraName, + const ArConfigArg ¶m); + + // --------------------------------------------------------------------------- + + /// Returns whether the specified camera is contained in the collection. + AREXPORT virtual bool exists(const char *cameraName); + + /// Returns whether the specified command is defined for a particular camera. + AREXPORT virtual bool exists(const char *cameraName, + const char *command); + + /// Returns whether the specified parameter has been defined for a particular camera. + AREXPORT virtual bool parameterExists(const char *cameraName, + const char *paramName); + + // --------------------------------------------------------------------------- + + /// Adds a callback to be invoked when the camera collection has been modified. + /** + * @param functor the ArFunctor * to be invoked when the collection has been + * modified; must be non-NULL + * @param position the ArListPos::Pos at which to put the callback + * (beginning or end) + * @return bool true if the callback was succesfully added; false, otherwise. + **/ + AREXPORT virtual bool addModifiedCB(ArFunctor *functor, + ArListPos::Pos position = ArListPos::LAST); + + /// Removes a callback from the modified notification list. + /** + * @param functor the ArFunctor * to be removed from the notification list + * @return bool true if the callback was succesfully removed; false, otherwise. + **/ + AREXPORT virtual bool removeModifiedCB(ArFunctor *functor); + + + /// Starts an update to the collection. + /** + * This method may be used when multiple changes are being made to the collection. + * While an update is in progress, the modified callbacks will not be invoked. + * The endUpdate() method should be called after all of the changes are complete + * (and then the modified callbacks will be invoked). + **/ + AREXPORT virtual void startUpdate(); + + /// Ends an update to the collection. + /** + * A call to startUpdate() must eventually be followed by a call to endUpdate(). + **/ + AREXPORT virtual void endUpdate(); + + + // --------------------------------------------------------------------------- + + /// Lock the collection + int lock() { + return (myMutex.lock()); + } + + /// Try to lock the collection without blocking + int tryLock() { + return(myMutex.tryLock()); + } + + /// Unlock the collection + int unlock() { + return(myMutex.unlock()); + } + + +// ----------------------------------------------------------------------------- +protected: + + /// Information regarding a particular camera command. + struct CommandInfo { + + /// Generic name of the command. + std::string myCommand; + /// Unique name of the corresponding command (or packet) for this camera. + std::string myCameraCommandName; + /// Default number of milliseconds between command requests. + int myRequestInterval; + + /// Constructor + CommandInfo(); + /// Destructor + ~CommandInfo(); + + }; // end struct CommandInfo + + + /// Information regarding a particular camera parameter. + struct ParamInfo { + + /// Source of the parameter (to be notified when the parameter changes) + ArCameraParameterSource *mySource; + /// The parameter + ArConfigArg myParam; + + /// Constructor + ParamInfo(); + /// Destructor + ~ParamInfo(); + + }; // end struct ParamInfo + + + /// Information regarding a single camera. + struct CameraInfo { + + /// Unique name of the camera + std::string myCameraName; + /// Type of the camera + std::string myCameraType; + /// String displayed for the name of the camera + std::string myDisplayName; + /// String displayed for the type of the camera + std::string myDisplayType; + /// Map of generic command names to the specific camera command info + std::map myCommandToInfoMap; + /// Map of parameter names to the related info (including the actual parameter value) + std::map myParamToInfoMap; + + /// Constructor + CameraInfo(); + /// Destructor + ~CameraInfo(); + + }; // end struct CameraInfo + + + /// Returns a pointer to the CameraInfo for the specified camera. + CameraInfo *findCameraInfo(const char *cameraName); + + /// Returns a pointer to the CommandInfo for the specified generic command. + CommandInfo *findCommandInfo(const char *cameraName, + const char *commandName); + + /// Returns a pointer to the ParamInfo for the specified parameter. + ParamInfo *findParamInfo(const char *cameraName, + const char *paramName); + + /// Sets an indication that the collection has been modified. + void setModified(); + + /// Invokes each of the callbacks when the collection has been modified. + void notifyModifiedListeners(); + +private: + /// Disabled copy ctor + ArCameraCollection(const ArCameraCollection &); + /// Disabled assignment operator + ArCameraCollection &operator=(const ArCameraCollection &); + +protected: + + /// Mutex for multi-threaded access + ArMutex myMutex; + /// Map of camera names to the associated camera information + std::map myCameraToInfoMap; + /// Whether updates are currently enabled + bool myIsUpdatesEnabled; + /// Whether the collection has been modified (since the last notification) + bool myIsModified; + /// List of callbacks to be notified when the collection is modified + std::list myModifiedCBList; + +}; // end class ArCameraCollection + +// ----------------------------------------------------------------------------- + +/// Interface for items that add information to the camera collection. +/** + * ArCameraCollectionItem is a simple interface whose primary purpose is to + * identify classes that support some aspect of a camera's functionality. + * It defines two methods: one to identify the associated camera, and one + * that adds the information about the supported functionality to the collection. + * (Note that the addToCameraCollection() method is not automatically invoked. + * Its only purpose in life is to suggest consistency between different items.) +**/ +class ArCameraCollectionItem +{ +public: + + /// Constructor + ArCameraCollectionItem() {}; + /// Destructor + virtual ~ArCameraCollectionItem() {}; + + /// Returns the name of the camera handled by this item. + virtual const char *getCameraName() = 0; + + /// Adds this item to the given camera collection. + virtual void addToCameraCollection(ArCameraCollection &collection) = 0; + +}; // end class ArCameraCollectionItem + +// ----------------------------------------------------------------------------- + +/// Interface for collection items that also access the camera's parameters. +/** + * ArCameraParameterSource is a special collection item that provides the ability + * to read and modify some of the camera's parameters. In general, the + * addToCameraCollection() method should add the parameters to the collection. + * The collection will then invoke the getParameter() and setParameter() methods as + * callers make changes to the parameters; the ArCameraParameterSource is reponsible + * for propagating the changes to the camera hardware. +**/ +class ArCameraParameterSource : public ArCameraCollectionItem +{ +public: + + /// Constructor + ArCameraParameterSource() {}; + /// Destructor + ~ArCameraParameterSource() {}; + + /// Gets the specified camera parameter. + virtual bool getParameter(const char *paramName, + ArConfigArg ¶mOut) = 0; + + /// Sets the given camera parameter. + virtual bool setParameter(const ArConfigArg ¶m) = 0; + +}; // end class ArCameraParameterSource + + +#endif // ARCAMERACOLLECTION_H diff --git a/Legacy/Aria/include/ArCameraCommands.h b/Legacy/Aria/include/ArCameraCommands.h new file mode 100644 index 0000000..faf01f4 --- /dev/null +++ b/Legacy/Aria/include/ArCameraCommands.h @@ -0,0 +1,167 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARCAMERACOMMANDS_H +#define ARCAMERACOMMANDS_H + +#include "ariaUtil.h" + +/// Commands that are supported by the camera (ArPTZ) and video classes. +/** + * ArCameraCommands defines the commands that are commonly supported by + * the Aria camera and video classes. The commands that are actually + * supported for a particular camera are specified in the ArCameraCollection. + *

+ * There are basically two classes of commands: + *

    + *
  1. Double Format Commands: These commands use the new double interface + * to the Aria camera classes. They are generally preferred for future + * development since they provide finer control over the camera movements. + * In addition, only these commands will work correctly in a multi-camera + * configuration.
  2. + * + *
  3. Integer Format Commands: These commands are maintained for backwards + * compatibility. They will not work correctly in a multi-camera + * configuration. (Only the first camera will be used.)
  4. + *
+ * +**/ +class ArCameraCommands +{ +public: + + // --------------------------------------------------------------------------- + // Double Format Commands + // --------------------------------------------------------------------------- + + /// Returns the current pan/tilt/zoom of the camera (in double format). + AREXPORT static const char *GET_CAMERA_DATA; + + /// Returns general information about the camera (in double format). + /** + * General information about the camera includes the pan/tilt/zoom ranges + * and whether zooming is available. In general, clients need only + * to request this data once at startup. + **/ + AREXPORT static const char *GET_CAMERA_INFO; + + /// Returns the last image obtained from the camera. + AREXPORT static const char *GET_PICTURE; + + /// Returns the last image obtained from the camera. + AREXPORT static const char *GET_PICTURE_OPTIM; + + /// Returns a high resolution image from the camera, suitable for saving. + /** + * This command is not yet fully supported. + **/ + AREXPORT static const char *GET_SNAPSHOT; + + /// Returns whether the camera/image should be displayed by the client. + /** + * This command is not yet fully supported. + **/ + AREXPORT static const char *GET_DISPLAY; + + + /// Sends a command to the camera to set its pan/tilt/zoom, in absolute terms (in double format). + AREXPORT static const char *SET_CAMERA_ABS; + + /// Sends a command to the camera to set its pan/tilt, as specified by a percent offset of its current frame. + AREXPORT static const char *SET_CAMERA_PCT; + + /// Sends a command to the camera to set its pan/tilt/zoom, relative to its current position (in double format). + AREXPORT static const char *SET_CAMERA_REL; + + /// Sends a packet back with the list of modes + AREXPORT static const char *GET_CAMERA_MODE_LIST; + + /// A packet that gets sent out when the mode is changed + /** + Note that each mode might have arguments after it for just that + mode, so only the mode name at the start is generic. + **/ + AREXPORT static const char *CAMERA_MODE_UPDATED; + + /// A command that sets the mode of the camera + /** + Note that each mode can have its own arguments so only the mode + name at the start is generic. + **/ + AREXPORT static const char *SET_CAMERA_MODE; + + /// A command that resets the camera + AREXPORT static const char *RESET_CAMERA; + + // --------------------------------------------------------------------------- + // Integer Format Commands + // The following commands are maintained solely for backwards-compatibility. + // --------------------------------------------------------------------------- + + + /// Returns the current pan/tilt/zoom of the camera (as byte2 integers). + /** + * @deprecated GET_CAMERA_DATA is preferred instead + **/ + AREXPORT static const char *GET_CAMERA_DATA_INT; + + /// Returns general information about the camera (as byte2 integers). + /** + * @deprecated GET_CAMERA_INFO is preferred instead + **/ + AREXPORT static const char *GET_CAMERA_INFO_INT; + + /// Sends a command to the camera to set its pan/tilt/zoom, in absolute terms (as byte integers). + /** + * @deprecated SET_CAMERA_ABS is preferred instead + **/ + AREXPORT static const char *SET_CAMERA_ABS_INT; + + /// Sends a command to the camera to set its pan/tilt/zoom, relative to its current position (as byte integers). + /** + * @deprecated SET_CAMERA_REL is preferred instead + **/ + AREXPORT static const char *SET_CAMERA_REL_INT; + + /// Sends a command to the camera to set its pan/tilt, as specified by a percent offset (as byte integers). + /** + * @deprecated SET_CAMERA_PCT is preferred instead + **/ + AREXPORT static const char *SET_CAMERA_PCT_INT; + + /** + * @deprecated GET_PICTURE is preferred instead + **/ + AREXPORT static const char *GET_VIDEO; + + /** + * @deprecated GET_SNAPSHOT is preferred instead + **/ + AREXPORT static const char *GET_SNAPSHOT_PLAIN; + +}; // end class ArCameraCommands + +#endif // ARCAMERACOMMANDS_H + diff --git a/Legacy/Aria/include/ArCommands.h b/Legacy/Aria/include/ArCommands.h new file mode 100644 index 0000000..5734aac --- /dev/null +++ b/Legacy/Aria/include/ArCommands.h @@ -0,0 +1,172 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARCOMMANDS_H +#define ARCOMMANDS_H + +/// A class containing names for most robot microcontroller system commands +/** + A class with an enum of the commands that can be sent to the robot, see the + robot operations manual for more detailed descriptions. + @ingroup OptionalClasses +*/ +class ArCommands +{ +public: + enum Commands { + PULSE = 0, ///< none, keep alive command, so watchdog doesn't trigger + OPEN = 1, ///< none, sent after connection to initiate connection + CLOSE = 2, ///< none, sent to close the connection to the robot + POLLING = 3, ///< string, string that sets sonar polling sequence + ENABLE = 4, ///< int, enable (1) or disable (0) motors + SETA = 5, ///< int, sets translational accel (+) or decel (-) (mm/sec/sec) + SETV = 6, ///< int, sets maximum velocity (mm/sec) + SETO = 7, ///< int, resets robots origin back to 0, 0, 0 + MOVE = 8, ///< int, translational move (mm) + ROTATE = 9, ///< int, set rotational velocity, duplicate of RVEL (deg/sec) + SETRV = 10, ///< int, sets the maximum rotational velocity (deg/sec) + VEL = 11, ///< int, set the translational velocity (mm/sec) + HEAD = 12, ///< int, turn to absolute heading 0-359 (degrees) + DHEAD = 13, ///< int, turn relative to current heading (degrees) + //DROTATE = 14, does not really exist + SAY = 15, /**< string, makes the robot beep. + up to 20 pairs of duration (20 ms incrs) and tones (halfcycle) */ + JOYINFO = 17, // int, requests joystick packet, 0 to stop, 1 for 1, 2 for continuous + CONFIG = 18, ///< int, request configuration packet + ENCODER = 19, ///< int, > 0 to request continous stream of packets, 0 to stop + SETRVDIR = 20, ///< int, Sets the rot vel max in each direction + RVEL = 21, ///< int, set rotational velocity (deg/sec) + DCHEAD = 22, ///< int, colbert relative heading setpoint (degrees) + SETRA = 23, ///< int, sets rotational accel(+) or decel(-) (deg/sec) + SONAR = 28, ///< int, enable (1) or disable (0) sonar + STOP = 29, ///< int, stops the robot + DIGOUT = 30, ///< int, sets the digout lines + //TIMER = 31, ... no clue about this one + VEL2 = 32, /**< int, independent wheel velocities, + first 8 bits = right, second 8 bits = left, multiplied by Vel2 divisor. See manual. */ + GRIPPER = 33, ///< int, gripper server command, see gripper manual for detail + //KICK = 34, um... + ADSEL = 35, ///< int, select the port given as argument + GRIPPERVAL = 36, ///< p2 gripper server value, see gripper manual for details + GRIPPERPACREQUEST = 37, ///< p2 gripper packet request + IOREQUEST = 40, ///< request iopackets from p2os + PTUPOS = 41, ///< most-sig byte is port number, least-sig byte is pulse width + TTY2 = 42, ///< string, send string argument to serial dev connected to aux1 + GETAUX = 43, ///< int, requests 1-200 bytes from aux1 serial channel, 0 flush + BUMPSTALL = 44, /**< int, stop and register a stall if front (1), rear (2), + or both (3) bump rings are triggered, Off (default) is 0 */ + TCM2 = 45, ///< TCM2 module commands, see tcm2 manual for details + JOYDRIVE = 47, /**< Command to tell p2os to drive with the joystick + plugged into the robot */ + MOVINGBLINK = 49, ///< int, 1 to blink lamp quickly before moving, 0 not to (for patrolbot) + HOSTBAUD = 50, ///< int, set baud rate for host port - 0=9600, 1=19200, 2=38400, 3=57600, 4=115200 + AUX1BAUD = 51, ///< int, set baud rate for Aux1 - 0=9600, 1=19200, 2=38400, 3=57600, 4=115200 + AUX2BAUD = 52, ///< int, set baud rate for Aux2 - 0=9600, 1=19200, 2=38400, 3=57600, 4=115200 + ESTOP = 55, ///< none, emergency stop, overrides decel + ESTALL = 56, // ? + GYRO = 58, ///< int, set to 1 to enable gyro packets, 0 to disable + TTY4 = 60, + GETAUX3 = 61, + BATTERYINFO = 62, ///< int, requests battery info packets, 0 to stop, 1 for 1, 2 for continuous + TTY3 = 66, + GETAUX2 = 67, + BATTEST = 250, + + // SRISIM specific: + LOADPARAM = 61, ///< @deprecated only supported by SRISim. Conflicts with GETAUX3 + OLDSIM_LOADPARAM = 61, ///< @deprecated only supported by SRISim. Conflicts with GETAUX3 + ENDSIM = 62, ///< @deprecated use SIM_EXIT + OLDSIM_EXIT = 62, ///< @deprecated use SIM_EXIT + LOADWORLD = 63, ///< @deprecated only supported by SRISim + OLDSIM_LOADWORLD = 63, ///< @deprecated only supported by SRISim + STEP = 64, ///< @deprecated only supported by SRISim + OLDSIM_STEP = 64, ///< @deprecated only supported by SRISim + + // for calibrating the compass: + CALCOMP = 65, ///< int, commands for calibrating compass, see compass manual + + // SRISIM specific: + // SETORIGINX and SETORIGINY overlap with TTY3 and GETAUX2 so they are disabled: + //SETSIMORIGINX = 66, + //SETSIMORIGINY = 67, + //OLDSIM_SETORIGINX = 66, + //OLDSIM_SETORIGINY = 67, + SETSIMORIGINTH = 68, ///< @deprecated use SIM_SET_POSE + OLDSIM_SETORIGINTH = 68, ///< @deprecated use SIM_SET_POSE + RESETSIMTOORIGIN = 69, ///< @deprecated use SIM_RESET + OLDSIM_RESETTOORIGIN = 69, ///< @deprecated use SIM_RESET + + // AmigoBot-H8 specific: + SOUND = 90, ///< int, AmigoBot (old H8 model) specific, plays sound with given number + PLAYLIST = 91, /**< int, AmigoBot (old H8 model) specific, requests name of sound, + 0 for all, otherwise for specific sound */ + SOUNDTOG = 92, ///< int, AmigoBot (old H8 model) specific, enable(1) or diable(0) sound + + // Power commands + POWER_PC = 95, ///< int, Powers on or off the PC (if the firwmare is set up to do this in its power settings) + POWER_LRF = 96, ///< int, Powers on or off the laser (if the firwmare is set up to do this in its power settings) + POWER_5V = 97, ///< int, Powers on or off the 5v accessories (if the firwmare is set up to do this in its power settings) + POWER_12V = 98, ///< int, Powers on or off the 12v accessories (if the firwmare is set up to do this in its power settings) + POWER_24V = 98, ///< int, Powers on or off the 24v accessories (if the firwmare is set up to do this in its power settings) + POWER_AUX_PC = 125, ///< int, Powers on or off the auxilliary PC (if the firwmare is set up to do this in its power settings) + POWER_TOUCHSCREEN = 126, ///< int, Powers on or off the touchscreen (if the firwmare is set up to do this in its power settings) + POWER_PTZ = 127, ///< int, Powers on or off the PTZ (if the firwmare is set up to do this in its power settings) + POWER_AUDIO = 128, ///< int, Powers on or off the audio (if the firwmare is set up to do this in its power settings) + POWER_LRF2 = 129, ///< int, Powers on or off the second laser (if the firwmare is set up to do this in its power settings) + + // For SEEKUR or later lateral-capable robots + LATVEL = 110, ///< int, sets the lateral velocity (mm) + LATACCEL = 113, ///< int, sets the lateral acceleration (+, mm/sec2) or lateral deceleration (-, mm/sec2) + SETLATV = 0, /// set max. lat. vel. (not available yet) + + // MTX commands + SRECORD = 210, /// < int, (for downloading MTX firmware) byte with 0 for wait, 1 for OK, -1 for ERROR (waiting might take 3-5 seconds + MARCDEBUG = 211, ///< for debug messages from MARC, possibly responses, possibly pushed... they are ascii strings that should be logged + WHEEL_LIGHT = 212, ///< For the wheel lights + ABSOLUTE_MAXES = 213, ///< To set the absolute maxes + + SAFETY_STATE_INFO = 214, ///< int, request safety state info packets (0 == stop, 1 == send once, 2 == send continuous), + SAFETY_SET_STATE = 215, ///< 2 bytes, first byte which system, second byte for value + SAFETY_DISABLE_POWER_OFF_TIMER = 216, ///< int, 0 set off, 1 set on + + + // MobileSim specific: + SIM_SET_POSE = 224, ///< int4,int4,int4 Move robot to global pose in simulator (does not change odometry). Each value is a 4-byte integer. + SIM_RESET= 225, ///< none, Reset robot's state to original in simulator and reset odometry to 0,0,0. + SIM_LRF_ENABLE = 230, ///< int, 1 to begin sending packets of data from a simulated laser rangefinder (on the same socket connection), 2 to send extended-information laser packets (with reading flags), 0 to disable LRF + SIM_LRF_SET_FOV_START = 231, ///< int Set angle (degrees from center) at which the simulater laser takes its first reading (normally -90). + SIM_LRF_SET_FOV_END = 232, ///< int Set angle (degrees from center) at which the simulated laser takes its last reading (normally 90). + SIM_LRF_SET_RES = 233, ///< int Set the number of degrees between laser readings (in combination with FOV, determines the number of readings per sweep) (normally 1) + SIM_CTRL = 236, ///< int,..., Send a simulator meta-command (an operation on the simulator itself). The initial 2-byte integer argument selects the operation. See simulator documentation. + SIM_STAT = 237, ///< none, Request that the simulator reply with a SIMSTAT (0x62) packet. You must have a packet handler registered with ArRobot to receive its output. See simulator documentation. + SIM_MESSAGE = 238, ///< string, Display a log message in the simulator. Argument is a length-prefixed ASCII byte string. + SIM_EXIT = 239 ///< int, Exit the simulator. Argument is the exit code (use 0 for a "normal" exit). + }; + +}; + +#endif // ARCOMMANDS_H + + diff --git a/Legacy/Aria/include/ArCondition.h b/Legacy/Aria/include/ArCondition.h new file mode 100644 index 0000000..b62c518 --- /dev/null +++ b/Legacy/Aria/include/ArCondition.h @@ -0,0 +1,100 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARCONDITION_H +#define ARCONDITION_H + + +#if !defined(WIN32) || defined(MINGW) +#include +#include "ArMutex.h" +#endif +#include "ariaTypedefs.h" + + +/** Threading condition wrapper class + @ingroup UtilityClasses +*/ +class ArCondition +{ +public: + + enum { + STATUS_FAILED=1, ///< General failure + STATUS_FAILED_DESTROY, ///< Another thread is waiting on this condition so it can not be destroyed + STATUS_FAILED_INIT, ///< Failed to initialize thread. Requested action is imposesible + STATUS_WAIT_TIMEDOUT, ///< The timedwait timed out before signaling + STATUS_WAIT_INTR, ///< The wait was interupted by a signal + STATUS_MUTEX_FAILED_INIT, ///< The underlying mutex failed to init + STATUS_MUTEX_FAILED ///< The underlying mutex failed in some fashion + }; + + /** @internal */ +#if defined(WIN32) && !defined(MINGW) + typedef HANDLE CondType; +#else + typedef pthread_cond_t CondType; +#endif + + /// Constructor + AREXPORT ArCondition(); + /// Desctructor + AREXPORT virtual ~ArCondition(); + + /// Signal the thread waiting + AREXPORT int signal(); + /// Broadcast a signal to all threads waiting + AREXPORT int broadcast(); + /** @brief Wait for a signal */ + AREXPORT int wait(); + /// Wait for a signal for a period of time in milliseconds + AREXPORT int timedWait(unsigned int msecs); + /// Translate error into string + AREXPORT const char *getError(int messageNumber) const; + + // Set a name to be included in log messages + void setLogName(const char *logName) {myLogName = logName;} + const char *getLogName() + { + return (myLogName=="")?"unnamed":myLogName.c_str(); + } + + +protected: + + static ArStrMap ourStrMap; + + bool myFailedInit; + CondType myCond; +#if defined(WIN32) && !defined(MINGW) + int myCount; +#else + ArMutex myMutex; +#endif + std::string myLogName; +}; + + +#endif // ARCONDITION_H diff --git a/Legacy/Aria/include/ArConfig.h b/Legacy/Aria/include/ArConfig.h new file mode 100644 index 0000000..f6a2013 --- /dev/null +++ b/Legacy/Aria/include/ArConfig.h @@ -0,0 +1,613 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARCONFIG_H +#define ARCONFIG_H + +#include "ArConfigArg.h" +#include "ArFileParser.h" +#include "ArHasFileName.h" +#include + +class ArArgumentBuilder; +class ArConfigSection; + + +/// Stores configuration information which may be read to and from files or other sources +/** + * The configuration is a set of parameters (or config arguments), organized into + * sections. Parameters contain a key or name (a short string), a value + * (which may be one of several types), a priority (important, normal, or trivial + * to most users), a longer description, and a display hint which suggests + * what kind of UI control might be most appropriate for the parameter. + * After adding a parameter to the configuration, its value may be changed + * when the configuration is loaded or reloaded from a file. + * Various program modules may register callbacks to be notified + * when a shared global configuration (such as the static ArConfig object kept + * by the Aria class) is loaded or otherwise changed. + * + * Classes dealing with more specialized kinds of config files + * inherit from this one. + * + * Important methods in this class are: addParam(), addProcessFileCB(), + * remProcessFileCB(), parseFile(), writeFile(). + * + * Usually, configuration data are read from and written to a file using + * parseFile() and writeFile(), or are set + * by a remote client via ArNetworking. It is also possible to import + * configuration settings from an ArArgumentParser (which, for example, may + * contain a program's command line arguments) using useArgumentParser(). + * + * @warning ArConfig does not escape any special characters when writing or + * loading to/from a file. Therefore in general parameter names, values, section + * names, and comments must not contain characters which have special meaning + * in a config file, such as '#', ';', tab or newline. (see also ArFileParser) Parameter names may + * have spaces, though by convention they generally do not. + + @ingroup OptionalClasses +*/ +class ArConfig : public ArHasFileName +{ +private: + + /// Current version of the output config file. + static const char *CURRENT_CONFIG_VERSION; + /// Parser tag that introduces the config file version. + static const char *CONFIG_VERSION_TAG; + + /// Current version of the output config resource file. + static const char *CURRENT_RESOURCE_VERSION; + /// Parser tag that introduces the config resource file version. + static const char *RESOURCE_VERSION_TAG; + +public: + + /// Sections related to I/O, ARCL, display, network communication, etc. + static const char *CATEGORY_ROBOT_INTERFACE; + /// Sections related to robot behavior, docking, driving, navigation, etc. + static const char *CATEGORY_ROBOT_OPERATION; + /// Sections related to the robot hardware and its sensors/accessories. + static const char *CATEGORY_ROBOT_PHYSICAL; + /// Sections related to the fleet, enterprise manager, etc. + static const char *CATEGORY_FLEET; + /// Sections related to security. + static const char *CATEGORY_SECURITY; + /// Sections related to debug, including logging, replay, etc. + static const char *CATEGORY_DEBUG; + +public: + /// Constructor + AREXPORT ArConfig(const char *baseDirectory = NULL, + bool noBlanksBetweenParams = false, + bool ignoreBounds = false, + bool failOnBadSection = false, + bool saveUnknown = true); + /// Destructor + AREXPORT virtual ~ArConfig(); + + /// Copy constructor + AREXPORT ArConfig(const ArConfig &config); + + /// Assignment operator + AREXPORT ArConfig &operator=(const ArConfig &config); + + /// Copies the given config to this one, detaching any pointers so they are not shared + AREXPORT virtual void copyAndDetach(const ArConfig &config); + + /// Stores an optional config and robot name to be used in log messages. + AREXPORT virtual void setConfigName(const char *configName, + const char *robotName = NULL); + + /// Turn on this flag to reduce the number of verbose log messages. + AREXPORT virtual void setQuiet(bool isQuiet); + + + /// Sets an associate config that provides translations for each parameter (as read from a resource file). + AREXPORT virtual void setTranslator(ArConfig *xlatorConfig); + + /// Returns the associated translator config, or NULL if none. + AREXPORT virtual ArConfig *getTranslator() const; + + + /// Parse a config file + AREXPORT bool parseFile(const char *fileName, + bool continueOnError = false, + bool noFileNotFoundMessage = false, + char *errorBuffer = NULL, + size_t errorBufferLen = 0, + std::list *sectionsToParse = NULL, + ArPriority::Priority highestPriority = ArPriority::FIRST_PRIORITY, + ArPriority::Priority lowestPriority = ArPriority::LAST_PRIORITY, + ArConfigArg::RestartLevel *restartLevelNeeded = NULL); + + /// Write out a config file + AREXPORT bool writeFile(const char *fileName, + bool append = false, + std::set *alreadyWritten = NULL, + bool writeExtras = false, + std::list *sectionsToWrite = NULL, + ArPriority::Priority highestPriority = ArPriority::FIRST_PRIORITY, + ArPriority::Priority lowestPriority = ArPriority::LAST_PRIORITY); + + + + /// Parse a config resource file, for translation. + AREXPORT bool parseResourceFile(const char *fileName, + bool continueOnError = true, + char *errorBuffer = NULL, + size_t errorBufferLen = 0, + std::list *sectionsToParse = NULL); + + /// Parse a config resource file with parameters suitable for custom commands. + AREXPORT void parseResourceFile(ArArgumentBuilder *builder); + + /// Write a config resource file, for translation. + AREXPORT bool writeResourceFile(const char *fileName, + bool append = false, + std::set *alreadyWritten = NULL, + std::list *sectionsToWrite = NULL); + + /// Write a config resource file with parameters suitable for custom commands. + AREXPORT void writeResourceFile(ArArgumentBuilder *builder); + + /// Command to add a section and its description to the specified category. + /** + * The category is expected to be one of the CATEGORY_ constants defined above. + **/ + AREXPORT bool addSection(const char *categoryName, + const char *sectionName, + const char *sectionDescription); + + + /// Command to add a parameter to the given section with given priority + AREXPORT bool addParam(const ArConfigArg &arg, + const char *sectionName = "", + ArPriority::Priority priority = ArPriority::NORMAL, + const char *displayHint = NULL, + ArConfigArg::RestartLevel restart = ArConfigArg::NO_RESTART); + + /// Command to add a new comment to the given section with given priority + AREXPORT bool addComment(const char *comment, const char *sectionName = "", + ArPriority::Priority priority = ArPriority::NORMAL); + + /// Adds a parameter that has all the other information on it + /// already set + AREXPORT bool addParamAsIs(const ArConfigArg &arg, + const char *sectionName = ""); + + /// Sets the comment for a section + AREXPORT void setSectionComment(const char *sectionName, + const char *comment); + + + /// Uses this argument parser after it parses a file before it processes + AREXPORT void useArgumentParser(ArArgumentParser *parser); + + /// for inheritors this is called after the file is processed + /** + For classes that inherit from ArConfig this function is called + after parseFile and all of the processFileCBs are called... If + you want to call something before the processFileCBs then just + add a processFileCB... this is only called if there were no + errors parsing the file or continueOnError was set to false when + parseFile was called + + @return true if the config parsed was good (parseFile will return + true) false if the config parsed wasn't (parseFile will return false) + **/ + AREXPORT virtual bool processFile(void) { return true; } + /// Adds a callback to be invoked when the configuration is loaded or + /// reloaded. + AREXPORT void addProcessFileCB(ArRetFunctor *functor, + int priority = 0); + /// Adds a callback to be invoked when the configuration is loaded + /// or reloaded.... if you really want errors you should use + /// addProcessFileWithErrorCB, this is just to catch mistakes + AREXPORT void addProcessFileCB(ArRetFunctor2 *functor, + int priority = 0); + /// Adds a callback to be invoked when the configuration is loaded or + /// reloaded, which may also receive error messages + AREXPORT void addProcessFileWithErrorCB( + ArRetFunctor2 *functor, + int priority = 0); + /// Removes a processedFile callback + AREXPORT void remProcessFileCB(ArRetFunctor *functor); + /// Removes a processedFile callback + AREXPORT void remProcessFileCB( + ArRetFunctor2 *functor); + /// Call the processFileCBs + AREXPORT bool callProcessFileCallBacks(bool continueOnError, + char *errorBuffer = NULL, + size_t errorBufferLen = 0); + /// This parses the argument given (for parser or other use) + AREXPORT bool parseArgument(ArArgumentBuilder *arg, + char *errorBuffer = NULL, + size_t errorBufferLen = 0); + + /// Parses the config file version information. + AREXPORT bool parseVersion(ArArgumentBuilder *arg, + char *errorBuffer = NULL, + size_t errorBufferLen = 0); + + /// This parses the section change (for parser or other use) + AREXPORT bool parseSection(ArArgumentBuilder *arg, + char *errorBuffer = NULL, + size_t errorBufferLen = 0); + + AREXPORT bool parseListBegin(ArArgumentBuilder *arg, + char *errorBuffer, + size_t errorBufferLen); + + AREXPORT bool parseListEnd(ArArgumentBuilder *arg, + char *errorBuffer, + size_t errorBufferLen); + + /// This parses an unknown argument (so we can save it) + AREXPORT bool parseUnknown(ArArgumentBuilder *arg, + char *errorBuffer = NULL, + size_t errorBufferLen = 0); + + /// Gets the restart level needed + AREXPORT ArConfigArg::RestartLevel getRestartLevelNeeded(void) const; + + /// Gets the restart level needed + AREXPORT void resetRestartLevelNeeded(void); + + /// Get the base directory + AREXPORT const char *getBaseDirectory(void) const; + /// Set the base directory + AREXPORT void setBaseDirectory(const char *baseDirectory); + /// Get the file name we loaded + AREXPORT const char *getFileName(void) const; + + /// Set whether we have blanks between the params or not + AREXPORT void setNoBlanksBetweenParams(bool noBlanksBetweenParams); + + /// Get whether we have blanks between the params or not + AREXPORT bool getNoBlanksBetweenParams(void); + + /// Use an argument parser to change the config + AREXPORT bool parseArgumentParser(ArArgumentParser *parser, + bool continueOnError = false, + char *errorBuffer = NULL, + size_t errorBufferLen = 0); + + + /// Returns the list of categories contained in this config. + AREXPORT std::list getCategoryNames() const; + + /// Returns the names of the sections that have been added to the specified category. + AREXPORT std::list getSectionNamesInCategory(const char *categoryName) const; + + /// Returns the names of all sections in the config. + AREXPORT std::list getSectionNames() const; + + /// Get the sections themselves (use only if you know what to do) + AREXPORT std::list *getSections(void); + + + + /// Find the section with the given name. + /// @return section object, or NULL if not found. + AREXPORT ArConfigSection *findSection(const char *sectionName) const; + + /// Set the log level used when loading or reloading the configuration + AREXPORT void setProcessFileCallbacksLogLevel(ArLog::LogLevel level) + { myProcessFileCallbacksLogLevel = level; } + /// Get the log level used when loading or reloading the configuration + AREXPORT ArLog::LogLevel getProcessFileCallbacksLogLevel(void) + { return myProcessFileCallbacksLogLevel; } + + /// Sets whether we save unknown items (if we don't save 'em we ignore 'em) + AREXPORT void setSaveUnknown(bool saveUnknown) + { mySaveUnknown = saveUnknown; } + /// Gets whether we save unknowns (if we don't save 'em we ignore 'em) + AREXPORT bool getSaveUnknown(void) { return mySaveUnknown; } + + /// Clears out all the section information + AREXPORT void clearSections(void); + /// Clears out all the section information and the processFileCBs + AREXPORT void clearAll(void); + + /// adds a flag to a section + AREXPORT bool addSectionFlags(const char *sectionName, + const char *flags); + /// Removes a flag from a section + AREXPORT bool remSectionFlag(const char *sectionName, + const char *flag); + + /// calls clearValueSet on the whole config (internal for default configs) + AREXPORT void clearAllValueSet(void); + /// Removes all unset values from the config (internal for default configs) + AREXPORT void removeAllUnsetValues(void); + /// Removes all values from sections in which no value has been set (internal) + AREXPORT void removeAllUnsetSections(void); + + /// Logs the config + AREXPORT void log(bool isSummary = true, + std::list *sectionNameList = NULL, + const char *logPrefix = ""); + + /// Sets permissions on some things + AREXPORT void setPermissions(bool allowFactory = true, + bool rememberUnknowns = true); + + /// Adds a section for this config to always skip + void addSectionNotToParse(const char *section); + /// Removes a section for this config to always skip + void remSectionNotToParse(const char *section); + +protected: + + /// Write out a section + AREXPORT void writeSection(ArConfigSection *section, + FILE *file, + std::set *alreadyWritten, + bool writeExtras, + ArPriority::Priority highestPriority, + ArPriority::Priority lowestPriority); + + /// Write out a section in CSV format for translation + AREXPORT void writeSectionResource(ArConfigSection *section, + FILE *file, + std::set *alreadyWritten); + + AREXPORT void translateSection(ArConfigSection *section); + + void copySectionsToParse(std::list *from); + + /// Removes unset values from the config. + /** + * @param isRemovingUnsetSectionsOnly a bool set to true if unset parameters should + * not be removed from sections that have any set parameters; false if all unset + * values should be removed + **/ + AREXPORT void removeAllUnsetValues(bool isRemovingUnsetSectionsOnly); + + + /** + This class's job is to make the two functor types largely look + like the same one from the code's perspective, this is so we can + store them both in the same map for order of operations purposes. + + The funkiness with the constructor is because the retfunctor2 + looks like the retfunctor and winds up always falling into that + constructor. + **/ + class ProcessFileCBType + { + public: + ProcessFileCBType( + ArRetFunctor2 *functor) + { + myCallbackWithError = functor; + myCallback = NULL; + } + ProcessFileCBType(ArRetFunctor *functor) + { + myCallbackWithError = NULL; + myCallback = functor; + } + ~ProcessFileCBType() {} + bool call(char *errorBuffer, size_t errorBufferLen) + { + if (myCallbackWithError != NULL) + return myCallbackWithError->invokeR(errorBuffer, errorBufferLen); + else if (myCallback != NULL) + return myCallback->invokeR(); + // if we get here there's a problem + ArLog::log(ArLog::Terse, "ArConfig: Horrible problem with process callbacks"); + return false; + } + bool haveFunctor(ArRetFunctor2 *functor) + { + if (myCallbackWithError == functor) + return true; + else + return false; + } + bool haveFunctor(ArRetFunctor *functor) + { + if (myCallback == functor) + return true; + else + return false; + } + const char *getName(void) + { + if (myCallbackWithError != NULL) + return myCallbackWithError->getName(); + else if (myCallback != NULL) + return myCallback->getName(); + // if we get here there's a problem + ArLog::log(ArLog::Terse, "ArConfig: Horrible problem with process callback names"); + return NULL; + } + protected: + ArRetFunctor2 *myCallbackWithError; + ArRetFunctor *myCallback; + }; + + void addParserHandlers(void); + void remParserHandlers(void); + void addListNamesToParser(const ArConfigArg &parent); + + /// Optional name of the robot with which the config is associated. + std::string myRobotName; + /// Optional name of the config instance. + std::string myConfigName; + /// Prefix to be inserted in log messages (contains the robot and config names). + std::string myLogPrefix; + + ArArgumentParser *myArgumentParser; + std::multimap myProcessFileCBList; + bool myNoBlanksBetweenParams; + + /// Version information read from config file + std::string myConfigVersion; + + ArConfig *myTranslator; + char myCsvSeparatorChar; + + std::string mySection; + std::list *mySectionsToParse; + std::set mySectionsNotToParse; + ArPriority::Priority myHighestPriorityToParse; + ArPriority::Priority myLowestPriorityToParse; + + ArConfigArg::RestartLevel myRestartLevelNeeded; + bool myCheckingForRestartLevel; + + bool mySectionBroken; + bool mySectionIgnored; + bool myUsingSections; + + std::list myParsingListNames; + bool myIsParsingListBroken; + + std::string myFileName; + std::string myBaseDirectory; + ArFileParser myParser; + + bool myIgnoreBounds; + bool myFailOnBadSection; + bool myDuplicateParams; + bool mySaveUnknown; + bool myIsQuiet; + + bool myPermissionAllowFactory; + bool myPermissionSaveUnknown; + + ArLog::LogLevel myProcessFileCallbacksLogLevel; + + /// Map that defines the section names contained in each category. + std::map > myCategoryToSectionsMap; + + // our list of sections which has in it the argument list for each + std::list mySections; + + // callback for the file parser + ArRetFunctor3C myParserCB; + // callback for the config version in the file parser + ArRetFunctor3C myVersionCB; + // callback for the section in the file parser + ArRetFunctor3C mySectionCB; + + // callback for the _listBegin in the file parser + ArRetFunctor3C myListBeginCB; + // callback for the _listEnd in the file parser + ArRetFunctor3C myListEndCB; + + // callback for the unknown param (or whatever) file parser + ArRetFunctor3C myUnknownCB; + + +}; + + +/** Represents a section in the configuration. Sections are used to + * group items used by separate parts of Aria. + */ +class ArConfigSection +{ +public: + AREXPORT ArConfigSection(const char *name = NULL, + const char *comment = NULL, + bool isQuiet = false, + const char *categoryName = NULL); + + AREXPORT virtual ~ArConfigSection(); + AREXPORT ArConfigSection(const ArConfigSection §ion); + AREXPORT ArConfigSection &operator=(const ArConfigSection §ion); + + /// Copies the given section to this one, detaching any pointers so they are not shared + AREXPORT virtual void copyAndDetach(const ArConfigSection §ion); + + /** @return The name of this section */ + const char *getName(void) const { return myName.c_str(); } + + /** @return A comment describing this section */ + const char *getComment(void) const { return myComment.c_str(); } + + /// Returns the name of the category that contains this section. + AREXPORT const char *getCategoryName() const; + + const char *getFlags(void) const { return myFlags->getFullString(); } + AREXPORT bool hasFlag(const char *flag) const; + + std::list *getParams(void) { return &myParams; } + + void setName(const char *name); + + void setComment(const char *comment); + + AREXPORT bool addFlags(const char *flags, bool isQuiet = false); + AREXPORT bool remFlag(const char *dataFlag); + + /// Finds a parameter item in this section with the given name. Returns NULL if not found. + AREXPORT ArConfigArg *findParam(const char *paramName, + bool isAllowStringHolders = false); + + /// Finds a list member parameter with the specified name path. Returns NULL if not found. + AREXPORT ArConfigArg *findParam(const std::list ¶mNamePath, + bool isAllowHolders = false); + + /// Finds a list member parameter with the specified name path. Returns NULL if not found. + AREXPORT ArConfigArg *findParam(const char **paramNamePath, + int pathLength, + bool isAllowHolders = false); + + /// Determines whether the current section contains parameters in the specified priority ran + AREXPORT bool containsParamsOfPriority(ArPriority::Priority highestPriority, + ArPriority::Priority lowestPriority); + + /// Removes a string holder for this param, returns true if it found one + AREXPORT bool remStringHolder(const char *paramName); + + /// Turn on this flag to reduce the number of verbose log messages. + AREXPORT void setQuiet(bool isQuiet); + +protected: + + /// Give the config access to the protected category name setter. + friend class ArConfig; + + /// Sets the name of the category to which this section belongs. + void setCategoryName(const char *categoryName); + +protected: + + std::string myName; + std::string myComment; + std::string myCategoryName; + std::string myDisplayName; // Not yet supported + ArArgumentBuilder *myFlags; + std::list myParams; + bool myIsQuiet; + +}; // end class ArConfigSection + +#endif // ARCONFIG + diff --git a/Legacy/Aria/include/ArConfigArg.h b/Legacy/Aria/include/ArConfigArg.h new file mode 100644 index 0000000..228a874 --- /dev/null +++ b/Legacy/Aria/include/ArConfigArg.h @@ -0,0 +1,786 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARCONFIGARG_H +#define ARCONFIGARG_H + +#include + +#include "ariaTypedefs.h" +#include "ariaUtil.h" +#include "ArFunctor.h" + +class ArArgumentBuilder; +class ArFileParser; + +/// Argument class for ArConfig +/** + ArConfigArg stores information about a parameter (name, description, type), + and a pointer to the variable that will actually store the value. This + variable is normally stored and used by whatever class or module has added the + parameter to ArConfig. (In addition, there are some special types of + ArConfigArg that behave differently such as the "holder" types and separator, + these are used internally or in special cases.) + + Which constructor you use determines the value type of the ArConfigArg object. + + A typical idiom for creating ArConfigArg objects and adding them to ArConfig + is to create a temporary ArConfigArg in the call to ArConfig::addParam(): + + @code + config->addParam(ArConfigArg("MyParameter", &myTarget, "Example Parameter"), "Example Section"); + @endcode + + Where config is a pointer to an ArConfig object or subclass, and + myTarget is a variable (e.g. int) that is a class member whose instance will not + be destroyed before the end of the program, or which will remove the parameter + from ArConfig before being destroyed (the pointer to myTarget that is stored + in ArConfig must not become invalid.) The ArConfigArg object passed to + addParam() will be copied and stored in ArConfig. + + + + @swignote Swig cannot determine the correct constructor to use + based on most target langugages types, so you must use subclasses + defined for various types. Or, use the constructor that accepts + functors for dealing with arguments. Also, Swig cannot use pointers + to change variables, so you must create ArConfigArg objects, passing + in default values, and retain references to those objects, + in addition to passing them to ArConfig, and read new values from those + objects if ArConfig changes; or pass functors to ArConfigArg instead + of the initial value. +*/ +class ArConfigArg +{ +public: + + typedef enum + { + INVALID, ///< An invalid argument, the argument wasn't created correctly + INT, ///< Integer argument + DOUBLE, ///< Double argument + STRING, ///< String argument + BOOL, ///< Boolean argument + FUNCTOR, ///< Argument that handles things with functors + DESCRIPTION_HOLDER, ///< Argument that just holds a description + STRING_HOLDER, ///< this one is for holding strings and reading them in and writing them out but not really letting them get sent anywhere (its for unknown config parameters (so they don't get lost if a feature is turned off) + SEPARATOR, ///< Empty argument that merely acts as a separator within a (large) section. + CPPSTRING, ///< Pointer to std::string, use like STRING. + LIST, ///< Composite argument that contains an ordered list of other args + LIST_HOLDER, ///< Placeholder for composite argument that are not currently active + LAST_TYPE = LIST_HOLDER ///< Last value in the enumeration + } Type; + + + /// Indicates the components that must be restarted if the parameter is changed + enum RestartLevel { + NO_RESTART, //< No restart necessary (default value) + RESTART_CLIENT, //< Client software must be restarted (TODO Can this be eliminated?) + RESTART_IO, //< IO has changed and needs to be restarted + RESTART_SOFTWARE, //< Server software must be restarted + RESTART_HARDWARE, //< Physical robot must be rebooted + LAST_RESTART_LEVEL = RESTART_HARDWARE + }; + + enum { + DEFAULT_DOUBLE_PRECISION = 5, ///< Default double precision, originates from previous saving behavior + TYPE_COUNT = LAST_TYPE + 1, ///< Number of argument types + RESTART_LEVEL_COUNT = LAST_RESTART_LEVEL + 1, ///< Number of restart levels + }; + + + + /// Keyword that indicates the start of an ArConfigArg LIST object, for ArFileParser. + static const char *LIST_BEGIN_TAG; + /// Keyword that indicates the end of an ArConfigArg LIST object, for ArFileParser. + static const char *LIST_END_TAG; + + /// Resource file keyword that indicates an empty string (cannot write empty for csv). + static const char *NULL_TAG; + /// Resource file keyword that indicates a new entry. + static const char *NEW_RESOURCE_TAG; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Static Methods + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + /// Returns a text representation of the given type, suitable for logging. + static const char *toString(Type t); + + /// Returns a text representation of the given RestartLevel, suitable for logging. + static const char *toString(RestartLevel r); + + + /// Given a text representation, returns the appropriate Type. + static Type typeFromString(const char *text); + + /// Given a text representation, returns the appropriate RestartLevel. + static RestartLevel restartLevelFromString(const char *text); + + + + /// Returns the section name contained in the given resource arg. + AREXPORT static std::string parseResourceSectionName(ArArgumentBuilder *arg, + const char *logPrefix = ""); + + /// Returns the param name contained in the given resource arg. + AREXPORT static std::string parseResourceArgName(ArArgumentBuilder *arg, + const char *logPrefix = ""); + + /// Returns the arg type contained in the given resource arg. + AREXPORT static Type parseResourceType(ArArgumentBuilder *arg, + const char *logPrefix = ""); + + /// Returns true if the given resource arg is "top-level", i.e. not a list member. + AREXPORT static bool isResourceTopLevel(ArArgumentBuilder *arg, + const char *logPrefix = ""); + + /// Returns the parent path contained in the resource arg for list members. + AREXPORT static std::list parseResourceParentPath(ArArgumentBuilder *arg, + char separator = '|', + const char *logPrefix = ""); + + /// Returns the description contained in the given resource arg. + AREXPORT static std::string parseResourceDescription(ArArgumentBuilder *arg, + const char *logPrefix = ""); + /// Returns the extra explanation contained in the given resource arg. + AREXPORT static std::string parseResourceExtra(ArArgumentBuilder *arg, + const char *logPrefix = ""); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Instance Methods + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + /// Default empty contructor + AREXPORT ArConfigArg(); + /// Constructor for making an integer argument by pointer (4 bytes) + AREXPORT ArConfigArg(const char * name, int *pointer, + const char * description = "", + int minInt = INT_MIN, + int maxInt = INT_MAX); + /// Constructor for making an int argument thats a short (2 bytes) + AREXPORT ArConfigArg(const char * name, short *pointer, + const char * description = "", + int minInt = SHRT_MIN, + int maxInt = SHRT_MAX); + /// Constructor for making an int argument thats a ushort (2 bytes) + AREXPORT ArConfigArg(const char * name, unsigned short *pointer, + const char * description = "", + int minInt = 0, + int maxInt = USHRT_MAX); + /// Constructor for making an char (1 byte) argument by pointer (treated as int) + AREXPORT ArConfigArg(const char * name, unsigned char *pointer, + const char * description = "", + int minInt = 0, + int maxInt = 255); + /// Constructor for making a double argument by pointer + AREXPORT ArConfigArg(const char * name, + double *pointer, + const char * description = "", + double minDouble = -HUGE_VAL, + double maxDouble = HUGE_VAL, + int precision = DEFAULT_DOUBLE_PRECISION); + /// Constructor for making a boolean argument by pointer + AREXPORT ArConfigArg(const char * name, bool *pointer, + const char * description = ""); + /// Constructor for making an argument of a string by pointer (see details) + AREXPORT ArConfigArg(const char *name, char *str, + const char *description, + size_t maxStrLen); + /// Constructor for making an argument of a string by pointer (see details) + AREXPORT ArConfigArg(const char *name, const char *str, + const char *description); + + /// Constructor for making an argument of a C++ std::string + AREXPORT ArConfigArg(const char *name, std::string *str, const char *description); + + /// Constructor for making an integer argument + AREXPORT ArConfigArg(const char * name, int val, + const char * description = "", + int minInt = INT_MIN, + int maxInt = INT_MAX); + /// Constructor for making a double argument + AREXPORT ArConfigArg(const char * name, + double val, + const char * description = "", + double minDouble = -HUGE_VAL, + double maxDouble = HUGE_VAL, + int precision = DEFAULT_DOUBLE_PRECISION); + /// Constructor for making a boolean argument + AREXPORT ArConfigArg(const char * name, bool val, + const char * description = ""); + /// Constructor for making an argument that has functors to handle things + AREXPORT ArConfigArg(const char *name, + ArRetFunctor1 *setFunctor, + ArRetFunctor *> *getFunctor, + const char *description); + + /// Constructor for just holding a description (for ArConfig) + AREXPORT ArConfigArg(const char *str, Type type = DESCRIPTION_HOLDER); + /// Constructor for holding an unknown argument (STRING_HOLDER) + AREXPORT ArConfigArg(const char *name, const char *str); + + /// Constructs a new named argument of the specified type. + AREXPORT ArConfigArg(Type type, + const char *name, + const char *description); + + /// Constructs a new argument of the specified type. + AREXPORT ArConfigArg(Type type); + + /// Destructor + AREXPORT virtual ~ArConfigArg(); + + /// Copy constructor that allows a new name to be assigned + AREXPORT ArConfigArg(const char *argName, + const ArConfigArg & arg); + + /// Copy constructor + AREXPORT ArConfigArg(const ArConfigArg & arg); + /// Assignment operator + AREXPORT ArConfigArg &operator=(const ArConfigArg &arg); + + /// Copies the given arg to this one, detaching any pointers so they are not shared + AREXPORT void copyAndDetach(const ArConfigArg &arg); + + + /// Copies the translation data from given arg to this one. + AREXPORT bool copyTranslation(const ArConfigArg &arg); + + + /// Gets the type of the argument + AREXPORT ArConfigArg::Type getType(void) const; + /// Gets the name of the argument + AREXPORT const char *getName(void) const; + /// Gets the brief description of the argument + AREXPORT const char *getDescription(void) const; + + /// Sets the description (normally given in the constructor) + AREXPORT void setDescription(const char *description); + + /// For arguments that require more than a brief description, set the extra explanation. + AREXPORT void setExtraExplanation(const char *extraExplanation); + + /// Returns the extra explanation, if any, for this argument + AREXPORT const char *getExtraExplanation() const; + + + /// Sets the argument value, for int arguments + AREXPORT bool setInt(int val, + char *errorBuffer = NULL, size_t errorBufferLen = 0, + bool doNotSet = false); + + /// Sets the argument value, for double arguments + AREXPORT bool setDouble(double val, + char *errorBuffer = NULL, size_t errorBufferLen = 0, + bool doNotSet = false); + + /// Sets the argument value, for bool arguments + AREXPORT bool setBool(bool val, + char *errorBuffer = NULL, size_t errorBufferLen = 0, + bool doNotSet = false); + + /// Sets the argument value for string arguments + AREXPORT bool setString(const char *str, + char *errorBuffer = NULL, size_t errorBufferLen = 0, + bool doNotSet = false); + + /// Sets the argument value for string arguments. The value of @a str is copied to the target string. + AREXPORT bool setString(const std::string &str, + char *errorBuffer = NULL, size_t errorBufferLen = 0, + bool doNotSet = false); + + AREXPORT bool setCppString(const std::string &str, + char *errorBuffer = NULL, size_t errorBufferLen = 0, + bool doNotSet = false); + + /// Sets the argument by calling the setFunctor callback + AREXPORT bool setArgWithFunctor(ArArgumentBuilder *argument, + char *errorBuffer = NULL, + size_t errorBufferLen = 0, + bool doNotSet = false); + + + + /// Gets the argument value, for int arguments + AREXPORT int getInt(bool *ok = NULL) const; + + /// Gets the minimum int value + AREXPORT int getMinInt(bool *ok = NULL) const; + /// Gets the maximum int value + AREXPORT int getMaxInt(bool *ok = NULL) const; + + + /// Gets the argument value, for double arguments + AREXPORT double getDouble(bool *ok = NULL) const; + /// Gets the minimum double value + AREXPORT double getMinDouble(bool *ok = NULL) const; + /// Gets the maximum double value + AREXPORT double getMaxDouble(bool *ok = NULL) const; + /// Gets the decimal precision of the double + AREXPORT int getDoublePrecision(bool *ok = NULL) const; + + /// Gets the argument value, for bool arguments + AREXPORT bool getBool(bool *ok = NULL) const; + + /// Gets the argument value, for string (and string holder) arguments + AREXPORT const char *getString(bool *ok = NULL) const; + + /// Gets the argument value, which is a list of argumentbuilders here + AREXPORT const std::list *getArgsWithFunctor(bool *ok = NULL) const; + + AREXPORT std::string getCppString(bool *ok = NULL) const; + + AREXPORT const std::string* getCppStringPtr(bool *ok = NULL) const; + + + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Methods for LIST Type + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + /// Adds a child arg to this arg. Valid only for LIST type; otherwise returns false. + AREXPORT bool addArg(const ArConfigArg &arg); + + /// Returns whether the list contains child args. Valid only for LIST type; otherwise returns false. + AREXPORT bool hasArgs() const; + + /// Returns the number of child args. Valid only for LIST type; otherwise returns 0. + AREXPORT size_t getArgCount() const; + + // KMC 7/9/12 Right now, the returned args will not have the parent set to this arg. + // I suspect that this may present an implementation issue later but am not sure. + // Perhaps the addition of an iterator would suffice. + // + /// Returns a list of all child args in this arg. Valid only for LIST type; otherwise returns an empty list. + AREXPORT std::list getArgs(bool *ok = NULL) const; + + /// Returns the child arg at the specified index (between 0 and getArgCount()). + AREXPORT const ArConfigArg *getArg(size_t index) const; + + /// Returns the child arg at the specified index (between 0 and getArgCount()). + AREXPORT ArConfigArg *getArg(size_t index); + + /// Finds the specified child arg. Valid only for LIST type; otherwise returns NULL. + AREXPORT const ArConfigArg *findArg(const char *childParamName) const; + + /// Finds the specified child arg. Valid only for LIST type; otherwise returns NULL. + AREXPORT ArConfigArg *findArg(const char *childParamName); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Miscellaneous Attributes + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + /// Gets the priority (only used by ArConfig) + AREXPORT ArPriority::Priority getConfigPriority(void) const; + /// Sets the priority (only used by ArConfig) + AREXPORT void setConfigPriority(ArPriority::Priority priority); + + /// Returns the display hint for this arg, or NULL if none is defined. + AREXPORT const char *getDisplayHint() const; + /// Sets the display hint for this arg. + AREXPORT void setDisplayHint(const char *hintText); + + /// Gets the restart level of this parameter (only used by ArConfig) + AREXPORT RestartLevel getRestartLevel() const; + /// Sets the restart level of this parameter (only used by ArConfig) + AREXPORT void setRestartLevel(RestartLevel level); + + /// Gets if notifications of changes are supressed (for the central + /// server config) + AREXPORT bool getSupressChanges(void) const; + /// Sets if notifications of changes are supressed (for the central + /// server config) + AREXPORT void setSupressChanges(bool supressChanges); + + + /// Returns a pointer to the immediate parent arg. If this is not a child ArConfigArg, then returns NULL. + AREXPORT ArConfigArg *getParentArg() const; + + /// If getParentArg() is not null, then returns the path to the top level, as a single string + AREXPORT std::string getParentPathName(char separator = '|') const; + + /// Given a parent path, as a single string, splits it in a format useable by ArConfigSection findParam + AREXPORT static std::list splitParentPathName(const char *parentPathName, + char separator = '|'); + + + /// Replaces spaces in the name with underscores + AREXPORT void replaceSpacesInName(void); + + /// Returns whether the arg has a minimum value, currently applicable to INTs and DOUBLEs + AREXPORT bool hasMinBound() const; + + /// Returns whether the arg has a maximum value, currently applicable to INTs and DOUBLEs + AREXPORT bool hasMaxBound() const; + + /// Sets whether to ignore bounds or not (default is to not to) + AREXPORT void setIgnoreBounds(bool ignoreBounds = false); + + /// Returns true if this arg points to a member of another object, false if arg is self-contained. + AREXPORT bool hasExternalDataReference() const; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Generic (Type-Independent) Methods + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + /// Adds given parserCB handler for the appropriate keyword(s) to the given file parser. + AREXPORT bool addToFileParser(ArFileParser *parser, + ArRetFunctor3C *parserCB, + const char *logPrefix = "", + bool isQuiet = false) const; + + + + /// Sets the value of this arg to the data described in the given ArArgumentBuilder + AREXPORT bool parseArgument(ArArgumentBuilder *arg, + char *errorBuffer, + size_t errorBufferLen, + const char *logPrefix = "", + bool isQuiet = false, + bool *changed = NULL); + + /// Writes this arg to the given file, in a format suitable for reading by parseArgument. + AREXPORT bool writeArguments(FILE *file, + char *lineBuf, + int lineBufSize, + int startCommentColumn, + bool isWriteExtra = false, + const char *logPrefix = "", + int indentLevel = 0) const; + + /// Writes the name of this arg to the given buffer, indenting as specified. + AREXPORT bool writeName(char *lineBuf, + int lineBufSize, + int indentLevel) const; + + /// Writes the min/max values of this arg to the given buffer, as applicable. + AREXPORT bool writeBounds(char *line, + size_t lineLen, + const char *logPrefix = "") const; + + /// Logs the type, name, and value of this argument + AREXPORT void log(bool verbose = false, + int indentCount = 1, + const char *logPrefix = "") const; + + /// Checks only the name, type, and value attributes and returns whether they are equal. + AREXPORT bool isValueEqual(const ArConfigArg &other) const; + + /// If the given source is of the same type, copies its value to this arg + /** + * Note that this method currently only works for the primitive arg + * types (i.e. int, bool, etc.). It doesn't copy functors or description + * holders. + * + * @param source the ArConfigArg whose value is to be copied to this arg + * @param isVerifyArgNames a bool set to true if the argument value should + * be set only if the given source has the same name as this argument; + * the default value is false + * @return bool true if the value was copied; false if the source was of a + * different (or non-copyable) type + **/ + AREXPORT bool setValue(const ArConfigArg &source, + bool isVerifyArgNames = false); + + /// Gets whether this value has been set since it was last cleared or not + bool isValueSet(void) { return myValueSet; } + + /// Tells the configArg that the value hasn't been set + void clearValueSet(void) { myValueSet = false; } + + /// For special arg types (such as LIST), sets the flag to indicate the value was set. + void setValueSet(void) { myValueSet = true; } + + + /// Returns whether the arg has been translated by a resource file. + bool isTranslated() const; + + /// Sets whether the arg has been translated by a resource file. + void setTranslated(bool b); + + + enum ResourceIndices { + RESOURCE_INDEX_OF_SECTION_NAME = 0, + RESOURCE_INDEX_OF_ARG_NAME = 1, + RESOURCE_INDEX_OF_TYPE = 2, + RESOURCE_INDEX_OF_PRIORITY = 3, + RESOURCE_INDEX_OF_RESTART_LEVEL = 4, + RESOURCE_INDEX_OF_PARENT_PATH = 5, + RESOURCE_INDEX_OF_DESCRIPTION = 6, + RESOURCE_INDEX_OF_EXTRA = 7, + RESOURCE_INDEX_OF_DISPLAY = 8, // not yet supported + RESOURCE_INDEX_OF_NEW = 9 + }; + + enum { + MAX_RESOURCE_ARG_TEXT_LENGTH = 1024 + }; + + /// Sets the value of this arg to the resource data described in the given ArArgumentBuilder + AREXPORT bool parseResource(ArArgumentBuilder *arg, + char *errorBuffer, + size_t errorBufferLen, + const char *logPrefix = "", + bool isQuiet = false); + + + + /// Parses the text obtained from the resource arg, strips surrounding quotes, blanks, and funny chars. + AREXPORT static bool parseResourceArgText(const char *argText, + char *bufOut, + size_t bufLen); + + /// Writes this arg to the given file, in a format suitable for reading by parseResource. + AREXPORT bool writeResource(FILE *file, + char *lineBuf, + int lineBufSize, + char separatorChar, + const char *sectionName, + const char *logPrefix = "") const; + + + /// Writes column labels and edit info to the given resource file, returns number of lines written + AREXPORT static int writeResourceHeader(FILE *file, + char *lineBuf, + int lineBufSize, + char separatorChar, + const char *sectionTitle, + const char *logPrefix = ""); + + /// Writes the section description to the resource file. + AREXPORT static int writeResourceSectionHeader(FILE *file, + char *lineBuf, + int lineBufSize, + char separatorChar, + const char *sectionName, + const char *sectionDesc, + const char *sectionExtra, + const char *sectionDisplayName, + bool isTranslated, + const char *logPrefix = ""); + +protected: + + // Giving ArConfig access to the write method + friend class ArConfig; + + /// Writes the given comment to the specified file, spanning multiple lines as necessary. + AREXPORT static bool writeMultiLineComment(const char *comment, + FILE *file, + char *lineBuf, + int lineBufSize, + const char *startComment); + + +private: + + enum IntType { + INT_NOT, ///< Not an int + INT_INT, ///< An int (4 bytes) + INT_SHORT, ///< A short (2 bytes) + INT_UNSIGNED_SHORT, ///< An unsigned short (2 bytes) + INT_UNSIGNED_CHAR ///< An unsigned char (1 byte) + }; + + /// Internal helper function + void clear(bool initial, + Type type = INVALID, + IntType intType = INT_NOT, + bool isDelete = true); + + /// Copies the given arg to this one, optionally detaching any internal pointer + void copy(const ArConfigArg &arg, bool isDetach = false); + + void set(ArConfigArg::Type type, + const char *name, + const char *description, + IntType intType = INT_NOT); + + /// Sets the parent pointer of this arg. + void setParent(ArConfigArg *parentArg); + + /// Whether the arg type is LIST or LIST_HOLDER + bool isListType() const; + +// KMC 7/11/12 Changed from protected to private so future changes are less +// of a concern +// protected: +private: + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + /// Data applicable to INT args + struct ArConfigIntData { + + // int data + ArConfigArg::IntType myIntType; + + // If unions need to be avoided for some reason, then this can simply + // be turned into a struct. + // + // begin union (based on myIntType) + union { + int *myIntPointer; + short *myIntShortPointer; + unsigned short *myIntUnsignedShortPointer; + unsigned char *myIntUnsignedCharPointer; + }; + // end union (based on myIntType) + + int myMinInt; + int myMaxInt; + + }; // end struct ArConfigIntData + + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + /// Data applicable to DOUBLE args + struct ArConfigDoubleData { + + double *myDoublePointer; + double myMinDouble; + double myMaxDouble; + int myPrecision; + + }; // end struct ArConfigDoubleData + + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + /// Data applicable to BOOL args + struct ArConfigBoolData { + + bool *myBoolPointer; + + }; // end struct ArConfigBoolData + + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + /// Data applicable to STRING and STRING_HOLDER args + struct ArConfigStringData { + + // string data + char *myStringPointer; + size_t myMaxStrLen; + // KMC own string change + // Not seeing the functional difference between this and myOwnPointedTo + // (which was previously applied to all but strings) + // bool myUsingOwnedString; + std::string *myString; ///< Used if myOwnedString is true. (Union member cannot have a copy constructor so using a pointer) + + }; // end struct ArConfigStringData + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + /// Data applicable to CPPSTRING + struct ArConfigCppStringData { + std::string *myCppStringPtr; + }; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + /// Data applicable to LIST args + struct ArConfigListData { + + std::list *myChildArgList; + + }; // end struct ArConfigListData + + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + /// Data applicable to FUNCTOR args + struct ArConfigFunctorData { + + ArRetFunctor1 *mySetFunctor; + ArRetFunctor *> *myGetFunctor; + + }; // end struct ArConfigFunctorData + + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // + // If unions need to be avoided for some reason, then this can simply + // be turned into a struct. + // + /// Data that varies according to type of arg + union ArConfigArgData { // begin union (based on myType) + ArConfigIntData myIntData; + ArConfigDoubleData myDoubleData; + ArConfigBoolData myBoolData; + ArConfigStringData myStringData; + ArConfigListData myListData; + ArConfigFunctorData myFunctorData; + ArConfigCppStringData myCppStringData; + }; // end union (based on myType) + + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + /// Number of spaces to indent each level of list contents + static int ourIndentSpaceCount; + + static std::map *ourTextToTypeMap; + static std::map *ourTextToRestartLevelMap; + + /// Type of this arg + ArConfigArg::Type myType; + /// Name of this arg (may be empty for SEPARATOR args) + std::string myName; + /// Brief description of this arg + std::string myDescription; + /// An optional extra explanation for args that need clarification + std::string myExtraExplanation; + + /// Name to be displayed in client applications. (Not yet supported.) + std::string myDisplayName; + + ArConfigArgData myData; + + /// Priority of this arg + ArPriority::Priority myConfigPriority; + /// Optional display hint used by clients + std::string myDisplayHint; + /// Indicates whether modifying the arg will result in a system restart + RestartLevel myRestartLevel; + /// Supressses change notification (for central server config params that should cause a restart on a robot, but not on the central server) + bool mySupressChanges; + + /// Pointer to the parent arg, or NULL if this arg is not a member of a LIST + ArConfigArg *myParentArg; + + /// Whether this arg "owns" its data, i.e. does not point to a member of another object + bool myOwnPointedTo : 1; + /// Whether this arg has been set to its initial value + bool myValueSet : 1; + /// Whether any min/max bounds requirements on this arg should be ignored + bool myIgnoreBounds : 1; + /// Whether this arg has been translated by a resource file + bool myIsTranslated : 1; + +}; // end class ArConfigArg + +#endif // ARCONFIGARG_H diff --git a/Legacy/Aria/include/ArConfigGroup.h b/Legacy/Aria/include/ArConfigGroup.h new file mode 100644 index 0000000..1afaa5c --- /dev/null +++ b/Legacy/Aria/include/ArConfigGroup.h @@ -0,0 +1,59 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARCONFIGGROUP_H +#define ARCONFIGGROUP_H + +#include "ArConfig.h" + +/// Container for holding a group of ArConfigs +class ArConfigGroup +{ +public: + /// Constructor + AREXPORT ArConfigGroup(const char *baseDirectory = NULL); + /// Destructor + AREXPORT ~ArConfigGroup(void); + /// Adds a config to the group + AREXPORT void addConfig(ArConfig *config); + /// Removes a config from the group + AREXPORT void remConfig(ArConfig *config); + /// Parses the given file (starting from the base directory) + AREXPORT bool parseFile(const char *fileName, bool continueOnError = false); + /// Reloads the last file parsed + AREXPORT bool reloadFile(bool continueOnError = true); + /// Writes a file out (overwrites any existing file) + AREXPORT bool writeFile(const char *fileName); + /// Sets the base directory on all configs this contains + AREXPORT void setBaseDirectory(const char *baseDirectory); + /// Gets the baes directory of this group (not the configs it contains) + AREXPORT const char *getBaseDirectory(void) const; +protected: + std::string myBaseDirectory; + std::string myLastFile; + std::list myConfigs; +}; + +#endif // ARCONFIGGROUP diff --git a/Legacy/Aria/include/ArDPPTU.h b/Legacy/Aria/include/ArDPPTU.h new file mode 100644 index 0000000..519a32f --- /dev/null +++ b/Legacy/Aria/include/ArDPPTU.h @@ -0,0 +1,457 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARDPPTU_H +#define ARDPPTU_H + +#include "ariaTypedefs.h" +#include "ArRobot.h" +#include "ArPTZ.h" +#include + +class ArBasePacket; + +/** Interface to Directed Perception pan/tilt unit, imprementing the ArPTZ + * interface. + +Functions such as pan(), tilt(), etc. +send requests to the PTU. By default, a new motion command will interrupt the +previous command, but the awaitExec() function sends a command instructing the +PTU to wait for the previous motion to finish. + +Incoming data sent from the PTU is read every ArRobot task cycle (10hz). If this +data contains a message giving the current measured position of the pan and +tilt axes, then this is stored as the current pan and tilt positions, and a request for +the next positions is sent. (This means that the pan and tilt positions are +received as fast as the PTU can send them, but no faster than the robot task +cycle.) If no pan and tilt positions have been received, then ArDPPTU defaults +to providing as pan and tilt position whatever the last *requested* positions +are (from the last use of pan(), tilt() or panTilt()). (This is the standard +behavior specified by the ArPTZ interface, and lets you deal with different +kinds of PTUs, some of which cannot measure their own position.) You can also +always check the last pan or tilt request with getLastPanRequest() and +getLastTiltRequest(). + +To use ArDPPTU you must set the appropriate device connection (usually an +ArSerialConnection), open this connection, then call the init() method on the +ArDPPTU object. Then, you can use resetCalib() to have the unit perform a self +calibration routine, configure power modes, set speeds, etc. + +The ArDPPTU constructor will switch on power to the PTU when on a Seekur or +Seekur Jr. robot. The shutdown() method (and destructor) will switch off power. + +If a specific DPPTU type was given in the constructor, then some internal +conversion factors are set according to that type. If left as the +PANTILT_DEFAULT type, then the conversion factors are automatically determined +by querying the DPPTU device. PANTILT_DEFAULT is recommended. + +The DPPTU performs a startup self-calibration routine when first powered on. You +can recalibrate by calling resetCalib(). + +By default the DPPTU is configured to use low power when in motion, and no power +on the motors when holding a position. This is OK for most cameras. However, +the DPPTU has a very high payload (especially PTU47 for outdoor use) and you +may want to enable higher power modes if the PTU slips when carrying heavy +payloads using setMovePower() and setHoldPower(). + +The DPPTU can be connected to a computer serial port (typically COM4) or through +a Pioneer microcontroller auxilliary serial port. +If the DPPTU is connected to the microcontroller, make sure that the baud rate of the microcontroller-DPPTU connection is at least as fast, if not faster than the connection of the computer to the microcontroller. If it's slower then the commands sent to the DPPTU may get backed up in the AUX port buffer and cause the DPPTU to behave erratically. So, if the computer-microcontroller connection is autobauding up to 38400bps, then make sure that the microcontroller aux port is set to 38400bps, as well, and consult the DPPTU manual for directions on changing its baud rate. + +@sa the DPPTU manuals and documentation available at
http://robots.mobilerobots.com + + + @ingroup OptionalClasses +*/ + +/// A class with the commands for the DPPTU +class ArDPPTUCommands +{ +public: + + enum { + DELIM = 0x20, /// myQueryCB; + char *myDataBuf; + + + ArFunctorC myShutdownCB; + int myDeviceIndex; + void shutdown(); + + ArTime myLastPositionMessageHandled; + bool myWarnedOldPositionData; + ArTime myLastQuerySent; + + std::vector myPowerPorts; + + bool myGotPanRes; + bool myGotTiltRes; + + ///@since 2.7.6 + static ArPTZ* create(size_t index, ArPTZParams params, ArArgumentParser *parser, ArRobot *robot); + ///@since 2.7.6 + static ArPTZConnector::GlobalPTZCreateFunc ourCreateFunc; +}; + +#endif // ARDPPTU_H + diff --git a/Legacy/Aria/include/ArDataLogger.h b/Legacy/Aria/include/ArDataLogger.h new file mode 100644 index 0000000..898b8e8 --- /dev/null +++ b/Legacy/Aria/include/ArDataLogger.h @@ -0,0 +1,126 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARDATALOGGER_H +#define ARDATALOGGER_H + +#include "ariaUtil.h" +#include "ArMutex.h" +#include "ArFunctor.h" +#include + +class ArRobot; +class ArConfig; + + +/// This class will log data, but you have to use it through an ArConfig right now +/** + This class doesn't log anything by default, but can be set up to + log all sorts of data. Note that if you do an addString after you + do an addToConfig it'll automatically be enabled (since right now + we don't want to change config after loading since the values would + wind up wierd). + + @ingroup OptionalClasses + **/ +class ArDataLogger +{ +public: + /// Constructor + AREXPORT ArDataLogger(ArRobot *robot, const char *fileName = NULL); + /// Destructor + AREXPORT ~ArDataLogger(); + /// Adds the data logger information to the config + AREXPORT void addToConfig(ArConfig *config); + /// Adds a string to the list of options in the raw format + AREXPORT void addString(const char *name, ArTypes::UByte2 maxLen, + ArFunctor2 *functor); + + /// Gets the functor for adding a string (for ArStringInfoGroup) + ArFunctor3 *> * + getAddStringFunctor(void) { return &myAddStringFunctor; } + +protected: + AREXPORT void connectCallback(void); + AREXPORT bool processFile(char *errorBuffer, size_t errorBufferLen); + AREXPORT void userTask(void); + ArRobot *myRobot; + ArTime myLastLogged; + ArConfig *myConfig; + bool myAddToConfigAtConnect; + bool myAddedToConfig; + + FILE *myFile; + bool myConfigLogging; + int myConfigLogInterval; + char myOpenedFileName[512]; + char myConfigFileName[512]; + std::string myPermanentFileName; + + // for what we're logging + bool myLogVoltage; + bool myLogStateOfCharge; + bool myLogLeftVel; + bool myLogRightVel; + bool myLogTransVel; + bool myLogRotVel; + bool myLogLatVel; + bool myLogLeftStalled; + bool myLogRightStalled; + bool myLogStallBits; + bool myLogFlags; + bool myLogFaultFlags; + int myAnalogCount; + bool *myAnalogEnabled; + int myAnalogVoltageCount; + bool *myAnalogVoltageEnabled; + int myDigInCount; + bool *myDigInEnabled; + int myDigOutCount; + bool *myDigOutEnabled; + bool myLogPose; + bool myLogEncoderPose; + bool myLogCorrectedEncoderPose; + bool myLogEncoders; + bool myLogChargeState; + bool myLogBatteryInfo; + int myStringsCount; + std::vector myStringsEnabled; + + ArMutex myMutex; + + std::vector myStrings; + ArTypes::UByte2 myMaxMaxLength; + ArFunctor3C *> myAddStringFunctor; + + + ArFunctorC myConnectCB; + ArRetFunctor2C myProcessFileCB; + ArFunctorC myUserTaskCB; +}; + +#endif // ARDATALOGGER_H diff --git a/Legacy/Aria/include/ArDeviceConnection.h b/Legacy/Aria/include/ArDeviceConnection.h new file mode 100644 index 0000000..b2895ef --- /dev/null +++ b/Legacy/Aria/include/ArDeviceConnection.h @@ -0,0 +1,186 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARDEVICECONNECTION_H +#define ARDEVICECONNECTION_H + +#include +#include "ariaTypedefs.h" +#include "ariaUtil.h" +#include "ArBasePacket.h" + +/// Base class for device connections +/** + Base class for device connections, this is mostly for connections to the + robot or simulator but could also be used for a connection to a laser + or other device + + Note that this is mostly a base class, so if you'll want to use one of the + classes which inherit from this one... also note that in those classes + is where you'll find setPort which sets the place the device connection + will try to connect to... the inherited classes also have an open which + returns more detailed information about the open attempt, and which takes + the parameters for where to connect +*/ +class ArDeviceConnection +{ + public: + /// constructor + AREXPORT ArDeviceConnection(); + /// destructor also forces a close on the connection + AREXPORT virtual ~ArDeviceConnection(); + /// Reads data from connection + /** + Reads data from connection + @param data pointer to a character array to read the data into + @param size maximum number of bytes to read + @param msWait read blocks for this many milliseconds (not at all for == 0) + @return number of bytes read, or -1 for failure + @see write, writePacket + */ + AREXPORT virtual int read(const char *data, unsigned int size, + unsigned int msWait = 0) = 0; + /// Writes data to connection + /** + Writes data to connection from a packet + @param packet pointer to a packet to write the data from + @return number of bytes written, or -1 for failure + @see read, write + */ + AREXPORT virtual int writePacket(ArBasePacket *packet) + { if (packet == NULL || packet->getLength() == 0) return 0; + return write(packet->getBuf(), packet->getLength()); } + /// Writes data to connection + /** + Writes data to connection + @param data pointer to a character array to write the data from + @param size number of bytes to write + @return number of bytes read, or -1 for failure + @see read, writePacket + */ + AREXPORT virtual int write(const char *data, unsigned int size) = 0; + /// Gets the status of the connection, which is one of the enum status + /** + Gets the status of the connection, which is one of the enum status. + If you want to get a string to go along with the number, use + getStatusMessage + @return the status of the connection + @see getStatusMessage + */ + AREXPORT virtual int getStatus(void) = 0; + /// Gets the description string associated with the status + /** + @param messageNumber the int from getStatus you want the string for + @return the description associated with the status + @see getStatus + */ + AREXPORT const char *getStatusMessage(int messageNumber) const; + + /// Opens the connection again, using the values from setLocation or + // a previous open + virtual bool openSimple(void) = 0; + + /// Closes the connection + /** + @return whether the close succeeded or not + */ + virtual bool close(void) { return false; } + /// Gets the string of the message associated with opening the device + /** + Each class inherited from this one has an open method which returns 0 + for success or an integer which can be passed into this function to + obtain a string describing the reason for failure + @param messageNumber the number returned from the open + @return the error description associated with the messageNumber + */ + AREXPORT virtual const char * getOpenMessage(int messageNumber) = 0; + enum Status { + STATUS_NEVER_OPENED = 1, ///< Never opened + STATUS_OPEN, ///< Currently open + STATUS_OPEN_FAILED, ///< Tried to open, but failed + STATUS_CLOSED_NORMALLY, ///< Closed by a close call + STATUS_CLOSED_ERROR ///< Closed because of error + }; + /// Gets the time data was read in + /** + @param index looks like this is the index back in the number of bytes + last read in + @return the time the last read data was read in + */ + AREXPORT virtual ArTime getTimeRead(int index) = 0; + /// sees if timestamping is really going on or not + /** @return true if real timestamping is happening, false otherwise */ + AREXPORT virtual bool isTimeStamping(void) = 0; + + /// Gets the port name + AREXPORT const char *getPortName(void) const; + /// Gets the port type + AREXPORT const char *getPortType(void) const; + + /// Sets the device type (what this is connecting to) + AREXPORT void setDeviceName(const char *deviceName); + /// Gets the device type (what this is connecting to) + AREXPORT const char *getDeviceName(void) const; + + /// Notifies the device connection that the start of a packet is + /// trying to be read + AREXPORT void debugStartPacket(void); + /// Notifies the device connection that some bytes were read (should + /// call with 0 if it read but got no bytes) + AREXPORT void debugBytesRead(int bytesRead); + /// Notifies the device connection that the end of a packet was + /// read, which will cause log messages if set to do so + AREXPORT void debugEndPacket(bool goodPacket, int type = 0); + /// Makes all device connections so that they'll dump data + AREXPORT static bool debugShouldLog(bool shouldLog); + protected: + /// Sets the port name + AREXPORT void setPortName(const char *portName); + /// Sets the port type + AREXPORT void setPortType(const char *portType); + + void buildStrMap(void); + static bool ourStrMapInited; + static ArStrMap ourStrMap; + + std::string myDCPortName; + std::string myDCPortType; + std::string myDCDeviceName; + + static bool ourDCDebugShouldLog; + static ArTime ourDCDebugFirstTime; + bool myDCDebugPacketStarted; + ArTime myDCDebugStartTime; + ArTime myDCDebugFirstByteTime; + ArTime myDCDebugLastByteTime; + int myDCDebugBytesRead; + int myDCDebugTimesRead; + long long myDCDebugNumGoodPackets; + long long myDCDebugNumBadPackets; +}; + +#endif + + diff --git a/Legacy/Aria/include/ArDrawingData.h b/Legacy/Aria/include/ArDrawingData.h new file mode 100644 index 0000000..1815dcd --- /dev/null +++ b/Legacy/Aria/include/ArDrawingData.h @@ -0,0 +1,217 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARDRAWINGDATA_H +#define ARDRAWINGDATA_H + +#include "ariaTypedefs.h" +#include "ariaUtil.h" + +/// A class for holding color information for ArDrawingData +class ArColor +{ +public: + /// Constructor (colors use full range of 0-255) + ArColor(unsigned char red, unsigned char green, unsigned char blue) + { myRed = red; myGreen = green; myBlue = blue; } + /// Constructor + ArColor() { myRed = 255, myGreen = 255, myBlue = 255; } + + /// Constructs a color from the given RGB value + ArColor(ArTypes::Byte4 rgbValue) + { + myRed = (rgbValue & 0xFF0000) >> 16; + myGreen = (rgbValue & 0x00FF00) >> 8; + myBlue = (rgbValue & 0x0000FF); + } + + /// Destructor + virtual ~ArColor() {} + /// Gets the red value (uses full range of 0-255) + unsigned char getRed(void) { return myRed; } + /// Gets the green value (uses full range of 0-255) + unsigned char getGreen(void) { return myGreen; } + /// Gets the blue value (uses full range of 0-255) + unsigned char getBlue(void) { return myBlue; } + /// Gets the color in a byte 4 for putting into a buffer + ArTypes::Byte4 colorToByte4(void) + { return ((myRed << 16) | (myGreen << 8) | myBlue); } +protected: + unsigned char myRed; + unsigned char myGreen; + unsigned char myBlue; + +}; + + +/** Describes general properties of a figure to be drawn on screen. + * (The actual location/geometry data of the figure is stored elsewhere and may + * change frequently) + * + * The following shapes are currently recognized: + *
    + *
  • "polyDots" - a set of small filled circles centered on each point. Each + * ellipse is "size" mm in diameter. (Example: laser)
  • + *
  • "polyArrows" - a set of small arrows that terminate on each point and + * point towards the robot. + * Each arrow is "size" mm in length. (Example: sonar)
  • + *
  • "polyLine" - a line through each of the points. The line is "size" + * pixels wide. (Example: path)
  • + *
  • "polyPoints" - a set of one pixel points. (Example: localization)
  • + *
  • "polySegments" - a set of line segments. For an array of n points, + * n/2 segments are drawn. Each segment is drawn from + * array[i] to array[i+1] (with i starting at 0). The + * segments are "size" pixels wide.
  • + *
+ * + * The primary color determines what color the shape is. No shapes currently use + * the secondary color (but future shapes may, or these shapes may be extended + * in the future to use it). + * + * The layer is an arbitrary int identifier that must be greater than 30 and + * less than 100. (Layers below 30 are considered part of the map data, i.e. + * not associated with a particular robot.) The robot is drawn on layer 50. + * Any items that are to be drawn on top of the robot should have a layer + * number greater than 50. By default, range devices begin on layer 70. + * + * The visibility attribute specifies + * whether the data is to be displayed by default, and whether the user is allowed + * to change the display. The following visibilities are currently supported: + *
    + *
  • "AlwaysOn" - item is always displayed
  • + *
  • "DefaultOn" - item is visible by default, but the user may hide it
  • + *
  • "DefaultOff" - item is hidden by default but the user may show it
  • + *
  • "AlwaysOff" - item is always hidden
  • + *
+ * The default visibility is "DefaultOn". + * +**/ +class ArDrawingData +{ +public: + + enum { + DEFAULT_REFRESH_TIME = 200 ///< Default number of ms between data refresh requests + }; + + + /// Constructor + /** + @param shape the name of the shape to draw (see above / MobileEyes docs for meaning) + @param primaryColor the main color (meaning depends on shape) + @param size the size (meaning varies depends on shape) + @param layer the layer to draw on (see above / MobileEyes docs for meaning) + @param defaultRefreshTime how often we want to draw it in ms + @param visibility a string that indicates whether the data is visible + whether the user is allowed to change the visibility (see above / MobileEyes + docs for valid values). + **/ + ArDrawingData(const char *shape, + ArColor primaryColor, + int size, + int layer, + unsigned int defaultRefreshTime = DEFAULT_REFRESH_TIME, + const char *visibility = "DefaultOn") : + myShape(shape), + myPrimaryColor(primaryColor), + mySize(size), + myLayer(layer), + myDefaultRefreshTime(defaultRefreshTime), + mySecondaryColor(ArColor(0,0,0)), + myVisibility(visibility) + { + } + + /// Constructor + /** + @param shape the name of the shape to draw (see above / MobileEyes docs for meaning) + @param primaryColor the main color (meaning depends on shape) + @param size the size (meaning varies depends on shape) + @param layer the layer to draw on (see above / MobileEyes docs for meaning) + @param defaultRefreshTime how often we want to draw it in ms + @param secondaryColor the secondary color (meaning depends on shape) + @param visibility a string that indicates whether the data is visible + whether the user is allowed to change the visibility (see above / MobileEyes + docs for valid values). + **/ + ArDrawingData(const char *shape, + ArColor primaryColor, + int size, + int layer, + unsigned int defaultRefreshTime, + ArColor secondaryColor, + const char *visibility = "DefaultOn") + { + myShape = shape; + myPrimaryColor = primaryColor; + mySize = size; + myLayer = layer; + myDefaultRefreshTime = defaultRefreshTime; + mySecondaryColor = secondaryColor; + myVisibility = visibility; + } + /// Destructor + virtual ~ArDrawingData() {} + /// Returns the shape of data to draw + const char * getShape(void) { return myShape.c_str(); } + /// Gets the primary color (meaning depending on shape) + ArColor getPrimaryColor(void) { return myPrimaryColor; } + /// Gets the size (meaning depends on shape, but its in mm) + int getSize(void) { return mySize; } + /// Gets the layer to draw at (see MobileEyes docs for what layer means) + int getLayer(void) { return myLayer; } + /// Gets how often this data should be drawn (0 == only when explicitly sent) + unsigned int getDefaultRefreshTime(void) { return myDefaultRefreshTime; } + /// Gets the secondary color (meaning depends on shape) + ArColor getSecondaryColor(void) { return mySecondaryColor; } + /// Gets the visibility of the drawing data + const char *getVisibility(void) { return myVisibility.c_str(); } + + /// Sets the shape of data to draw + void setShape(const char *shape) { myShape = shape; } + /// Sets the primary color (meaning depends on shape) + void setPrimaryColor(ArColor color) { myPrimaryColor = color; } + /// Sets the size (meaning depends on shape, but its in mm) + void setSize(int size) { mySize = size; } + /// Sets the layer (see MobileEyes for docs on what layer means) + void setLayer(int layer) { myLayer = layer; } + /// Gets how often this data should be drawn (0 == only when explicitly sent) + void setDefaultRefreshTime(unsigned int refreshTime) + { myDefaultRefreshTime = refreshTime; } + /// Sets the secondary color (meaning depends on shape) + void setSecondaryColor(ArColor color) { mySecondaryColor = color; } + /// Sets the visibility of the drawing data + void setVisibility(const char *visibility) { myVisibility = visibility; } +protected: + std::string myShape; + ArColor myPrimaryColor; + int mySize; + int myLayer; + unsigned int myDefaultRefreshTime; + ArColor mySecondaryColor; + std::string myVisibility; +}; + +#endif diff --git a/Legacy/Aria/include/ArExitErrorSource.h b/Legacy/Aria/include/ArExitErrorSource.h new file mode 100644 index 0000000..85ed2d3 --- /dev/null +++ b/Legacy/Aria/include/ArExitErrorSource.h @@ -0,0 +1,69 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef AREXITERRORSOURCE_H +#define AREXITERRORSOURCE_H + +/// Small interface for obtaining exit-on-error information +/** + * ArExitErrorSource may be implemented by classes that wish to + * provide information if and when they cause an erroneous + * application exit. The use of this interface is entirely at + * the discretion of the application. Aria does not invoke its + * methods. +**/ +class ArExitErrorSource +{ +public: + + /// Constructor + ArExitErrorSource() {} + + /// Destructor + virtual ~ArExitErrorSource() {} + + /// Returns a textual description of the error source. + /** + * @param buf a char array in which the method puts the output + * error description + * @param bufLen the int number of char's in the array + * @return bool true if the description was successfully written; + * false if an error occurred + **/ + virtual bool getExitErrorDesc(char *buf, int bufLen) = 0; + + /// Returns the error code used for the exit call + /** + * Ideally, the returned error code should be unique across all + * error sources. (Past implementations have the method spec and + * body on a single line so that it's easily searchable... Current + * implementations have that OR this string on a line so that it'll + * show up searchable easily still). + **/ + virtual int getExitErrorCode() const = 0; + +}; // end class ArExitErrorSource + +#endif // AREXITERRORSOURCE_H diff --git a/Legacy/Aria/include/ArExport.h b/Legacy/Aria/include/ArExport.h new file mode 100644 index 0000000..38beb9f --- /dev/null +++ b/Legacy/Aria/include/ArExport.h @@ -0,0 +1,51 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef AREXPORT_H +#define AREXPORT_H + +// Including this header file forces AREXPORT to be defined as the dllexport declaration in Windows DLL builds. +// It should only be included in source files in ARIA and other libraries. Header files should include ariaTypedefs instead. + +#if (defined(_WIN32) || defined(WIN32)) && !defined(MINGW) + +#ifndef SWIG +#ifndef ARIA_STATIC +#undef AREXPORT +#define AREXPORT _declspec(dllexport) +#else // ARIA_STATIC +#define AREXPORT +#endif // ARIA_STATIC +#endif // SWIG + +#else // WIN32 + +#define AREXPORT + +#endif // WIN32 + +#endif // AREXPORT_H + + diff --git a/Legacy/Aria/include/ArFileParser.h b/Legacy/Aria/include/ArFileParser.h new file mode 100644 index 0000000..0c68b76 --- /dev/null +++ b/Legacy/Aria/include/ArFileParser.h @@ -0,0 +1,224 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARFILEPARSER_H +#define ARFILEPARSER_H + +#include "ariaTypedefs.h" +#include "ArArgumentParser.h" +#include "ArFunctor.h" +#include "ariaUtil.h" + +/// Class for parsing files more easily +/** + This class helps parse text files based on keywords followed by various + values. + To use it, add functors of different types + of arguments with addHandler(), then call parseFile() to parse the file + and invoke the various functors as items are read from the file. + parseFile() returns true if there were no errors parsing and false if + there were errors. + + One side feature is that you can have ONE handler for the keyword + NULL, and if there is a line read that isn't entirely comments or + whitespace that handler will be given the line. There isn't an + explicit set for them since then there'd be another set of 5 adds. + + There should be some whitespace after keywords in the file, and any + semicolon (;) or hash mark (#) will act as a comment with the rest of the line + ignored. (Alternative comment delimeters may be set using + setCommentDelimeters()). If no handler exists for the first word the line is + passed to the handler above for NULL. You can't have any lines + longer than 10000 characters or keywords longer than 512 characters + (though I don't know why you'd have either). If you have more than + 2048 words on a line you'll have problems as well. + + @ingroup OptionalClasses + + * @note ArFileParser does not escape any special characters when writing or + * loading to/from a file. Therefore in general keywords, values, + * and comments must not contain characters which have special meaning + * in a config file, such as '#', ';', tab or newline. + **/ +class ArFileParser +{ +public: + + /// Constructor + AREXPORT ArFileParser(const char *baseDirectory = "./", + bool isPreCompressQuotes = false); + + + + /// Destructor + AREXPORT ~ArFileParser(void); + + /// Adds a functor to handle a keyword that wants an easily parsable string + AREXPORT bool addHandler(const char *keyword, + ArRetFunctor1 *functor); + /// Adds a functor to handle a keyword that wants an easily parsable string and returns error messages + AREXPORT bool addHandlerWithError(const char *keyword, + ArRetFunctor3 *functor); + /// Removes a handler for a keyword + AREXPORT bool remHandler(const char *keyword, bool logIfCannotFind = true); + /// Removes any handlers with this functor + AREXPORT bool remHandler(ArRetFunctor1 *functor); + /// Removes any handlers with this functor + AREXPORT bool remHandler( + ArRetFunctor3 *functor); + /* this shouldn't be needed and would be inelegant with the new scheme, + if someone needs it let us know and I'll update it somehow + /// Gets handler data for some keyword + AREXPORT ArRetFunctor1 *getHandler(const char *keyword); + */ + + AREXPORT void setPreParseFunctor(ArFunctor1 *functor); + + + /// Opens, parses, and then closes the specified file. + AREXPORT bool parseFile(const char *fileName, bool continueOnErrors = true, + bool noFileNotFoundMessage = false, + char *errorBuffer = NULL, size_t errorBufferLen = 0); + + /// Parses an open file; the file is not closed by this method. + /** + * @param file the open FILE* to be parsed; must not be NULL + * @param buffer a non-NULL char array in which to read the file + * @param bufferLength the number of chars in the buffer; must be greater than 0 + * @param continueOnErrors a bool set to true if parsing should continue + * even after an error is detected + **/ + AREXPORT bool parseFile(FILE *file, char *buffer, int bufferLength, + bool continueOnErrors = true, + char *errorBuffer = NULL, size_t errorBufferLen = 0); + + + /// If parseFile is currently in progress, then terminates it as soon as possible. + AREXPORT void cancelParsing(); + + + /// Gets the base directory + AREXPORT const char *getBaseDirectory(void) const; + /// Sets the base directory + AREXPORT void setBaseDirectory(const char *baseDirectory); + + /// Sets the strings used to mark comments in the file to be parsed. + AREXPORT void setCommentDelimiters(const std::list &delimiters); + + /// Clears the strings used to mark comments in the file to be parsed. + AREXPORT void clearCommentDelimiters(); + + + /// Function to parse a single line + AREXPORT bool parseLine(char *line, char *errorBuffer = NULL, + size_t errorBufferLen = 0); + /// Function to reset counters + AREXPORT void resetCounters(void); + /// Sets the maximum number of arguments in a line we can expect + AREXPORT void setMaxNumArguments(size_t maxNumArguments = 512) + { myMaxNumArguments = maxNumArguments; } + /// Turn on this flag to reduce the number of verbose log messages. + AREXPORT void setQuiet(bool isQuiet); + +protected: + + /// Returns true if cancelParsing() has been called during parseFile() + bool isInterrupted(); + + class HandlerCBType + { + public: + HandlerCBType( + ArRetFunctor3 *functor) + { + myCallbackWithError = functor; + myCallback = NULL; + } + HandlerCBType(ArRetFunctor1 *functor) + { + myCallbackWithError = NULL; + myCallback = functor; + } + ~HandlerCBType() {} + bool call(ArArgumentBuilder *arg, char *errorBuffer, + size_t errorBufferLen) + { + if (myCallbackWithError != NULL) + return myCallbackWithError->invokeR(arg, errorBuffer, errorBufferLen); + else if (myCallback != NULL) + return myCallback->invokeR(arg); + // if we get here there's a problem + ArLog::log(ArLog::Terse, "ArFileParser: Horrible problem with process callbacks"); + return false; + } + bool haveFunctor( + ArRetFunctor3 *functor) + { + if (myCallbackWithError == functor) + return true; + else + return false; + } + bool haveFunctor(ArRetFunctor1 *functor) + { + if (myCallback == functor) + return true; + else + return false; + } + const char *getName(void) + { + if (myCallbackWithError != NULL) + return myCallbackWithError->getName(); + else if (myCallback != NULL) + return myCallback->getName(); + // if we get here there's a problem + ArLog::log(ArLog::Terse, "ArFileParser: Horrible problem with process callback names"); + return NULL; + } + protected: + ArRetFunctor3 *myCallbackWithError; + ArRetFunctor1 *myCallback; + }; + size_t myMaxNumArguments; + int myLineNumber; + std::string myBaseDir; + std::list myCommentDelimiterList; + + ArFunctor1 *myPreParseFunctor; + + std::map myMap; + // handles that NULL case + HandlerCBType *myRemainderHandler; + bool myIsQuiet; + bool myIsPreCompressQuotes; + bool myIsInterrupted; + ArMutex myInterruptMutex; +}; + +#endif // ARFILEPARSER_H + + diff --git a/Legacy/Aria/include/ArForbiddenRangeDevice.h b/Legacy/Aria/include/ArForbiddenRangeDevice.h new file mode 100644 index 0000000..357b6e0 --- /dev/null +++ b/Legacy/Aria/include/ArForbiddenRangeDevice.h @@ -0,0 +1,74 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARFORBIDDENRANGEDEVICE_H +#define ARFORBIDDENRANGEDEVICE_H + +#include "ariaTypedefs.h" +#include "ArRangeDevice.h" +#include "ArMapInterface.h" + +/// Class that takes forbidden lines and turns them into range readings +/// @ingroup OptionalClasses +class ArForbiddenRangeDevice : public ArRangeDevice +{ +public: + /// Constructor + AREXPORT ArForbiddenRangeDevice(ArMapInterface *armap, + double distanceIncrement = 100, + unsigned int maxRange = 4000, + const char *name = "forbidden"); + /// Destructor + AREXPORT virtual ~ArForbiddenRangeDevice(); + /// Saves the forbidden lines from the map + AREXPORT void processMap(void); + /// Remakes the readings + AREXPORT void processReadings(void); + /// Sets the robot pointer and attachs its process function + AREXPORT virtual void setRobot(ArRobot *robot); + + /// Enable readings + AREXPORT void enable(void); + /// Disables readings until reenabled + AREXPORT void disable(void); + /// Sees if this device is active or not + AREXPORT bool isEnabled(void) const { return myIsEnabled;; } + /// Gets a callback to enable the device + AREXPORT ArFunctor *getEnableCB(void) { return &myEnableCB; } + /// Gets a callback to disable the device + AREXPORT ArFunctor *getDisableCB(void) { return &myDisableCB; } +protected: + ArMutex myDataMutex; + ArMapInterface *myMap; + double myDistanceIncrement; + std::list mySegments; + ArFunctorC myProcessCB; + ArFunctorC myMapChangedCB; + bool myIsEnabled; + ArFunctorC myEnableCB; + ArFunctorC myDisableCB; +}; + +#endif // ARFORBIDDENRANGEDEVICE_H diff --git a/Legacy/Aria/include/ArFunctor.h b/Legacy/Aria/include/ArFunctor.h new file mode 100644 index 0000000..71a38a6 --- /dev/null +++ b/Legacy/Aria/include/ArFunctor.h @@ -0,0 +1,5415 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARFUNCTOR_H +#define ARFUNCTOR_H + +#include "ariaTypedefs.h" +#include "ariaOSDef.h" +#include +#include + +/// An object which allows storing a generalized reference to a method with an object instance to call later (used for callback functions) +/** + Functors are meant to encapsulate the idea of a pointer to a function + which is a member of a class. To use a pointer to a member function, + you must have a C style function pointer, 'void(Class::*)()', and a + pointer to an instance of the class in which the function is a member + of. This is because all non-static member functions must have a 'this' + pointer. If they dont and if the member function uses any member data + or even other member functions it will not work right and most likely + crash. This is because the 'this' pointer is not the correct value + and is most likely a random uninitialized value. The virtue of static + member functions is that they do not require a 'this' pointer to be run. + But the compiler will never let you access any member data or functions + from within a static member function. + + Because of the design of C++ never allowed for encapsulating these two + pointers together into one language supported construct, this has to be + done by hand. For conviences sake, there are functors (ArGlobalFunctor, + ArGlobalRetFunctor) which take a pure C style function pointer + (a non-member function). This is in case you want to use a functor that + refers to a global C style function. + + Aria makes use of functors by using them as callback functions. Since + Aria is programmed using the object oriented programming paradigm, all + the callback functions need to be tied to an object and a particular + instance. Thus the need for functors. Most of the use of callbacks simply + take an ArFunctor, which is the base class for all the functors. This + class only has the ability to invoke a functor. All the derivitave + functors have the ability to invoke the correct function on the correct + object. + + Because functions have different signatures because they take different + types of parameters and have different number of parameters, templates + were used to create the functors. These are the base classes for the + functors. These classes encapsulate everything except for the class + type that the member function is a member of. This allows someone to + accept a functor of type ArFunctor1 which has one parameter of type + 'int'. But they never have to know that the function is a member function + of class 'SomeUnknownType'. These classes are: + + ArFunctor, ArFunctor1, ArFunctor2, ArFunctor3 + ArRetFunctor, ArRetFunctor1, ArRetFunctor2, ArRetFunctor3 + + These 8 functors are the only thing a piece of code that wants a functor + will ever need. But these classes are abstract classes and can not be + instantiated. On the other side, the piece of code that wants to be + called back will need the functor classes that know about the class type. + These functors are: + + ArFunctorC, ArFunctor1C, ArFunctor2C, ArFunctor3C + ArRetFunctorC, ArRetFunctor1C, ArRetFunctor2C, ArRetFunctor3C + + These functors are meant to be instantiated and passed of to a piece of + code that wants to use them. That piece of code should only know the + functor as one of the functor classes without the 'C' in it. + + Note that you can create these FunctorC instances with default + arguments that are then used when the invoke is called without those + arguments... These are quite useful since if you have a class that + expects an ArFunctor you can make an ArFunctor1C with default + arguments and pass it as an ArFunctor... and it will get called with + that default argument, this is useful for having multiple functors + use the same function with different arguments and results (just + takes one functor each). + + Functors now have a getName() method, this is useful as an aid to debugging, + allowing you to display the name of some functor being used. + + @javanote You can subclass ArFunctor and override invoke(). + + @see @ref functorExample.cpp + + @ingroup ImportantClasses +**/ +class ArFunctor +{ +public: + + /// Destructor + virtual ~ArFunctor() {} + + /// Invokes the functor + virtual void invoke(void) = 0; + + /// Gets the name of the functor + virtual const char *getName(void) { return myName.c_str(); } + + /// Sets the name of the functor + virtual void setName(const char *name) { myName = name; } + +#ifndef SWIG + /// Sets the name of the functor with formatting + /** @swigomit use setName() */ + virtual void setNameVar(const char *name, ...) + { + char arg[2048]; + va_list ptr; + va_start(ptr, name); + vsnprintf(arg, sizeof(arg), name, ptr); + arg[sizeof(arg) - 1] = '\0'; + va_end(ptr); + return setName(arg); + } +#endif + +protected: + std::string myName; +}; + +/// Base class for functors with 1 parameter +/** + This is the base class for functors with 1 parameter. Code that has a + reference to a functor that takes 1 parameter should use this class + name. This allows the code to know how to invoke the functor without + knowing which class the member function is in. + + For an overall description of functors, see ArFunctor. +*/ +template +class ArFunctor1 : public ArFunctor +{ +public: + + /// Destructor + virtual ~ArFunctor1() {} + + /// Invokes the functor + virtual void invoke(void) = 0; + + /// Invokes the functor + /** + @param p1 first parameter + */ + virtual void invoke(P1 p1) = 0; +}; + +/// Base class for functors with 2 parameters +/** + This is the base class for functors with 2 parameters. Code that has a + reference to a functor that takes 2 parameters should use this class + name. This allows the code to know how to invoke the functor without + knowing which class the member function is in. + + For an overall description of functors, see ArFunctor. +*/ +template +class ArFunctor2 : public ArFunctor1 +{ +public: + + /// Destructor + virtual ~ArFunctor2() {} + + /// Invokes the functor + virtual void invoke(void) = 0; + + /// Invokes the functor + /** + @param p1 first parameter + */ + virtual void invoke(P1 p1) = 0; + + /// Invokes the functor + /** + @param p1 first parameter + @param p2 second parameter + */ + virtual void invoke(P1 p1, P2 p2) = 0; +}; + +/// Base class for functors with 3 parameters +/** + This is the base class for functors with 3 parameters. Code that has a + reference to a functor that takes 3 parameters should use this class + name. This allows the code to know how to invoke the functor without + knowing which class the member function is in. + + For an overall description of functors, see ArFunctor. +*/ +template +class ArFunctor3 : public ArFunctor2 +{ +public: + + /// Destructor + virtual ~ArFunctor3() {} + + /// Invokes the functor + virtual void invoke(void) = 0; + + /// Invokes the functor + /** + @param p1 first parameter + */ + virtual void invoke(P1 p1) = 0; + + /// Invokes the functor + /** + @param p1 first parameter + @param p2 second parameter + */ + virtual void invoke(P1 p1, P2 p2) = 0; + + /// Invokes the functor + /** + @param p1 first parameter + @param p2 second parameter + @param p3 third parameter + */ + virtual void invoke(P1 p1, P2 p2, P3 p3) = 0; +}; + + + +/// Base class for functors with 4 parameters +/** + This is the base class for functors with 4 parameters. Code that has a + reference to a functor that takes 4 parameters should use this class + name. This allows the code to know how to invoke the functor without + knowing which class the member function is in. + + For an overall description of functors, see ArFunctor. +*/ +template +class ArFunctor4 : public ArFunctor3 +{ +public: + + /// Destructor + virtual ~ArFunctor4() {} + + /// Invokes the functor + virtual void invoke(void) = 0; + + /// Invokes the functor + /** + @param p1 first parameter + */ + virtual void invoke(P1 p1) = 0; + + /// Invokes the functor + /** + @param p1 first parameter + @param p2 second parameter + */ + virtual void invoke(P1 p1, P2 p2) = 0; + + /// Invokes the functor + /** + @param p1 first parameter + @param p2 second parameter + @param p3 third parameter + */ + virtual void invoke(P1 p1, P2 p2, P3 p3) = 0; + + /// Invokes the functor + /** + @param p1 first parameter + @param p2 second parameter + @param p3 third parameter + @param p4 fourth parameter + */ + virtual void invoke(P1 p1, P2 p2, P3 p3, P4 p4) = 0; + +}; + + +/// Base class for functors with 5 parameters +/** + This is the base class for functors with 5 parameters. Code that has a + reference to a functor that takes 5 parameters should use this class + name. This allows the code to know how to invoke the functor without + knowing which class the member function is in. + + For an overall description of functors, see ArFunctor. +*/ +template +class ArFunctor5 : public ArFunctor4 +{ +public: + + /// Destructor + virtual ~ArFunctor5() {} + + /// Invokes the functor + virtual void invoke(void) = 0; + + /// Invokes the functor + /** + @param p1 first parameter + */ + virtual void invoke(P1 p1) = 0; + + /// Invokes the functor + /** + @param p1 first parameter + @param p2 second parameter + */ + virtual void invoke(P1 p1, P2 p2) = 0; + + /// Invokes the functor + /** + @param p1 first parameter + @param p2 second parameter + @param p3 third parameter + */ + virtual void invoke(P1 p1, P2 p2, P3 p3) = 0; + + /// Invokes the functor + /** + @param p1 first parameter + @param p2 second parameter + @param p3 third parameter + @param p4 fourth parameter + */ + virtual void invoke(P1 p1, P2 p2, P3 p3, P4 p4) = 0; + + /// Invokes the functor + /** + @param p1 first parameter + @param p2 second parameter + @param p3 third parameter + @param p4 fourth parameter + @param p4 fifth parameter + */ + virtual void invoke(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) = 0; + +}; + + + + +/// Base class for functors with a return value +/** + This is the base class for functors with a return value. Code that has a + reference to a functor that returns a value should use this class + name. This allows the code to know how to invoke the functor without + knowing which class the member function is in. + + For an overall description of functors, see ArFunctor. + + @javanote To create the equivalent of ArRetFunctor, you can + subclass ArRetFunctor_Bool and override invoke(bool) + +*/ +template +class ArRetFunctor : public ArFunctor +{ +public: + + /// Destructor + virtual ~ArRetFunctor() {} + + /// Invokes the functor + virtual void invoke(void) {invokeR();} + + /// Invokes the functor with return value + virtual Ret invokeR(void) = 0; +}; + +/// Base class for functors with a return value with 1 parameter +/** + This is the base class for functors with a return value and take 1 + parameter. Code that has a reference to a functor that returns a value + and takes 1 parameter should use this class name. This allows the code + to know how to invoke the functor without knowing which class the member + function is in. + + For an overall description of functors, see ArFunctor. +*/ +template +class ArRetFunctor1 : public ArRetFunctor +{ +public: + + /// Destructor + virtual ~ArRetFunctor1() {} + + /// Invokes the functor with return value + virtual Ret invokeR(void) = 0; + + /// Invokes the functor with return value + /** + @param p1 first parameter + */ + virtual Ret invokeR(P1 p1) = 0; +}; + +/// Base class for functors with a return value with 2 parameters +/** + This is the base class for functors with a return value and take 2 + parameters. Code that has a reference to a functor that returns a value + and takes 2 parameters should use this class name. This allows the code + to know how to invoke the functor without knowing which class the member + function is in. + + For an overall description of functors, see ArFunctor. +*/ +template +class ArRetFunctor2 : public ArRetFunctor1 +{ +public: + + /// Destructor + virtual ~ArRetFunctor2() {} + + /// Invokes the functor with return value + virtual Ret invokeR(void) = 0; + + /// Invokes the functor with return value + /** + @param p1 first parameter + */ + virtual Ret invokeR(P1 p1) = 0; + + /// Invokes the functor with return value + /** + @param p1 first parameter + @param p2 second parameter + */ + virtual Ret invokeR(P1 p1, P2 p2) = 0; +}; + +/// Base class for functors with a return value with 3 parameters +/** + This is the base class for functors with a return value and take 3 + parameters. Code that has a reference to a functor that returns a value + and takes 3 parameters should use this class name. This allows the code + to know how to invoke the functor without knowing which class the member + function is in. + + For an overall description of functors, see ArFunctor. +*/ +template +class ArRetFunctor3 : public ArRetFunctor2 +{ +public: + + /// Destructor + virtual ~ArRetFunctor3() {} + + /// Invokes the functor with return value + virtual Ret invokeR(void) = 0; + + /// Invokes the functor with return value + /** + @param p1 first parameter + */ + virtual Ret invokeR(P1 p1) = 0; + + /// Invokes the functor with return value + /** + @param p1 first parameter + @param p2 second parameter + */ + virtual Ret invokeR(P1 p1, P2 p2) = 0; + + /// Invokes the functor with return value + /** + @param p1 first parameter + @param p2 second parameter + @param p3 third parameter + */ + virtual Ret invokeR(P1 p1, P2 p2, P3 p3) = 0; +}; + + + + +/// Base class for functors with a return value with 4 parameters +/** + This is the base class for functors with a return value and take 4 + parameters. Code that has a reference to a functor that returns a value + and takes 4 parameters should use this class name. This allows the code + to know how to invoke the functor without knowing which class the member + function is in. + + For an overall description of functors, see ArFunctor. +*/ +template +class ArRetFunctor4 : public ArRetFunctor3 +{ +public: + + /// Destructor + virtual ~ArRetFunctor4() {} + + /// Invokes the functor with return value + virtual Ret invokeR(void) = 0; + + /// Invokes the functor with return value + /** + @param p1 first parameter + */ + virtual Ret invokeR(P1 p1) = 0; + + /// Invokes the functor with return value + /** + @param p1 first parameter + @param p2 second parameter + */ + virtual Ret invokeR(P1 p1, P2 p2) = 0; + + /// Invokes the functor with return value + /** + @param p1 first parameter + @param p2 second parameter + @param p3 third parameter + */ + virtual Ret invokeR(P1 p1, P2 p2, P3 p3) = 0; + + /// Invokes the functor with return value + /** + @param p1 first parameter + @param p2 second parameter + @param p3 third parameter + @param p4 fourth parameter + */ + virtual Ret invokeR(P1 p1, P2 p2, P3 p3, P4 p4) = 0; +}; + +/// Base class for functors with a return value with 5 parameters +/** + This is the base class for functors with a return value and take 5 + parameters. Code that has a reference to a functor that returns a value + and takes 5 parameters should use this class name. This allows the code + to know how to invoke the functor without knowing which class the member + function is in. + + For an overall description of functors, see ArFunctor. +*/ +template +class ArRetFunctor5 : public ArRetFunctor4 +{ +public: + + /// Destructor + virtual ~ArRetFunctor5() {} + + /// Invokes the functor with return value + virtual Ret invokeR(void) = 0; + + /// Invokes the functor with return value + /** + @param p1 first parameter + */ + virtual Ret invokeR(P1 p1) = 0; + + /// Invokes the functor with return value + /** + @param p1 first parameter + @param p2 second parameter + */ + virtual Ret invokeR(P1 p1, P2 p2) = 0; + + /// Invokes the functor with return value + /** + @param p1 first parameter + @param p2 second parameter + @param p3 third parameter + */ + virtual Ret invokeR(P1 p1, P2 p2, P3 p3) = 0; + + /// Invokes the functor with return value + /** + @param p1 first parameter + @param p2 second parameter + @param p3 third parameter + @param p4 fourth parameter + */ + virtual Ret invokeR(P1 p1, P2 p2, P3 p3, P4 p4) = 0; + + /// Invokes the functor with return value + /** + @param p1 first parameter + @param p2 second parameter + @param p3 third parameter + @param p4 fourth parameter + @param p4 fifth parameter + */ + virtual Ret invokeR(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) = 0; +}; + + + + + +////// +////// +////// +////// +////// +////// +////// ArFunctors for global functions. C style function pointers. +////// +////// +////// +////// +////// +////// + + +#ifndef SWIG +/// Functor for a global function with no parameters +/** + This is a class for global functions. This ties a C style function + pointer into the functor class hierarchy as a convience. Code that + has a reference to this class and treat it as an ArFunctor can use + it like any other functor. + + For an overall description of functors, see ArFunctor. + + @swigomit +*/ +class ArGlobalFunctor : public ArFunctor +{ +public: + + /// Constructor + ArGlobalFunctor() {} + /// Constructor - supply function pointer + /** + @param func global function pointer + */ + ArGlobalFunctor(void (*func)(void)) : myFunc(func) {} + /// Destructor + virtual ~ArGlobalFunctor() {} + + /// Invokes the functor + virtual void invoke(void) {(*myFunc)();} +protected: + + void (*myFunc)(void); +}; + +/// Functor for a global function with 1 parameter +/** + This is a class for global functions which take 1 parameter. This ties + a C style function pointer into the functor class hierarchy as a + convience. Code that has a reference to this class and treat it as + an ArFunctor can use it like any other functor. + + For an overall description of functors, see ArFunctor. +*/ +template +class ArGlobalFunctor1 : public ArFunctor1 +{ +public: + + /// Constructor + ArGlobalFunctor1() {} + /// Constructor - supply function pointer + /** + @param func global function pointer + */ + ArGlobalFunctor1(void (*func)(P1)) : + myFunc(func), myP1() {} + /// Constructor - supply function pointer, default parameters + /** + @param func global function pointer + @param p1 default first parameter + */ + ArGlobalFunctor1(void (*func)(P1), P1 p1) : + myFunc(func), myP1(p1) {} + + /// Destructor + virtual ~ArGlobalFunctor1() {} + + /// Invokes the functor + virtual void invoke(void) {(*myFunc)(myP1);} + + /// Invokes the functor + /** + @param p1 first parameter + */ + virtual void invoke(P1 p1) {(*myFunc)(p1);} + + /// Set the default parameter + /** + @param p1 default first parameter + */ + virtual void setP1(P1 p1) {myP1=p1;} + +protected: + + void (*myFunc)(P1); + P1 myP1; +}; + + +/// Functor for a global function with 2 parameters +/** + This is a class for global functions which take 2 parameters. This ties + a C style function pointer into the functor class hierarchy as a + convience. Code that has a reference to this class and treat it as + an ArFunctor can use it like any other functor. + + For an overall description of functors, see ArFunctor. +*/ +template +class ArGlobalFunctor2 : public ArFunctor2 +{ +public: + + /// Constructor + ArGlobalFunctor2() {} + + /// Constructor - supply function pointer + /** + @param func global function pointer + */ + ArGlobalFunctor2(void (*func)(P1, P2)) : + myFunc(func), myP1(), myP2() {} + + /// Constructor - supply function pointer, default parameters + /** + @param func global function pointer + @param p1 default first parameter + */ + ArGlobalFunctor2(void (*func)(P1, P2), P1 p1) : + myFunc(func), myP1(p1), myP2() {} + + /// Constructor - supply function pointer, default parameters + /** + @param func global function pointer + @param p1 default first parameter + @param p2 default second parameter + */ + ArGlobalFunctor2(void (*func)(P1, P2), P1 p1, P2 p2) : + myFunc(func), myP1(p1), myP2(p2) {} + + /// Destructor + virtual ~ArGlobalFunctor2() {} + + /// Invokes the functor + virtual void invoke(void) {(*myFunc)(myP1, myP2);} + + /// Invokes the functor + /** + @param p1 first parameter + */ + virtual void invoke(P1 p1) {(*myFunc)(p1, myP2);} + + /// Invokes the functor + /** + @param p1 first parameter + @param p2 second parameter + */ + virtual void invoke(P1 p1, P2 p2) {(*myFunc)(p1, p2);} + + /// Set the default parameter + /** + @param p1 default first parameter + */ + virtual void setP1(P1 p1) {myP1=p1;} + + /// Set the default 2nd parameter + /** + @param p2 default second parameter + */ + virtual void setP2(P2 p2) {myP2=p2;} + +protected: + + void (*myFunc)(P1, P2); + P1 myP1; + P2 myP2; +}; + +/// Functor for a global function with 3 parameters +/** + This is a class for global functions which take 3 parameters. This ties + a C style function pointer into the functor class hierarchy as a + convience. Code that has a reference to this class and treat it as + an ArFunctor can use it like any other functor. + + For an overall description of functors, see ArFunctor. +*/ +template +class ArGlobalFunctor3 : public ArFunctor3 +{ +public: + + /// Constructor + ArGlobalFunctor3() {} + + /// Constructor - supply function pointer + /** + @param func global function pointer + */ + ArGlobalFunctor3(void (*func)(P1, P2, P3)) : + myFunc(func), myP1(), myP2(), myP3() {} + + /// Constructor - supply function pointer, default parameters + /** + @param func global function pointer + @param p1 default first parameter + */ + ArGlobalFunctor3(void (*func)(P1, P2, P3), P1 p1) : + myFunc(func), myP1(p1), myP2(), myP3() {} + + /// Constructor - supply function pointer, default parameters + /** + @param func global function pointer + @param p1 default first parameter + @param p2 default second parameter + */ + ArGlobalFunctor3(void (*func)(P1, P2, P3), P1 p1, P2 p2) : + myFunc(func), myP1(p1), myP2(p2), myP3() {} + + /// Constructor - supply function pointer, default parameters + /** + @param func global function pointer + @param p1 default first parameter + @param p2 default second parameter + @param p3 default third parameter + */ + ArGlobalFunctor3(void (*func)(P1, P2, P3), P1 p1, P2 p2, P3 p3) : + myFunc(func), myP1(p1), myP2(p2), myP3(p3) {} + + /// Destructor + virtual ~ArGlobalFunctor3() {} + + /// Invokes the functor + virtual void invoke(void) {(*myFunc)(myP1, myP2, myP3);} + + /// Invokes the functor + /** + @param p1 first parameter + */ + virtual void invoke(P1 p1) {(*myFunc)(p1, myP2, myP3);} + + /// Invokes the functor + /** + @param p1 first parameter + @param p2 second parameter + */ + virtual void invoke(P1 p1, P2 p2) {(*myFunc)(p1, p2, myP3);} + + /// Invokes the functor + /** + @param p1 first parameter + @param p2 second parameter + @param p3 third parameter + */ + virtual void invoke(P1 p1, P2 p2, P3 p3) {(*myFunc)(p1, p2, p3);} + + /// Set the default parameter + /** + @param p1 default first parameter + */ + virtual void setP1(P1 p1) {myP1=p1;} + + /// Set the default 2nd parameter + /** + @param p2 default second parameter + */ + virtual void setP2(P2 p2) {myP2=p2;} + + /// Set the default third parameter + /** + @param p3 default third parameter + */ + virtual void setP3(P3 p3) {myP3=p3;} + +protected: + + void (*myFunc)(P1, P2, P3); + P1 myP1; + P2 myP2; + P3 myP3; +}; + + + + + +/// Functor for a global function with 4 parameters +/** + This is a class for global functions which take 4 parameters. This ties + a C style function pointer into the functor class hierarchy as a + convience. Code that has a reference to this class and treat it as + an ArFunctor can use it like any other functor. + + For an overall description of functors, see ArFunctor. +*/ +template +class ArGlobalFunctor4 : public ArFunctor4 +{ +public: + + /// Constructor + ArGlobalFunctor4() {} + + /// Constructor - supply function pointer + /** + @param func global function pointer + */ + ArGlobalFunctor4(void (*func)(P1, P2, P3, P4)) : + myFunc(func), myP1(), myP2(), myP3(), myP4() {} + + /// Constructor - supply function pointer, default parameters + /** + @param func global function pointer + @param p1 default first parameter + */ + ArGlobalFunctor4(void (*func)(P1, P2, P3, P4), P1 p1) : + myFunc(func), myP1(p1), myP2(), myP3(), myP4() {} + + /// Constructor - supply function pointer, default parameters + /** + @param func global function pointer + @param p1 default first parameter + @param p2 default second parameter + */ + ArGlobalFunctor4(void (*func)(P1, P2, P3, P4), P1 p1, P2 p2) : + myFunc(func), myP1(p1), myP2(p2), myP3(), myP4() {} + + /// Constructor - supply function pointer, default parameters + /** + @param func global function pointer + @param p1 default first parameter + @param p2 default second parameter + @param p3 default third parameter + */ + ArGlobalFunctor4(void (*func)(P1, P2, P3, P4), P1 p1, P2 p2, P3 p3) : + myFunc(func), myP1(p1), myP2(p2), myP3(p3), myP4() {} + + /// Constructor - supply function pointer, default parameters + /** + @param func global function pointer + @param p1 default first parameter + @param p2 default second parameter + @param p3 default third parameter + @param p4 default fourth parameter + */ + ArGlobalFunctor4(void (*func)(P1, P2, P3, P4), P1 p1, P2 p2, P3 p3, P4 p4) : + myFunc(func), myP1(p1), myP2(p2), myP3(p3), myP4(p4) {} + + /// Destructor + virtual ~ArGlobalFunctor4() {} + + /// Invokes the functor + virtual void invoke(void) {(*myFunc)(myP1, myP2, myP3, myP4);} + + /// Invokes the functor + /** + @param p1 first parameter + */ + virtual void invoke(P1 p1) {(*myFunc)(p1, myP2, myP3, myP4);} + + /// Invokes the functor + /** + @param p1 first parameter + @param p2 second parameter + */ + virtual void invoke(P1 p1, P2 p2) {(*myFunc)(p1, p2, myP3, myP4);} + + /// Invokes the functor + /** + @param p1 first parameter + @param p2 second parameter + @param p3 third parameter + */ + virtual void invoke(P1 p1, P2 p2, P3 p3) {(*myFunc)(p1, p2, p3, myP4);} + + /// Invokes the functor + /** + @param p1 first parameter + @param p2 second parameter + @param p3 third parameter + @param p4 fourth parameter + */ + virtual void invoke(P1 p1, P2 p2, P3 p3, P4 p4) {(*myFunc)(p1, p2, p3, p4);} + + /// Set the default parameter + /** + @param p1 default first parameter + */ + virtual void setP1(P1 p1) {myP1=p1;} + + /// Set the default 2nd parameter + /** + @param p2 default second parameter + */ + virtual void setP2(P2 p2) {myP2=p2;} + + /// Set the default third parameter + /** + @param p3 default third parameter + */ + virtual void setP3(P3 p3) {myP3=p3;} + + /// Set the default fourth parameter + /** + @param p4 default fourth parameter + */ + virtual void setP4(P4 p4) {myP4=p4;} + +protected: + + void (*myFunc)(P1, P2, P3, P4); + P1 myP1; + P2 myP2; + P3 myP3; + P4 myP4; +}; + + +/// Functor for a global function with 5 parameters +/** + This is a class for global functions which take 5 parameters. This ties + a C style function pointer into the functor class hierarchy as a + convience. Code that has a reference to this class and treat it as + an ArFunctor can use it like any other functor. + + For an overall description of functors, see ArFunctor. +*/ +template +class ArGlobalFunctor5 : public ArFunctor5 +{ +public: + + /// Constructor + ArGlobalFunctor5() {} + + /// Constructor - supply function pointer + /** + @param func global function pointer + */ + ArGlobalFunctor5(void (*func)(P1, P2, P3, P4, P5)) : + myFunc(func), myP1(), myP2(), myP3(), myP4(), myP5() {} + + /// Constructor - supply function pointer, default parameters + /** + @param func global function pointer + @param p1 default first parameter + */ + ArGlobalFunctor5(void (*func)(P1, P2, P3, P4, P5), P1 p1) : + myFunc(func), myP1(p1), myP2(), myP3(), myP4(), myP5() {} + + /// Constructor - supply function pointer, default parameters + /** + @param func global function pointer + @param p1 default first parameter + @param p2 default second parameter + */ + ArGlobalFunctor5(void (*func)(P1, P2, P3, P4, P5), P1 p1, P2 p2) : + myFunc(func), myP1(p1), myP2(p2), myP3(), myP4(), myP5() {} + + /// Constructor - supply function pointer, default parameters + /** + @param func global function pointer + @param p1 default first parameter + @param p2 default second parameter + @param p3 default third parameter + */ + ArGlobalFunctor5(void (*func)(P1, P2, P3, P4, P5), P1 p1, P2 p2, P3 p3) : + myFunc(func), myP1(p1), myP2(p2), myP3(p3), myP4(), myP5() {} + + /// Constructor - supply function pointer, default parameters + /** + @param func global function pointer + @param p1 default first parameter + @param p2 default second parameter + @param p3 default third parameter + @param p4 default fourth parameter + */ + ArGlobalFunctor5(void (*func)(P1, P2, P3, P4, P5), P1 p1, P2 p2, P3 p3, P4 p4) : + myFunc(func), myP1(p1), myP2(p2), myP3(p3), myP4(p4), myP5() {} + + /// Constructor - supply function pointer, default parameters + /** + @param func global function pointer + @param p1 default first parameter + @param p2 default second parameter + @param p3 default third parameter + @param p4 default fourth parameter + @param p5 default fifth parameter + */ + ArGlobalFunctor5(void (*func)(P1, P2, P3, P4, P5), P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) : + myFunc(func), myP1(p1), myP2(p2), myP3(p3), myP4(p4), myP5(p5) {} + + /// Destructor + virtual ~ArGlobalFunctor5() {} + + /// Invokes the functor + virtual void invoke(void) {(*myFunc)(myP1, myP2, myP3, myP4, myP5);} + + /// Invokes the functor + /** + @param p1 first parameter + */ + virtual void invoke(P1 p1) {(*myFunc)(p1, myP2, myP3, myP4, myP5);} + + /// Invokes the functor + /** + @param p1 first parameter + @param p2 second parameter + */ + virtual void invoke(P1 p1, P2 p2) {(*myFunc)(p1, p2, myP3, myP4, myP5);} + + /// Invokes the functor + /** + @param p1 first parameter + @param p2 second parameter + @param p3 third parameter + */ + virtual void invoke(P1 p1, P2 p2, P3 p3) {(*myFunc)(p1, p2, p3, myP4, myP5);} + + /// Invokes the functor + /** + @param p1 first parameter + @param p2 second parameter + @param p3 third parameter + @param p4 fourth parameter + */ + virtual void invoke(P1 p1, P2 p2, P3 p3, P4 p4) {(*myFunc)(p1, p2, p3, p4, myP5);} + + /// Invokes the functor + /** + @param p1 first parameter + @param p2 second parameter + @param p3 third parameter + @param p4 fourth parameter + @param p5 fifth parameter + */ + virtual void invoke(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) {(*myFunc)(p1, p2, p3, p4, p5);} + + /// Set the default parameter + /** + @param p1 default first parameter + */ + virtual void setP1(P1 p1) {myP1=p1;} + + /// Set the default 2nd parameter + /** + @param p2 default second parameter + */ + virtual void setP2(P2 p2) {myP2=p2;} + + /// Set the default third parameter + /** + @param p3 default third parameter + */ + virtual void setP3(P3 p3) {myP3=p3;} + + /// Set the default fourth parameter + /** + @param p4 default fourth parameter + */ + virtual void setP4(P4 p4) {myP4=p4;} + + /// Set the default fifth parameter + /** + @param p4 default fifth parameter + */ + virtual void setP5(P5 p5) {myP5=p5;} + +protected: + + void (*myFunc)(P1, P2, P3, P4, P5); + P1 myP1; + P2 myP2; + P3 myP3; + P4 myP4; + P5 myP5; +}; + +#endif // Omitting ArGlobalFunctor from Swig + + + + +////// +////// +////// +////// +////// +////// +////// ArFunctors for global functions, C style function pointers with return +////// return values. +////// +////// +////// +////// +////// +////// + +#ifndef SWIG + +/// Functor for a global function with return value +/** + This is a class for global functions which return a value. This ties + a C style function pointer into the functor class hierarchy as a + convience. Code that has a reference to this class and treat it as + an ArFunctor can use it like any other functor. + + For an overall description of functors, see ArFunctor. +*/ +template +class ArGlobalRetFunctor : public ArRetFunctor +{ +public: + + /// Constructor + ArGlobalRetFunctor() {} + + /// Constructor - supply function pointer + /** + @param func global function pointer + */ + ArGlobalRetFunctor(Ret (*func)(void)) : myFunc(func) {} + + /// Destructor + virtual ~ArGlobalRetFunctor() {} + + /// Invokes the functor with return value + virtual Ret invokeR(void) {return (*myFunc)();} + +protected: + + Ret (*myFunc)(void); +}; + + +/// Functor for a global function with 1 parameter and return value +/** + This is a class for global functions which take 1 parameter and return + a value. This ties a C style function pointer into the functor class + hierarchy as a convience. Code that has a reference to this class + and treat it as an ArFunctor can use it like any other functor. + + For an overall description of functors, see ArFunctor. +*/ +template +class ArGlobalRetFunctor1 : public ArRetFunctor1 +{ +public: + + /// Constructor + ArGlobalRetFunctor1() {} + + /// Constructor - supply function pointer + /** + @param func global function pointer + */ + ArGlobalRetFunctor1(Ret (*func)(P1)) : + myFunc(func), myP1() {} + + /// Constructor - supply function pointer, default parameters + /** + @param func global function pointer + @param p1 default first parameter + */ + ArGlobalRetFunctor1(Ret (*func)(P1), P1 p1) : + myFunc(func), myP1(p1) {} + + /// Destructor + virtual ~ArGlobalRetFunctor1() {} + + /// Invokes the functor with return value + virtual Ret invokeR(void) {return (*myFunc)(myP1);} + + /// Invokes the functor with return value + /** + @param p1 first parameter + */ + virtual Ret invokeR(P1 p1) {return (*myFunc)(p1);} + + /// Set the default parameter + /** + @param p1 default first parameter + */ + virtual void setP1(P1 p1) {myP1=p1;} + +protected: + + Ret (*myFunc)(P1); + P1 myP1; +}; + +/// Functor for a global function with 2 parameters and return value +/** + This is a class for global functions which take 2 parameters and return + a value. This ties a C style function pointer into the functor class + hierarchy as a convience. Code that has a reference to this class + and treat it as an ArFunctor can use it like any other functor. + + For an overall description of functors, see ArFunctor. +*/ +template +class ArGlobalRetFunctor2 : public ArRetFunctor2 +{ +public: + + /// Constructor + ArGlobalRetFunctor2() {} + + /// Constructor - supply function pointer + /** + @param func global function pointer + */ + ArGlobalRetFunctor2(Ret (*func)(P1, P2)) : + myFunc(func), myP1(), myP2() {} + + /// Constructor - supply function pointer, default parameters + /** + @param func global function pointer + @param p1 default first parameter + */ + ArGlobalRetFunctor2(Ret (*func)(P1, P2), P1 p1) : + myFunc(func), myP1(p1), myP2() {} + + /// Constructor - supply function pointer, default parameters + /** + @param func global function pointer + @param p1 default first parameter + @param p2 default second parameter + */ + ArGlobalRetFunctor2(Ret (*func)(P1, P2), P1 p1, P2 p2) : + myFunc(func), myP1(p1), myP2(p2) {} + + /// Destructor + virtual ~ArGlobalRetFunctor2() {} + + /// Invokes the functor with return value + virtual Ret invokeR(void) {return (*myFunc)(myP1, myP2);} + + /// Invokes the functor with return value + /** + @param p1 first parameter + */ + virtual Ret invokeR(P1 p1) {return (*myFunc)(p1, myP2);} + + /// Invokes the functor with return value + /** + @param p1 first parameter + @param p2 second parameter + */ + virtual Ret invokeR(P1 p1, P2 p2) {return (*myFunc)(p1, p2);} + + /// Set the default parameter + /** + @param p1 default first parameter + */ + virtual void setP1(P1 p1) {myP1=p1;} + + /// Set the default 2nd parameter + /** + @param p2 default second parameter + */ + virtual void setP2(P2 p2) {myP2=p2;} + +protected: + + Ret (*myFunc)(P1, P2); + P1 myP1; + P2 myP2; +}; + +/// Functor for a global function with 2 parameters and return value +/** + This is a class for global functions which take 2 parameters and return + a value. This ties a C style function pointer into the functor class + hierarchy as a convience. Code that has a reference to this class + and treat it as an ArFunctor can use it like any other functor. + + For an overall description of functors, see ArFunctor. +*/ +template +class ArGlobalRetFunctor3 : public ArRetFunctor3 +{ +public: + + /// Constructor + ArGlobalRetFunctor3() {} + + /// Constructor - supply function pointer + /** + @param func global function pointer + */ + ArGlobalRetFunctor3(Ret (*func)(P1, P2, P3)) : + myFunc(func), myP1(), myP2(), myP3() {} + + /// Constructor - supply function pointer, default parameters + /** + @param func global function pointer + @param p1 default first parameter + */ + ArGlobalRetFunctor3(Ret (*func)(P1, P2, P3), P1 p1) : + myFunc(func), myP1(p1), myP2(), myP3() {} + + /// Constructor - supply function pointer, default parameters + /** + @param func global function pointer + @param p1 default first parameter + @param p2 default second parameter + */ + ArGlobalRetFunctor3(Ret (*func)(P1, P2, P3), P1 p1, P2 p2) : + myFunc(func), myP1(p1), myP2(p2), myP3() {} + + /// Constructor - supply function pointer, default parameters + /** + @param func global function pointer + @param p1 default first parameter + @param p2 default second parameter + @param p3 default third parameter + */ + ArGlobalRetFunctor3(Ret (*func)(P1, P2, P3), P1 p1, P2 p2, P3 p3) : + myFunc(func), myP1(p1), myP2(p2), myP3(p3) {} + + /// Destructor + virtual ~ArGlobalRetFunctor3() {} + + /// Invokes the functor with return value + virtual Ret invokeR(void) {return (*myFunc)(myP1, myP2, myP3);} + + /// Invokes the functor with return value + /** + @param p1 first parameter + */ + virtual Ret invokeR(P1 p1) {return (*myFunc)(p1, myP2, myP3);} + + /// Invokes the functor with return value + /** + @param p1 first parameter + @param p2 second parameter + */ + virtual Ret invokeR(P1 p1, P2 p2) {return (*myFunc)(p1, p2, myP3);} + + /// Invokes the functor with return value + /** + @param p1 first parameter + @param p2 second parameter + @param p3 third parameter + */ + virtual Ret invokeR(P1 p1, P2 p2, P3 p3) {return (*myFunc)(p1, p2, p3);} + + /// Set the default parameter + /** + @param p1 default first parameter + */ + virtual void setP1(P1 p1) {myP1=p1;} + + /// Set the default 2nd parameter + /** + @param p2 default second parameter + */ + virtual void setP2(P2 p2) {myP2=p2;} + + /// Set the default third parameter + /** + @param p3 default third parameter + */ + virtual void setP3(P3 p3) {myP3=p3;} + + + +protected: + + Ret (*myFunc)(P1, P2, P3); + P1 myP1; + P2 myP2; + P3 myP3; +}; + + + +/// Functor for a global function with 4 parameters and return value +/** + This is a class for global functions which take 4 parameters and return + a value. This ties a C style function pointer into the functor class + hierarchy as a convience. Code that has a reference to this class + and treat it as an ArFunctor can use it like any other functor. + + For an overall description of functors, see ArFunctor. +*/ +template +class ArGlobalRetFunctor4 : public ArRetFunctor4 +{ +public: + + /// Constructor + ArGlobalRetFunctor4() {} + + /// Constructor - supply function pointer + /** + @param func global function pointer + */ + ArGlobalRetFunctor4(Ret (*func)(P1, P2, P3, P4)) : + myFunc(func), myP1(), myP2(), myP3(), myP4() {} + + /// Constructor - supply function pointer, default parameters + /** + @param func global function pointer + @param p1 default first parameter + */ + ArGlobalRetFunctor4(Ret (*func)(P1, P2, P3, P4), P1 p1) : + myFunc(func), myP1(p1), myP2(), myP3(), myP4() {} + + /// Constructor - supply function pointer, default parameters + /** + @param func global function pointer + @param p1 default first parameter + @param p2 default second parameter + */ + ArGlobalRetFunctor4(Ret (*func)(P1, P2, P3, P4), P1 p1, P2 p2) : + myFunc(func), myP1(p1), myP2(p2), myP3(), myP4() {} + + /// Constructor - supply function pointer, default parameters + /** + @param func global function pointer + @param p1 default first parameter + @param p2 default second parameter + @param p3 default third parameter + */ + ArGlobalRetFunctor4(Ret (*func)(P1, P2, P3, P4), P1 p1, P2 p2, P3 p3) : + myFunc(func), myP1(p1), myP2(p2), myP3(p3), myP4() {} + + /// Constructor - supply function pointer, default parameters + /** + @param func global function pointer + @param p1 default first parameter + @param p2 default second parameter + @param p3 default third parameter + @param p4 default fourth parameter + */ + ArGlobalRetFunctor4(Ret (*func)(P1, P2, P3, P4), P1 p1, P2 p2, P3 p3, P4 p4) : + myFunc(func), myP1(p1), myP2(p2), myP3(p3), myP4(p4) {} + + /// Destructor + virtual ~ArGlobalRetFunctor4() {} + + /// Invokes the functor with return value + virtual Ret invokeR(void) {return (*myFunc)(myP1, myP2, myP3, myP4);} + + /// Invokes the functor with return value + /** + @param p1 first parameter + */ + virtual Ret invokeR(P1 p1) {return (*myFunc)(p1, myP2, myP3, myP4);} + + /// Invokes the functor with return value + /** + @param p1 first parameter + @param p2 second parameter + */ + virtual Ret invokeR(P1 p1, P2 p2) {return (*myFunc)(p1, p2, myP3, myP4);} + + /// Invokes the functor with return value + /** + @param p1 first parameter + @param p2 second parameter + @param p3 third parameter + */ + virtual Ret invokeR(P1 p1, P2 p2, P3 p3) {return (*myFunc)(p1, p2, p3, myP4);} + + /// Invokes the functor with return value + /** + @param p1 first parameter + @param p2 second parameter + @param p3 third parameter + @param p4 fourth parameter + */ + virtual Ret invokeR(P1 p1, P2 p2, P3 p3, P4 p4) {return (*myFunc)(p1, p2, p3, p4);} + + /// Set the default parameter + /** + @param p1 default first parameter + */ + virtual void setP1(P1 p1) {myP1=p1;} + + /// Set the default 2nd parameter + /** + @param p2 default second parameter + */ + virtual void setP2(P2 p2) {myP2=p2;} + + /// Set the default third parameter + /** + @param p3 default third parameter + */ + virtual void setP3(P3 p3) {myP3=p3;} + + + /// Set the default fourth parameter + /** + @param p4 default fourth parameter + */ + virtual void setP4(P4 p4) {myP4=p4;} + +protected: + + Ret (*myFunc)(P1, P2, P3, P4); + P1 myP1; + P2 myP2; + P3 myP3; + P4 myP4; +}; + + +/// Functor for a global function with 5 parameters and return value +/** + This is a class for global functions which take 5 parameters and return + a value. This ties a C style function pointer into the functor class + hierarchy as a convience. Code that has a reference to this class + and treat it as an ArFunctor can use it like any other functor. + + For an overall description of functors, see ArFunctor. +*/ +template +class ArGlobalRetFunctor5 : public ArRetFunctor5 +{ +public: + + /// Constructor + ArGlobalRetFunctor5() {} + + /// Constructor - supply function pointer + /** + @param func global function pointer + */ + ArGlobalRetFunctor5(Ret (*func)(P1, P2, P3, P4, P5)) : + myFunc(func), myP1(), myP2(), myP3(), myP4(), myP5() {} + + /// Constructor - supply function pointer, default parameters + /** + @param func global function pointer + @param p1 default first parameter + */ + ArGlobalRetFunctor5(Ret (*func)(P1, P2, P3, P4, P5), P1 p1) : + myFunc(func), myP1(p1), myP2(), myP3(), myP4(), myP5() {} + + /// Constructor - supply function pointer, default parameters + /** + @param func global function pointer + @param p1 default first parameter + @param p2 default second parameter + */ + ArGlobalRetFunctor5(Ret (*func)(P1, P2, P3, P4, P5), P1 p1, P2 p2) : + myFunc(func), myP1(p1), myP2(p2), myP3(), myP4(), myP5() {} + + /// Constructor - supply function pointer, default parameters + /** + @param func global function pointer + @param p1 default first parameter + @param p2 default second parameter + @param p3 default third parameter + */ + ArGlobalRetFunctor5(Ret (*func)(P1, P2, P3, P4, P5), P1 p1, P2 p2, P3 p3) : + myFunc(func), myP1(p1), myP2(p2), myP3(p3), myP4(), myP5() {} + + /// Constructor - supply function pointer, default parameters + /** + @param func global function pointer + @param p1 default first parameter + @param p2 default second parameter + @param p3 default third parameter + @param p4 default fourth parameter + */ + ArGlobalRetFunctor5(Ret (*func)(P1, P2, P3, P4, P5), P1 p1, P2 p2, P3 p3, P4 p4) : + myFunc(func), myP1(p1), myP2(p2), myP3(p3), myP4(p4), myP5() {} + + /** + @param func global function pointer + @param p1 default first parameter + @param p2 default second parameter + @param p3 default third parameter + @param p4 default fourth parameter + @param p5 default fifth parameter + */ + ArGlobalRetFunctor5(Ret (*func)(P1, P2, P3, P4, P5), P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) : + myFunc(func), myP1(p1), myP2(p2), myP3(p3), myP4(p4), myP5(p5) {} + + /// Destructor + virtual ~ArGlobalRetFunctor5() {} + + /// Invokes the functor with return value + virtual Ret invokeR(void) {return (*myFunc)(myP1, myP2, myP3, myP4, myP5);} + + /// Invokes the functor with return value + /** + @param p1 first parameter + */ + virtual Ret invokeR(P1 p1) {return (*myFunc)(p1, myP2, myP3, myP4, myP5);} + + /// Invokes the functor with return value + /** + @param p1 first parameter + @param p2 second parameter + */ + virtual Ret invokeR(P1 p1, P2 p2) {return (*myFunc)(p1, p2, myP3, myP4, myP5);} + + /// Invokes the functor with return value + /** + @param p1 first parameter + @param p2 second parameter + @param p3 third parameter + */ + virtual Ret invokeR(P1 p1, P2 p2, P3 p3) {return (*myFunc)(p1, p2, p3, myP4, myP5);} + + /// Invokes the functor with return value + /** + @param p1 first parameter + @param p2 second parameter + @param p3 third parameter + @param p4 fourth parameter + */ + virtual Ret invokeR(P1 p1, P2 p2, P3 p3, P4 p4) {return (*myFunc)(p1, p2, p3, p4, myP5);} + + /// Invokes the functor with return value + /** + @param p1 first parameter + @param p2 second parameter + @param p3 third parameter + @param p4 fourth parameter + @param p5 fifth parameter + */ + virtual Ret invokeR(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) {return (*myFunc)(p1, p2, p3, p4, p5);} + + /// Set the default parameter + /** + @param p1 default first parameter + */ + virtual void setP1(P1 p1) {myP1=p1;} + + /// Set the default 2nd parameter + /** + @param p2 default second parameter + */ + virtual void setP2(P2 p2) {myP2=p2;} + + /// Set the default third parameter + /** + @param p3 default third parameter + */ + virtual void setP3(P3 p3) {myP3=p3;} + + /// Set the default fourth parameter + /** + @param p4 default fourth parameter + */ + virtual void setP4(P4 p4) {myP4=p4;} + + /// Set the default fifth parameter + /** + @param p4 default fifth parameter + */ + virtual void setP5(P5 p5) {myP5=p5;} + +protected: + + Ret (*myFunc)(P1, P2, P3, P4, P5); + P1 myP1; + P2 myP2; + P3 myP3; + P4 myP4; + P5 myP5; +}; + +#endif // omitting ArGlobalRetFunctor from SWIG + + + + +////// +////// +////// +////// +////// +////// +////// ArFunctors for member functions +////// +////// +////// +////// +////// +////// + + +/// Functor for a member function +/** + This is a class for member functions. This class contains the knowledge + on how to call a member function on a particular instance of a class. + This class should be instantiated by code that wishes to pass off a + functor to another piece of code. + + For an overall description of functors, see ArFunctor. +*/ +template +class ArFunctorC : public ArFunctor +{ +public: + + /// Constructor + ArFunctorC() {} + + /// Constructor - supply function pointer + /** + @param obj object to call function on + @param func member function pointer + */ + ArFunctorC(T &obj, void (T::*func)(void)) : myObj(&obj), myFunc(func) {} + + /// Constructor - supply function pointer + /** + @param obj object to call function on + @param func member function pointer + */ + ArFunctorC(T *obj, void (T::*func)(void)) : myObj(obj), myFunc(func) {} + + /// Destructor + virtual ~ArFunctorC() {} + + /// Invokes the functor + virtual void invoke(void) {(myObj->*myFunc)();} + + /// Set the 'this' pointer + /** + @param obj the 'this' pointer + */ + virtual void setThis(T *obj) {myObj=obj;} + + /// Set the 'this' pointer + /** + @param obj the 'this' pointer + */ + virtual void setThis(T &obj) {myObj=&obj;} + +protected: + + T *myObj; + void (T::*myFunc)(void); +}; + + +/// Functor for a member function with 1 parameter +/** + This is a class for member functions which take 1 parameter. This class + contains the knowledge on how to call a member function on a particular + instance of a class. This class should be instantiated by code that + wishes to pass off a functor to another piece of code. + + For an overall description of functors, see ArFunctor. +*/ +template +class ArFunctor1C : public ArFunctor1 +{ +public: + + /// Constructor + ArFunctor1C() {} + + /// Constructor - supply function pointer + /** + @param obj object to call function on + @param func member function pointer + */ + ArFunctor1C(T &obj, void (T::*func)(P1)) : + myObj(&obj), myFunc(func), myP1() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func member function pointer + @param p1 default first parameter + */ + ArFunctor1C(T &obj, void (T::*func)(P1), P1 p1) : + myObj(&obj), myFunc(func), myP1(p1) {} + + /// Constructor - supply function pointer + /** + @param obj object to call function on + @param func member function pointer + */ + ArFunctor1C(T *obj, void (T::*func)(P1)) : + myObj(obj), myFunc(func), myP1() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func member function pointer + @param p1 default first parameter + */ + ArFunctor1C(T *obj, void (T::*func)(P1), P1 p1) : + myObj(obj), myFunc(func), myP1(p1) {} + + /// Destructor + virtual ~ArFunctor1C() {} + + /// Invokes the functor + virtual void invoke(void) {(myObj->*myFunc)(myP1);} + + /// Invokes the functor + /** + @param p1 first parameter + */ + virtual void invoke(P1 p1) {(myObj->*myFunc)(p1);} + + /// Set the 'this' pointer + /** + @param obj the 'this' pointer + */ + virtual void setThis(T *obj) {myObj=obj;} + + /// Set the 'this' pointer + /** + @param obj the 'this' pointer + */ + virtual void setThis(T &obj) {myObj=&obj;} + + /// Set the default parameter + /** + @param p1 default first parameter + */ + virtual void setP1(P1 p1) {myP1=p1;} + +protected: + + T *myObj; + void (T::*myFunc)(P1); + P1 myP1; +}; + + +/// Functor for a member function with 2 parameters +/** + This is a class for member functions which take 2 parameters. This class + contains the knowledge on how to call a member function on a particular + instance of a class. This class should be instantiated by code that + wishes to pass off a functor to another piece of code. + + For an overall description of functors, see ArFunctor. +*/ +template +class ArFunctor2C : public ArFunctor2 +{ +public: + + /// Constructor + ArFunctor2C() {} + + /// Constructor - supply function pointer + /** + @param obj object to call function on + @param func member function pointer + */ + ArFunctor2C(T &obj, void (T::*func)(P1, P2)) : + myObj(&obj), myFunc(func), myP1(), myP2() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func member function pointer + @param p1 default first parameter + */ + ArFunctor2C(T &obj, void (T::*func)(P1, P2), P1 p1) : + myObj(&obj), myFunc(func), myP1(p1), myP2() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func member function pointer + @param p1 default first parameter + @param p2 default second parameter + */ + ArFunctor2C(T &obj, void (T::*func)(P1, P2), P1 p1, P2 p2) : + myObj(&obj), myFunc(func), myP1(p1), myP2(p2) {} + + /// Constructor - supply function pointer + /** + @param obj object to call function on + @param func member function pointer + */ + ArFunctor2C(T *obj, void (T::*func)(P1, P2)) : + myObj(obj), myFunc(func), myP1(), myP2() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func member function pointer + @param p1 default first parameter + */ + ArFunctor2C(T *obj, void (T::*func)(P1, P2), P1 p1) : + myObj(obj), myFunc(func), myP1(p1), myP2() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func member function pointer + @param p1 default first parameter + @param p2 default second parameter + */ + ArFunctor2C(T *obj, void (T::*func)(P1, P2), P1 p1, P2 p2) : + myObj(obj), myFunc(func), myP1(p1), myP2(p2) {} + + /// Destructor + virtual ~ArFunctor2C() {} + + /// Invokes the functor + virtual void invoke(void) {(myObj->*myFunc)(myP1, myP2);} + + /// Invokes the functor + /** + @param p1 first parameter + */ + virtual void invoke(P1 p1) {(myObj->*myFunc)(p1, myP2);} + + /// Invokes the functor + /** + @param p1 first parameter + @param p2 second parameter + */ + virtual void invoke(P1 p1, P2 p2) {(myObj->*myFunc)(p1, p2);} + + /// Set the 'this' pointer + /** + @param obj the 'this' pointer + */ + virtual void setThis(T *obj) {myObj=obj;} + + /// Set the 'this' pointer + /** + @param obj the 'this' pointer + */ + virtual void setThis(T &obj) {myObj=&obj;} + + /// Set the default parameter + /** + @param p1 default first parameter + */ + virtual void setP1(P1 p1) {myP1=p1;} + + /// Set the default 2nd parameter + /** + @param p2 default second parameter + */ + virtual void setP2(P2 p2) {myP2=p2;} + +protected: + + T *myObj; + void (T::*myFunc)(P1, P2); + P1 myP1; + P2 myP2; +}; + +/// Functor for a member function with 3 parameters +/** + This is a class for member functions which take 3 parameters. This class + contains the knowledge on how to call a member function on a particular + instance of a class. This class should be instantiated by code that + wishes to pass off a functor to another piece of code. + + For an overall description of functors, see ArFunctor. +*/ +template +class ArFunctor3C : public ArFunctor3 +{ +public: + + /// Constructor + ArFunctor3C() {} + + /// Constructor - supply function pointer + /** + @param obj object to call function on + @param func member function pointer + */ + ArFunctor3C(T &obj, void (T::*func)(P1, P2, P3)) : + myObj(&obj), myFunc(func), myP1(), myP2(), myP3() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func member function pointer + @param p1 default first parameter + */ + ArFunctor3C(T &obj, void (T::*func)(P1, P2, P3), P1 p1) : + myObj(&obj), myFunc(func), myP1(p1), myP2(), myP3() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func member function pointer + @param p1 default first parameter + @param p2 default second parameter + */ + ArFunctor3C(T &obj, void (T::*func)(P1, P2, P3), P1 p1, P2 p2) : + myObj(&obj), myFunc(func), myP1(p1), myP2(p2), myP3() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func member function pointer + @param p1 default first parameter + @param p2 default second parameter + @param p3 default third parameter + */ + ArFunctor3C(T &obj, void (T::*func)(P1, P2, P3), P1 p1, P2 p2, P3 p3) : + myObj(&obj), myFunc(func), myP1(p1), myP2(p2), myP3(p3) {} + + /// Constructor - supply function pointer + /** + @param obj object to call function on + @param func member function pointer + */ + ArFunctor3C(T *obj, void (T::*func)(P1, P2, P3)) : + myObj(obj), myFunc(func), myP1(), myP2(), myP3() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func member function pointer + @param p1 default first parameter + */ + ArFunctor3C(T *obj, void (T::*func)(P1, P2, P3), P1 p1) : + myObj(obj), myFunc(func), myP1(p1), myP2(), myP3() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func member function pointer + @param p1 default first parameter + @param p2 default second parameter + */ + ArFunctor3C(T *obj, void (T::*func)(P1, P2, P3), P1 p1, P2 p2) : + myObj(obj), myFunc(func), myP1(p1), myP2(p2), myP3() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func member function pointer + @param p1 default first parameter + @param p2 default second parameter + @param p3 default third parameter + */ + ArFunctor3C(T *obj, void (T::*func)(P1, P2, P3), P1 p1, P2 p2, P3 p3) : + myObj(obj), myFunc(func), myP1(p1), myP2(p2), myP3(p3) {} + + /// Destructor + virtual ~ArFunctor3C() {} + + /// Invokes the functor + virtual void invoke(void) {(myObj->*myFunc)(myP1, myP2, myP3);} + + /// Invokes the functor + /** + @param p1 first parameter + */ + virtual void invoke(P1 p1) {(myObj->*myFunc)(p1, myP2, myP3);} + + /// Invokes the functor + /** + @param p1 first parameter + @param p2 second parameter + */ + virtual void invoke(P1 p1, P2 p2) {(myObj->*myFunc)(p1, p2, myP3);} + + /// Invokes the functor + /** + @param p1 first parameter + @param p2 second parameter + @param p3 third parameter + */ + virtual void invoke(P1 p1, P2 p2, P3 p3) {(myObj->*myFunc)(p1, p2, p3);} + + /// Set the 'this' pointer + /** + @param obj the 'this' pointer + */ + virtual void setThis(T *obj) {myObj=obj;} + + /// Set the 'this' pointer + /** + @param obj the 'this' pointer + */ + virtual void setThis(T &obj) {myObj=&obj;} + + /// Set the default parameter + /** + @param p1 default first parameter + */ + virtual void setP1(P1 p1) {myP1=p1;} + + /// Set the default 2nd parameter + /** + @param p2 default second parameter + */ + virtual void setP2(P2 p2) {myP2=p2;} + + /// Set the default third parameter + /** + @param p3 default third parameter + */ + virtual void setP3(P3 p3) {myP3=p3;} + +protected: + + T *myObj; + void (T::*myFunc)(P1, P2, P3); + P1 myP1; + P2 myP2; + P3 myP3; +}; + + + +/// Functor for a member function with 4 parameters +/** + This is a class for member functions which take 4 parameters. This class + contains the knowledge on how to call a member function on a particular + instance of a class. This class should be instantiated by code that + wishes to pass off a functor to another piece of code. + + For an overall description of functors, see ArFunctor. +*/ +template +class ArFunctor4C : public ArFunctor4 +{ +public: + + /// Constructor + ArFunctor4C() {} + + /// Constructor - supply function pointer + /** + @param obj object to call function on + @param func member function pointer + */ + ArFunctor4C(T &obj, void (T::*func)(P1, P2, P3, P4)) : + myObj(&obj), myFunc(func), myP1(), myP2(), myP3(), myP4() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func member function pointer + @param p1 default first parameter + */ + ArFunctor4C(T &obj, void (T::*func)(P1, P2, P3, P4), P1 p1) : + myObj(&obj), myFunc(func), myP1(p1), myP2(), myP3(), myP4() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func member function pointer + @param p1 default first parameter + @param p2 default second parameter + */ + ArFunctor4C(T &obj, void (T::*func)(P1, P2, P3, P4), P1 p1, P2 p2) : + myObj(&obj), myFunc(func), myP1(p1), myP2(p2), myP3(), myP4() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func member function pointer + @param p1 default first parameter + @param p2 default second parameter + @param p3 default third parameter + */ + ArFunctor4C(T &obj, void (T::*func)(P1, P2, P3, P4), P1 p1, P2 p2, P3 p3) : + myObj(&obj), myFunc(func), myP1(p1), myP2(p2), myP3(p3), myP4() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func member function pointer + @param p1 default first parameter + @param p2 default second parameter + @param p3 default third parameter + @param p4 default fourth parameter + */ + ArFunctor4C(T &obj, void (T::*func)(P1, P2, P3, P4), P1 p1, P2 p2, P3 p3, P4 p4) : + myObj(&obj), myFunc(func), myP1(p1), myP2(p2), myP3(p3), myP4(p4) {} + + /// Constructor - supply function pointer + /** + @param obj object to call function on + @param func member function pointer + */ + ArFunctor4C(T *obj, void (T::*func)(P1, P2, P3, P4)) : + myObj(obj), myFunc(func), myP1(), myP2(), myP3(), myP4() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func member function pointer + @param p1 default first parameter + */ + ArFunctor4C(T *obj, void (T::*func)(P1, P2, P3, P4), P1 p1) : + myObj(obj), myFunc(func), myP1(p1), myP2(), myP3(), myP4() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func member function pointer + @param p1 default first parameter + @param p2 default second parameter + */ + ArFunctor4C(T *obj, void (T::*func)(P1, P2, P3, P4), P1 p1, P2 p2) : + myObj(obj), myFunc(func), myP1(p1), myP2(p2), myP3(), myP4() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func member function pointer + @param p1 default first parameter + @param p2 default second parameter + @param p3 default third parameter + */ + ArFunctor4C(T *obj, void (T::*func)(P1, P2, P3, P4), P1 p1, P2 p2, P3 p3) : + myObj(obj), myFunc(func), myP1(p1), myP2(p2), myP3(p3), myP4() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func member function pointer + @param p1 default first parameter + @param p2 default second parameter + @param p3 default third parameter + @param p4 default fourth parameter + */ + ArFunctor4C(T *obj, void (T::*func)(P1, P2, P3, P4), P1 p1, P2 p2, P3 p3, P4 p4) : + myObj(obj), myFunc(func), myP1(p1), myP2(p2), myP3(p3), myP4(p4) {} + + + /// Destructor + virtual ~ArFunctor4C() {} + + /// Invokes the functor + virtual void invoke(void) {(myObj->*myFunc)(myP1, myP2, myP3, myP4);} + + /// Invokes the functor + /** + @param p1 first parameter + */ + virtual void invoke(P1 p1) {(myObj->*myFunc)(p1, myP2, myP3, myP4);} + + /// Invokes the functor + /** + @param p1 first parameter + @param p2 second parameter + */ + virtual void invoke(P1 p1, P2 p2) {(myObj->*myFunc)(p1, p2, myP3, myP4);} + + /// Invokes the functor + /** + @param p1 first parameter + @param p2 second parameter + @param p3 third parameter + */ + virtual void invoke(P1 p1, P2 p2, P3 p3) {(myObj->*myFunc)(p1, p2, p3, myP4);} + + /// Invokes the functor + /** + @param p1 first parameter + @param p2 second parameter + @param p3 third parameter + @param p4 fourth parameter + */ + virtual void invoke(P1 p1, P2 p2, P3 p3, P4 p4) {(myObj->*myFunc)(p1, p2, p3, p4);} + + /// Set the 'this' pointer + /** + @param obj the 'this' pointer + */ + virtual void setThis(T *obj) {myObj=obj;} + + /// Set the 'this' pointer + /** + @param obj the 'this' pointer + */ + virtual void setThis(T &obj) {myObj=&obj;} + + /// Set the default parameter + /** + @param p1 default first parameter + */ + virtual void setP1(P1 p1) {myP1=p1;} + + /// Set the default 2nd parameter + /** + @param p2 default second parameter + */ + virtual void setP2(P2 p2) {myP2=p2;} + + /// Set the default third parameter + /** + @param p3 default third parameter + */ + virtual void setP3(P3 p3) {myP3=p3;} + + /// Set the default fourth parameter + /** + @param p4 default fourth parameter + */ + virtual void setP4(P4 p4) {myP4=p4;} + + +protected: + + T *myObj; + void (T::*myFunc)(P1, P2, P3, P4); + P1 myP1; + P2 myP2; + P3 myP3; + P4 myP4; +}; + + +/// Functor for a member function with 5 parameters +/** + This is a class for member functions which take 5 parameters. This class + contains the knowledge on how to call a member function on a particular + instance of a class. This class should be instantiated by code that + wishes to pass off a functor to another piece of code. + + For an overall description of functors, see ArFunctor. +*/ +template +class ArFunctor5C : public ArFunctor5 +{ +public: + + /// Constructor + ArFunctor5C() {} + + /// Constructor - supply function pointer + /** + @param obj object to call function on + @param func member function pointer + */ + ArFunctor5C(T &obj, void (T::*func)(P1, P2, P3, P4, P5)) : + myObj(&obj), myFunc(func), myP1(), myP2(), myP3(), myP4(), myP5() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func member function pointer + @param p1 default first parameter + */ + ArFunctor5C(T &obj, void (T::*func)(P1, P2, P3, P4, P5), P1 p1) : + myObj(&obj), myFunc(func), myP1(p1), myP2(), myP3(), myP4(), myP5() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func member function pointer + @param p1 default first parameter + @param p2 default second parameter + */ + ArFunctor5C(T &obj, void (T::*func)(P1, P2, P3, P4, P5), P1 p1, P2 p2) : + myObj(&obj), myFunc(func), myP1(p1), myP2(p2), myP3(), myP4(), myP5() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func member function pointer + @param p1 default first parameter + @param p2 default second parameter + @param p3 default third parameter + */ + ArFunctor5C(T &obj, void (T::*func)(P1, P2, P3, P4, P5), P1 p1, P2 p2, P3 p3) : + myObj(&obj), myFunc(func), myP1(p1), myP2(p2), myP3(p3), myP4(), myP5() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func member function pointer + @param p1 default first parameter + @param p2 default second parameter + @param p3 default third parameter + @param p4 default fourth parameter + */ + ArFunctor5C(T &obj, void (T::*func)(P1, P2, P3, P4, P5), P1 p1, P2 p2, P3 p3, P4 p4) : + myObj(&obj), myFunc(func), myP1(p1), myP2(p2), myP3(p3), myP4(p4), myP5() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func member function pointer + @param p1 default first parameter + @param p2 default second parameter + @param p3 default third parameter + @param p4 default fourth parameter + @param p5 default fifth parameter + */ +ArFunctor5C(T &obj, void (T::*func)(P1, P2, P3, P4, P5), P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) : + myObj(&obj), myFunc(func), myP1(p1), myP2(p2), myP3(p3), myP4(p4), myP5(p5) {} + + /// Constructor - supply function pointer + /** + @param obj object to call function on + @param func member function pointer + */ + ArFunctor5C(T *obj, void (T::*func)(P1, P2, P3, P4, P5)) : + myObj(obj), myFunc(func), myP1(), myP2(), myP3(), myP4(), myP5() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func member function pointer + @param p1 default first parameter + */ + ArFunctor5C(T *obj, void (T::*func)(P1, P2, P3, P4, P5), P1 p1) : + myObj(obj), myFunc(func), myP1(p1), myP2(), myP3(), myP4(), myP5() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func member function pointer + @param p1 default first parameter + @param p2 default second parameter + */ + ArFunctor5C(T *obj, void (T::*func)(P1, P2, P3, P4, P5), P1 p1, P2 p2) : + myObj(obj), myFunc(func), myP1(p1), myP2(p2), myP3(), myP4(), myP5() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func member function pointer + @param p1 default first parameter + @param p2 default second parameter + @param p3 default third parameter + */ + ArFunctor5C(T *obj, void (T::*func)(P1, P2, P3, P4, P5), P1 p1, P2 p2, P3 p3) : + myObj(obj), myFunc(func), myP1(p1), myP2(p2), myP3(p3), myP4(), myP5() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func member function pointer + @param p1 default first parameter + @param p2 default second parameter + @param p3 default third parameter + @param p4 default fourth parameter + */ + ArFunctor5C(T *obj, void (T::*func)(P1, P2, P3, P4, P5), P1 p1, P2 p2, P3 p3, P4 p4) : + myObj(obj), myFunc(func), myP1(p1), myP2(p2), myP3(p3), myP4(p4), myP5() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func member function pointer + @param p1 default first parameter + @param p2 default second parameter + @param p3 default third parameter + @param p4 default fourth parameter + @param p5 default fifth parameter + */ + ArFunctor5C(T *obj, void (T::*func)(P1, P2, P3, P4, P5), P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) : + myObj(obj), myFunc(func), myP1(p1), myP2(p2), myP3(p3), myP4(p4), myP5(p5) {} + + + /// Destructor + virtual ~ArFunctor5C() {} + + /// Invokes the functor + virtual void invoke(void) {(myObj->*myFunc)(myP1, myP2, myP3, myP4, myP5);} + + /// Invokes the functor + /** + @param p1 first parameter + */ + virtual void invoke(P1 p1) {(myObj->*myFunc)(p1, myP2, myP3, myP4, myP5);} + + /// Invokes the functor + /** + @param p1 first parameter + @param p2 second parameter + */ + virtual void invoke(P1 p1, P2 p2) {(myObj->*myFunc)(p1, p2, myP3, myP4, myP5);} + + /// Invokes the functor + /** + @param p1 first parameter + @param p2 second parameter + @param p3 third parameter + */ + virtual void invoke(P1 p1, P2 p2, P3 p3) {(myObj->*myFunc)(p1, p2, p3, myP4, myP5);} + + /// Invokes the functor + /** + @param p1 first parameter + @param p2 second parameter + @param p3 third parameter + @param p4 fourth parameter + */ + virtual void invoke(P1 p1, P2 p2, P3 p3, P4 p4) {(myObj->*myFunc)(p1, p2, p3, p4, myP5);} + + + /// Invokes the functor + /** + @param p1 first parameter + @param p2 second parameter + @param p3 third parameter + @param p4 fourth parameter + @param p5 fifth parameter + */ + virtual void invoke(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) {(myObj->*myFunc)(p1, p2, p3, p4, p5);} + + /// Set the 'this' pointer + /** + @param obj the 'this' pointer + */ + virtual void setThis(T *obj) {myObj=obj;} + + /// Set the 'this' pointer + /** + @param obj the 'this' pointer + */ + virtual void setThis(T &obj) {myObj=&obj;} + + /// Set the default parameter + /** + @param p1 default first parameter + */ + virtual void setP1(P1 p1) {myP1=p1;} + + /// Set the default 2nd parameter + /** + @param p2 default second parameter + */ + virtual void setP2(P2 p2) {myP2=p2;} + + /// Set the default third parameter + /** + @param p3 default third parameter + */ + virtual void setP3(P3 p3) {myP3=p3;} + + /// Set the default fourth parameter + /** + @param p4 default fourth parameter + */ + virtual void setP4(P4 p4) {myP4=p4;} + + /// Set the default fifth parameter + /** + @param p4 default fifth parameter + */ + virtual void setP5(P5 p5) {myP5=p5;} + + +protected: + + T *myObj; + void (T::*myFunc)(P1, P2, P3, P4, P5); + P1 myP1; + P2 myP2; + P3 myP3; + P4 myP4; + P5 myP5; +}; + + + + + + +////// +////// +////// +////// +////// +////// +////// ArFunctors for member functions with return values +////// +////// +////// +////// +////// +////// + + +/// Functor for a member function with return value +/** + This is a class for member functions which return a value. This class + contains the knowledge on how to call a member function on a particular + instance of a class. This class should be instantiated by code that + wishes to pass off a functor to another piece of code. + + For an overall description of functors, see ArFunctor. +*/ +template +class ArRetFunctorC : public ArRetFunctor +{ +public: + + /// Constructor + ArRetFunctorC() {} + + /// Constructor - supply function pointer + /** + @param obj object to call function on + @param func member function pointer + */ + ArRetFunctorC(T &obj, Ret (T::*func)(void)) : myObj(&obj), myFunc(func) {} + + /// Constructor - supply function pointer + /** + @param obj object to call function on + @param func member function pointer + */ + ArRetFunctorC(T *obj, Ret (T::*func)(void)) : myObj(obj), myFunc(func) {} + + /// Destructor - supply function pointer + virtual ~ArRetFunctorC() {} + + /// Invokes the functor with return value + virtual Ret invokeR(void) {return (myObj->*myFunc)();} + + /// Set the 'this' pointer + /** + @param obj the 'this' pointer + */ + virtual void setThis(T *obj) {myObj=obj;} + + /// Set the 'this' pointer + /** + @param obj the 'this' pointer + */ + virtual void setThis(T &obj) {myObj=&obj;} + +protected: + + T *myObj; + Ret (T::*myFunc)(void); +}; + +/// Functor for a member function with return value and 1 parameter +/** + This is a class for member functions which take 1 parameter and return + a value. This class contains the knowledge on how to call a member + function on a particular instance of a class. This class should be + instantiated by code that wishes to pass off a functor to another + piece of code. + + For an overall description of functors, see ArFunctor. +*/ +template +class ArRetFunctor1C : public ArRetFunctor1 +{ +public: + + /// Constructor + ArRetFunctor1C() {} + + /// Constructor - supply function pointer + /** + @param obj object to call function on + @param func member function pointer + */ + ArRetFunctor1C(T &obj, Ret (T::*func)(P1)) : + myObj(&obj), myFunc(func), myP1() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func member function pointer + @param p1 default first parameter + */ + ArRetFunctor1C(T &obj, Ret (T::*func)(P1), P1 p1) : + myObj(&obj), myFunc(func), myP1(p1) {} + + /// Constructor - supply function pointer + /** + @param obj object to call function on + @param func member function pointer + */ + ArRetFunctor1C(T *obj, Ret (T::*func)(P1)) : + myObj(obj), myFunc(func), myP1() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func member function pointer + @param p1 default first parameter + */ + ArRetFunctor1C(T *obj, Ret (T::*func)(P1), P1 p1) : + myObj(obj), myFunc(func), myP1(p1) {} + + /// Destructor + virtual ~ArRetFunctor1C() {} + + /// Invokes the functor with return value + virtual Ret invokeR(void) {return (myObj->*myFunc)(myP1);} + + /// Invokes the functor with return value + /** + @param p1 first parameter + */ + virtual Ret invokeR(P1 p1) {return (myObj->*myFunc)(p1);} + + /// Set the 'this' pointer + /** + @param obj the 'this' pointer + */ + virtual void setThis(T *obj) {myObj=obj;} + + /// Set the 'this' pointer + /** + @param obj the 'this' pointer + */ + virtual void setThis(T &obj) {myObj=&obj;} + + /// Set the default parameter + /** + @param p1 default first parameter + */ + virtual void setP1(P1 p1) {myP1=p1;} + +protected: + + T *myObj; + Ret (T::*myFunc)(P1); + P1 myP1; +}; + +/// Functor for a member function with return value and 2 parameters +/** + This is a class for member functions which take 2 parameters and return + a value. This class contains the knowledge on how to call a member + function on a particular instance of a class. This class should be + instantiated by code that wishes to pass off a functor to another + piece of code. + + For an overall description of functors, see ArFunctor. +*/ +template +class ArRetFunctor2C : public ArRetFunctor2 +{ +public: + + /// Constructor + ArRetFunctor2C() {} + + /// Constructor - supply function pointer + /** + @param obj object to call function on + @param func member function pointer + */ + ArRetFunctor2C(T &obj, Ret (T::*func)(P1, P2)) : + myObj(&obj), myFunc(func), myP1(), myP2() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func member function pointer + @param p1 default first parameter + */ + ArRetFunctor2C(T &obj, Ret (T::*func)(P1, P2), P1 p1) : + myObj(&obj), myFunc(func), myP1(p1), myP2() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func member function pointer + @param p1 default first parameter + @param p2 default second parameter + */ + ArRetFunctor2C(T &obj, Ret (T::*func)(P1, P2), P1 p1, P2 p2) : + myObj(&obj), myFunc(func), myP1(p1), myP2(p2) {} + + /// Constructor - supply function pointer + /** + @param obj object to call function on + @param func member function pointer + */ + ArRetFunctor2C(T *obj, Ret (T::*func)(P1, P2)) : + myObj(obj), myFunc(func), myP1(), myP2() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func member function pointer + @param p1 default first parameter + */ + ArRetFunctor2C(T *obj, Ret (T::*func)(P1, P2), P1 p1) : + myObj(obj), myFunc(func), myP1(p1), myP2() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func member function pointer + @param p1 default first parameter + @param p2 default second parameter + */ + ArRetFunctor2C(T *obj, Ret (T::*func)(P1, P2), P1 p1, P2 p2) : + myObj(obj), myFunc(func), myP1(p1), myP2(p2) {} + + /// Destructor + virtual ~ArRetFunctor2C() {} + + /// Invokes the functor with return value + virtual Ret invokeR(void) {return (myObj->*myFunc)(myP1, myP2);} + + /// Invokes the functor with return value + /** + @param p1 first parameter + */ + virtual Ret invokeR(P1 p1) {return (myObj->*myFunc)(p1, myP2);} + + /// Invokes the functor with return value + /** + @param p1 first parameter + @param p2 second parameter + */ + virtual Ret invokeR(P1 p1, P2 p2) {return (myObj->*myFunc)(p1, p2);} + + /// Set the 'this' pointer + /** + @param obj the 'this' pointer + */ + virtual void setThis(T *obj) {myObj=obj;} + + /// Set the 'this' pointer + /** + @param obj the 'this' pointer + */ + virtual void setThis(T &obj) {myObj=&obj;} + + /// Set the default parameter + /** + @param p1 default first parameter + */ + virtual void setP1(P1 p1) {myP1=p1;} + + /// Set the default 2nd parameter + /** + @param p2 default second parameter + */ + virtual void setP2(P2 p2) {myP2=p2;} + +protected: + + T *myObj; + Ret (T::*myFunc)(P1, P2); + P1 myP1; + P2 myP2; +}; + +/// Functor for a member function with return value and 3 parameters +/** + This is a class for member functions which take 3 parameters and return + a value. This class contains the knowledge on how to call a member + function on a particular instance of a class. This class should be + instantiated by code that wishes to pass off a functor to another + piece of code. + + For an overall description of functors, see ArFunctor. +*/ +template +class ArRetFunctor3C : public ArRetFunctor3 +{ +public: + + /// Constructor + ArRetFunctor3C() {} + + /// Constructor - supply function pointer + /** + @param obj object to call function on + @param func member function pointer + */ + ArRetFunctor3C(T &obj, Ret (T::*func)(P1, P2, P3)) : + myObj(&obj), myFunc(func), myP1(), myP2(), myP3() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func member function pointer + @param p1 default first parameter + */ + ArRetFunctor3C(T &obj, Ret (T::*func)(P1, P2, P3), P1 p1) : + myObj(&obj), myFunc(func), myP1(p1), myP2(), myP3() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func member function pointer + @param p1 default first parameter + @param p2 default second parameter + */ + ArRetFunctor3C(T &obj, Ret (T::*func)(P1, P2, P3), P1 p1, P2 p2) : + myObj(&obj), myFunc(func), myP1(p1), myP2(p2), myP3() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func member function pointer + @param p1 default first parameter + @param p2 default second parameter + @param p3 default third parameter + */ + ArRetFunctor3C(T &obj, Ret (T::*func)(P1, P2, P3), P1 p1, P2 p2, P3 p3) : + myObj(&obj), myFunc(func), myP1(p1), myP2(p2), myP3(p3) {} + + /// Constructor - supply function pointer + /** + @param obj object to call function on + @param func member function pointer + */ + ArRetFunctor3C(T *obj, Ret (T::*func)(P1, P2, P3)) : + myObj(obj), myFunc(func), myP1(), myP2(), myP3() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func member function pointer + @param p1 default first parameter + */ + ArRetFunctor3C(T *obj, Ret (T::*func)(P1, P2, P3), P1 p1) : + myObj(obj), myFunc(func), myP1(p1), myP2(), myP3() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func member function pointer + @param p1 default first parameter + @param p2 default second parameter + */ + ArRetFunctor3C(T *obj, Ret (T::*func)(P1, P2, P3), P1 p1, P2 p2) : + myObj(obj), myFunc(func), myP1(p1), myP2(p2), myP3() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func member function pointer + @param p1 default first parameter + @param p2 default second parameter + @param p3 default third parameter + */ + ArRetFunctor3C(T *obj, Ret (T::*func)(P1, P2, P3), P1 p1, P2 p2, P3 p3) : + myObj(obj), myFunc(func), myP1(p1), myP2(p2), myP3(p3) {} + + /// Destructor + virtual ~ArRetFunctor3C() {} + + /// Invokes the functor with return value + virtual Ret invokeR(void) {return (myObj->*myFunc)(myP1, myP2, myP3);} + + /// Invokes the functor with return value + /** + @param p1 first parameter + */ + virtual Ret invokeR(P1 p1) {return (myObj->*myFunc)(p1, myP2, myP3);} + + /// Invokes the functor with return value + /** + @param p1 first parameter + @param p2 second parameter + */ + virtual Ret invokeR(P1 p1, P2 p2) {return (myObj->*myFunc)(p1, p2, myP3);} + + /// Invokes the functor with return value + /** + @param p1 first parameter + @param p2 second parameter + @param p3 third parameter + */ + virtual Ret invokeR(P1 p1, P2 p2, P3 p3) + {return (myObj->*myFunc)(p1, p2, p3);} + + /// Set the 'this' pointer + /** + @param obj object to call function on + @param obj the 'this' pointer + */ + virtual void setThis(T *obj) {myObj=obj;} + + /// Set the 'this' pointer + /** + @param obj object to call function on + @param obj the 'this' pointer + */ + virtual void setThis(T &obj) {myObj=&obj;} + + /// Set the default parameter + /** + @param p1 default first parameter + */ + virtual void setP1(P1 p1) {myP1=p1;} + + /// Set the default 2nd parameter + /** + @param p2 default second parameter + */ + virtual void setP2(P2 p2) {myP2=p2;} + + /// Set the default third parameter + /** + @param p3 default third parameter + */ + virtual void setP3(P3 p3) {myP3=p3;} + +protected: + + T *myObj; + Ret (T::*myFunc)(P1, P2, P3); + P1 myP1; + P2 myP2; + P3 myP3; +}; + + + + +// Start 4 + + +/// Functor for a member function with return value and 4 parameters +/** + This is a class for member functions which take 4 parameters and return + a value. This class contains the knowledge on how to call a member + function on a particular instance of a class. This class should be + instantiated by code that wishes to pass off a functor to another + piece of code. + + For an overall description of functors, see ArFunctor. +*/ +template +class ArRetFunctor4C : public ArRetFunctor4 +{ +public: + + /// Constructor + ArRetFunctor4C() {} + + /// Constructor - supply function pointer + /** + @param obj object to call function on + @param func member function pointer + */ + ArRetFunctor4C(T &obj, Ret (T::*func)(P1, P2, P3, P4)) : + myObj(&obj), myFunc(func), myP1(), myP2(), myP3(), myP4() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func member function pointer + @param p1 default first parameter + */ + ArRetFunctor4C(T &obj, Ret (T::*func)(P1, P2, P3, P4), P1 p1) : + myObj(&obj), myFunc(func), myP1(p1), myP2(), myP3(), myP4() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func member function pointer + @param p1 default first parameter + @param p2 default second parameter + */ + ArRetFunctor4C(T &obj, Ret (T::*func)(P1, P2, P3, P4), P1 p1, P2 p2) : + myObj(&obj), myFunc(func), myP1(p1), myP2(p2), myP3(), myP4() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func member function pointer + @param p1 default first parameter + @param p2 default second parameter + @param p3 default third parameter + */ + ArRetFunctor4C(T &obj, Ret (T::*func)(P1, P2, P3, P4), P1 p1, P2 p2, P3 p3) : + myObj(&obj), myFunc(func), myP1(p1), myP2(p2), myP3(p3), myP4() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func member function pointer + @param p1 default first parameter + @param p2 default second parameter + @param p3 default third parameter + @param p4 default fourth parameter + */ + ArRetFunctor4C(T &obj, Ret (T::*func)(P1, P2, P3, P4), P1 p1, P2 p2, P3 p3, P4 p4) : + myObj(&obj), myFunc(func), myP1(p1), myP2(p2), myP3(p3), myP4(p4) {} + + + + /// Constructor - supply function pointer + /** + @param obj object to call function on + @param func member function pointer + */ + ArRetFunctor4C(T *obj, Ret (T::*func)(P1, P2, P3, P4)) : + myObj(obj), myFunc(func), myP1(), myP2(), myP3(), myP4() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func member function pointer + @param p1 default first parameter + */ + ArRetFunctor4C(T *obj, Ret (T::*func)(P1, P2, P3, P4), P1 p1) : + myObj(obj), myFunc(func), myP1(p1), myP2(), myP3(), myP4() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func member function pointer + @param p1 default first parameter + @param p2 default second parameter + */ + ArRetFunctor4C(T *obj, Ret (T::*func)(P1, P2, P3, P4), P1 p1, P2 p2) : + myObj(obj), myFunc(func), myP1(p1), myP2(p2), myP3(), myP4() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func member function pointer + @param p1 default first parameter + @param p2 default second parameter + @param p3 default third parameter + */ + ArRetFunctor4C(T *obj, Ret (T::*func)(P1, P2, P3, P4), P1 p1, P2 p2, P3 p3) : + myObj(obj), myFunc(func), myP1(p1), myP2(p2), myP3(p3), myP4() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func member function pointer + @param p1 default first parameter + @param p2 default second parameter + @param p3 default third parameter + @param p4 default fourth parameter + */ + ArRetFunctor4C(T *obj, Ret (T::*func)(P1, P2, P3, P4), P1 p1, P2 p2, P3 p3, P4 p4) : + myObj(obj), myFunc(func), myP1(p1), myP2(p2), myP3(p3), myP4(p4) {} + + /// Destructor + virtual ~ArRetFunctor4C() {} + + /// Invokes the functor with return value + virtual Ret invokeR(void) {return (myObj->*myFunc)(myP1, myP2, myP3, myP4);} + + /// Invokes the functor with return value + /** + @param p1 first parameter + */ + virtual Ret invokeR(P1 p1) {return (myObj->*myFunc)(p1, myP2, myP3, myP4);} + + /// Invokes the functor with return value + /** + @param p1 first parameter + @param p2 second parameter + */ + virtual Ret invokeR(P1 p1, P2 p2) {return (myObj->*myFunc)(p1, p2, myP3, myP4);} + + /// Invokes the functor with return value + /** + @param p1 first parameter + @param p2 second parameter + @param p3 third parameter + */ + virtual Ret invokeR(P1 p1, P2 p2, P3 p3) + {return (myObj->*myFunc)(p1, p2, p3, myP4);} + + /// Invokes the functor with return value + /** + @param p1 first parameter + @param p2 second parameter + @param p3 third parameter + @param p4 fourth parameter + */ + virtual Ret invokeR(P1 p1, P2 p2, P3 p3, P4 p4) + {return (myObj->*myFunc)(p1, p2, p3, p4);} + + + /// Set the 'this' pointer + /** + @param obj the 'this' pointer + */ + virtual void setThis(T *obj) {myObj=obj;} + + /// Set the 'this' pointer + /** + @param obj the 'this' pointer + */ + virtual void setThis(T &obj) {myObj=&obj;} + + /// Set the default parameter + /** + @param p1 default first parameter + */ + virtual void setP1(P1 p1) {myP1=p1;} + + /// Set the default 2nd parameter + /** + @param p2 default second parameter + */ + virtual void setP2(P2 p2) {myP2=p2;} + + /// Set the default third parameter + /** + @param p3 default third parameter + */ + virtual void setP3(P3 p3) {myP3=p3;} + + /// Set the default fourth parameter + /** + @param p4 default fourth parameter + */ + virtual void setP4(P4 p4) {myP4=p4;} + +protected: + + T *myObj; + Ret (T::*myFunc)(P1, P2, P3, P4); + P1 myP1; + P2 myP2; + P3 myP3; + P4 myP4; +}; + + + +/// Functor for a member function with return value and 5 parameters +/** + This is a class for member functions which take 5 parameters and return + a value. This class contains the knowledge on how to call a member + function on a particular instance of a class. This class should be + instantiated by code that wishes to pass off a functor to another + piece of code. + + For an overall description of functors, see ArFunctor. +*/ +template +class ArRetFunctor5C : public ArRetFunctor5 +{ +public: + + /// Constructor + ArRetFunctor5C() {} + + /// Constructor - supply function pointer + /** + @param obj object to call function on + @param func member function pointer + */ + ArRetFunctor5C(T &obj, Ret (T::*func)(P1, P2, P3, P4, P5)) : + myObj(&obj), myFunc(func), myP1(), myP2(), myP3(), myP4(), myP5() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func member function pointer + @param p1 default first parameter + */ + ArRetFunctor5C(T &obj, Ret (T::*func)(P1, P2, P3, P4, P5), P1 p1) : + myObj(&obj), myFunc(func), myP1(p1), myP2(), myP3(), myP4(), myP5() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func member function pointer + @param p1 default first parameter + @param p2 default second parameter + */ + ArRetFunctor5C(T &obj, Ret (T::*func)(P1, P2, P3, P4, P5), P1 p1, P2 p2) : + myObj(&obj), myFunc(func), myP1(p1), myP2(p2), myP3(), myP4(), myP5() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func member function pointer + @param p1 default first parameter + @param p2 default second parameter + @param p3 default third parameter + */ + ArRetFunctor5C(T &obj, Ret (T::*func)(P1, P2, P3, P4, P5), P1 p1, P2 p2, P3 p3) : + myObj(&obj), myFunc(func), myP1(p1), myP2(p2), myP3(p3), myP4(), myP5() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func member function pointer + @param p1 default first parameter + @param p2 default second parameter + @param p3 default third parameter + @param p4 default fourth parameter + */ + ArRetFunctor5C(T &obj, Ret (T::*func)(P1, P2, P3, P4, P5), P1 p1, P2 p2, P3 p3, P4 p4) : + myObj(&obj), myFunc(func), myP1(p1), myP2(p2), myP3(p3), myP4(p4), myP5() {} + + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func member function pointer + @param p1 default first parameter + @param p2 default second parameter + @param p3 default third parameter + @param p4 default fourth parameter + @param p5 default fifth parameter + */ + ArRetFunctor5C(T &obj, Ret (T::*func)(P1, P2, P3, P4, P5), P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) : + myObj(&obj), myFunc(func), myP1(p1), myP2(p2), myP3(p3), myP4(p4), myP5(p5) {} + + + + /// Constructor - supply function pointer + /** + @param obj object to call function on + @param func member function pointer + */ + ArRetFunctor5C(T *obj, Ret (T::*func)(P1, P2, P3, P4, P5)) : + myObj(obj), myFunc(func), myP1(), myP2(), myP3(), myP4(), myP5() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func member function pointer + @param p1 default first parameter + */ + ArRetFunctor5C(T *obj, Ret (T::*func)(P1, P2, P3, P4, P5), P1 p1) : + myObj(obj), myFunc(func), myP1(p1), myP2(), myP3(), myP4(), myP5() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func member function pointer + @param p1 default first parameter + @param p2 default second parameter + */ + ArRetFunctor5C(T *obj, Ret (T::*func)(P1, P2, P3, P4, P5), P1 p1, P2 p2) : + myObj(obj), myFunc(func), myP1(p1), myP2(p2), myP3(), myP4(), myP5() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func member function pointer + @param p1 default first parameter + @param p2 default second parameter + @param p3 default third parameter + */ + ArRetFunctor5C(T *obj, Ret (T::*func)(P1, P2, P3, P4, P5), P1 p1, P2 p2, P3 p3) : + myObj(obj), myFunc(func), myP1(p1), myP2(p2), myP3(p3), myP4(), myP5() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func member function pointer + @param p1 default first parameter + @param p2 default second parameter + @param p3 default third parameter + @param p4 default fourth parameter + */ + ArRetFunctor5C(T *obj, Ret (T::*func)(P1, P2, P3, P4, P5), P1 p1, P2 p2, P3 p3, P4 p4) : + myObj(obj), myFunc(func), myP1(p1), myP2(p2), myP3(p3), myP4(p4), myP5() {} + + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func member function pointer + @param p1 default first parameter + @param p2 default second parameter + @param p3 default third parameter + @param p4 default fourth parameter + @param p5 default fifth parameter + */ + ArRetFunctor5C(T *obj, Ret (T::*func)(P1, P2, P3, P4, P5), P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) : + myObj(obj), myFunc(func), myP1(p1), myP2(p2), myP3(p3), myP4(p4), myP5(p5) {} + + /// Destructor + virtual ~ArRetFunctor5C() {} + + /// Invokes the functor with return value + virtual Ret invokeR(void) {return (myObj->*myFunc)(myP1, myP2, myP3, myP4, myP5);} + + /// Invokes the functor with return value + /** + @param p1 first parameter + */ + virtual Ret invokeR(P1 p1) {return (myObj->*myFunc)(p1, myP2, myP3, myP4, myP5);} + + /// Invokes the functor with return value + /** + @param p1 first parameter + @param p2 second parameter + */ + virtual Ret invokeR(P1 p1, P2 p2) {return (myObj->*myFunc)(p1, p2, myP3, myP4, myP5);} + + /// Invokes the functor with return value + /** + @param p1 first parameter + @param p2 second parameter + @param p3 third parameter + */ + virtual Ret invokeR(P1 p1, P2 p2, P3 p3) + {return (myObj->*myFunc)(p1, p2, p3, myP4, myP5);} + + /// Invokes the functor with return value + /** + @param p1 first parameter + @param p2 second parameter + @param p3 third parameter + @param p4 fourth parameter + */ + virtual Ret invokeR(P1 p1, P2 p2, P3 p3, P4 p4) + {return (myObj->*myFunc)(p1, p2, p3, p4, myP5);} + + /// Invokes the functor with return value + /** + @param p1 first parameter + @param p2 second parameter + @param p3 third parameter + @param p4 fourth parameter + @param p5 fifth parameter + */ + virtual Ret invokeR(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) + {return (myObj->*myFunc)(p1, p2, p3, p4, p5);} + + + /// Set the 'this' pointer + /** + @param obj the 'this' pointer + */ + virtual void setThis(T *obj) {myObj=obj;} + + /// Set the 'this' pointer + /** + @param obj the 'this' pointer + */ + virtual void setThis(T &obj) {myObj=&obj;} + + /// Set the default parameter + /** + @param p1 default first parameter + */ + virtual void setP1(P1 p1) {myP1=p1;} + + /// Set the default 2nd parameter + /** + @param p2 default second parameter + */ + virtual void setP2(P2 p2) {myP2=p2;} + + /// Set the default third parameter + /** + @param p3 default third parameter + */ + virtual void setP3(P3 p3) {myP3=p3;} + + /// Set the default fourth parameter + /** + @param p4 default fourth parameter + */ + virtual void setP4(P4 p4) {myP4=p4;} + + /// Set the default fifth parameter + /** + @param p4 default fifth parameter + */ + virtual void setP5(P5 p5) {myP5=p5;} + +protected: + + T *myObj; + Ret (T::*myFunc)(P1, P2, P3, P4, P5); + P1 myP1; + P2 myP2; + P3 myP3; + P4 myP4; + P4 myP5; +}; + + +/// Swig doesn't like the const functors +#ifndef SWIG + +////// +////// +////// +////// +////// +////// +////// ArFunctors for const member functions +////// +////// +////// +////// +////// +////// + + +/// Functor for a const member function +/** + This is a class for const member functions. This class contains the + knowledge on how to call a const member function on a particular + instance of a class. This class should be instantiated by code + that wishes to pass off a functor to another piece of code. + + For an overall description of functors, see ArFunctor. + + @swigomit +*/ +template +class ArConstFunctorC : public ArFunctor +{ +public: + + /// Constructor + ArConstFunctorC() {} + + /// Constructor - supply function pointer + /** + @param obj object to call function on + @param func const member function pointer + */ + ArConstFunctorC(T &obj, void (T::*func)(void) const) : myObj(&obj), myFunc(func) {} + + /// Constructor - supply function pointer + /** + @param obj object to call function on + @param func const member function pointer + */ + ArConstFunctorC(T *obj, void (T::*func)(void) const) : myObj(obj), myFunc(func) {} + + /// Destructor + virtual ~ArConstFunctorC() {} + + /// Invokes the functor + virtual void invoke(void) {(myObj->*myFunc)();} + + /// Set the 'this' pointer + /** + @param obj the 'this' pointer + */ + virtual void setThis(T *obj) {myObj=obj;} + + /// Set the 'this' pointer + /** + @param obj the 'this' pointer + */ + virtual void setThis(T &obj) {myObj=&obj;} + +protected: + + T *myObj; + void (T::*myFunc)(void) const; +}; + + +/// Functor for a const member function with 1 parameter +/** + This is a class for const member functions which take 1 + parameter. This class contains the knowledge on how to call a const + member function on a particular instance of a class. This class + should be instantiated by code that wishes to pass off a functor to + another piece of code. + + For an overall description of functors, see ArFunctor. */ +template +class ArConstFunctor1C : public ArFunctor1 +{ +public: + + /// Constructor + ArConstFunctor1C() {} + + /// Constructor - supply function pointer + /** + @param obj object to call function on + @param func const member function pointer + */ + ArConstFunctor1C(T &obj, void (T::*func)(P1) const) : + myObj(&obj), myFunc(func), myP1() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func const member function pointer + @param p1 default first parameter + */ + ArConstFunctor1C(T &obj, void (T::*func)(P1) const, P1 p1) : + myObj(&obj), myFunc(func), myP1(p1) {} + + /// Constructor - supply function pointer + /** + @param obj object to call function on + @param func const member function pointer + */ + ArConstFunctor1C(T *obj, void (T::*func)(P1) const) : + myObj(obj), myFunc(func), myP1() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func const member function pointer + @param p1 default first parameter + */ + ArConstFunctor1C(T *obj, void (T::*func)(P1) const, P1 p1) : + myObj(obj), myFunc(func), myP1(p1) {} + + /// Destructor + virtual ~ArConstFunctor1C() {} + + /// Invokes the functor + virtual void invoke(void) {(myObj->*myFunc)(myP1);} + + /// Invokes the functor + /** + @param p1 first parameter + */ + virtual void invoke(P1 p1) {(myObj->*myFunc)(p1);} + + /// Set the 'this' pointer + /** + @param obj the 'this' pointer + */ + virtual void setThis(T *obj) {myObj=obj;} + + /// Set the 'this' pointer + /** + @param obj the 'this' pointer + */ + virtual void setThis(T &obj) {myObj=&obj;} + + /// Set the default parameter + /** + @param p1 default first parameter + */ + virtual void setP1(P1 p1) {myP1=p1;} + +protected: + + T *myObj; + void (T::*myFunc)(P1) const; + P1 myP1; +}; + + +/// Functor for a const member function with 2 parameters +/** + This is a class for const member functions which take 2 + parameters. This class contains the knowledge on how to call a + const member function on a particular instance of a class. This + class should be instantiated by code that wishes to pass off a + functor to another piece of code. + + For an overall description of functors, see ArFunctor. */ +template +class ArConstFunctor2C : public ArFunctor2 +{ +public: + + /// Constructor + ArConstFunctor2C() {} + + /// Constructor - supply function pointer + /** + @param obj object to call function on + @param func const member function pointer + */ + ArConstFunctor2C(T &obj, void (T::*func)(P1, P2) const) : + myObj(&obj), myFunc(func), myP1(), myP2() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func const member function pointer + @param p1 default first parameter + */ + ArConstFunctor2C(T &obj, void (T::*func)(P1, P2) const, P1 p1) : + myObj(&obj), myFunc(func), myP1(p1), myP2() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func const member function pointer + @param p1 default first parameter + @param p2 default second parameter + */ + ArConstFunctor2C(T &obj, void (T::*func)(P1, P2) const, P1 p1, P2 p2) : + myObj(&obj), myFunc(func), myP1(p1), myP2(p2) {} + + /// Constructor - supply function pointer + /** + @param obj object to call function on + @param func const member function pointer + */ + ArConstFunctor2C(T *obj, void (T::*func)(P1, P2) const) : + myObj(obj), myFunc(func), myP1(), myP2() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func const member function pointer + @param p1 default first parameter + */ + ArConstFunctor2C(T *obj, void (T::*func)(P1, P2) const, P1 p1) : + myObj(obj), myFunc(func), myP1(p1), myP2() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func const member function pointer + @param p1 default first parameter + @param p2 default second parameter + */ + ArConstFunctor2C(T *obj, void (T::*func)(P1, P2) const, P1 p1, P2 p2) : + myObj(obj), myFunc(func), myP1(p1), myP2(p2) {} + + /// Destructor + virtual ~ArConstFunctor2C() {} + + /// Invokes the functor + virtual void invoke(void) {(myObj->*myFunc)(myP1, myP2);} + + /// Invokes the functor + /** + @param p1 first parameter + */ + virtual void invoke(P1 p1) {(myObj->*myFunc)(p1, myP2);} + + /// Invokes the functor + /** + @param p1 first parameter + @param p2 second parameter + */ + virtual void invoke(P1 p1, P2 p2) {(myObj->*myFunc)(p1, p2);} + + /// Set the 'this' pointer + /** + @param obj the 'this' pointer + */ + virtual void setThis(T *obj) {myObj=obj;} + + /// Set the 'this' pointer + /** + @param obj the 'this' pointer + */ + virtual void setThis(T &obj) {myObj=&obj;} + + /// Set the default parameter + /** + @param p1 default first parameter + */ + virtual void setP1(P1 p1) {myP1=p1;} + + /// Set the default 2nd parameter + /** + @param p2 default second parameter + */ + virtual void setP2(P2 p2) {myP2=p2;} + +protected: + + T *myObj; + void (T::*myFunc)(P1, P2) const; + P1 myP1; + P2 myP2; +}; + +/// Functor for a const member function with 3 parameters +/** + This is a class for const member functions which take 3 + parameters. This class contains the knowledge on how to call a + const member function on a particular instance of a class. This + class should be instantiated by code that wishes to pass off a + functor to another piece of code. + + For an overall description of functors, see ArFunctor. */ +template +class ArConstFunctor3C : public ArFunctor3 +{ +public: + + /// Constructor + ArConstFunctor3C() {} + + /// Constructor - supply function pointer + /** + @param obj object to call function on + @param func const member function pointer + */ + ArConstFunctor3C(T &obj, void (T::*func)(P1, P2, P3) const) : + myObj(&obj), myFunc(func), myP1(), myP2(), myP3() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func const member function pointer + @param p1 default first parameter + */ + ArConstFunctor3C(T &obj, void (T::*func)(P1, P2, P3) const, P1 p1) : + myObj(&obj), myFunc(func), myP1(p1), myP2(), myP3() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func const member function pointer + @param p1 default first parameter + @param p2 default second parameter + */ + ArConstFunctor3C(T &obj, void (T::*func)(P1, P2, P3) const, P1 p1, P2 p2) : + myObj(&obj), myFunc(func), myP1(p1), myP2(p2), myP3() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func const member function pointer + @param p1 default first parameter + @param p2 default second parameter + @param p3 default third parameter + */ + ArConstFunctor3C(T &obj, void (T::*func)(P1, P2, P3) const, P1 p1, P2 p2, P3 p3) : + myObj(&obj), myFunc(func), myP1(p1), myP2(p2), myP3(p3) {} + + /// Constructor - supply function pointer + /** + @param obj object to call function on + @param func const member function pointer + */ + ArConstFunctor3C(T *obj, void (T::*func)(P1, P2, P3) const) : + myObj(obj), myFunc(func), myP1(), myP2(), myP3() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func const member function pointer + @param p1 default first parameter + */ + ArConstFunctor3C(T *obj, void (T::*func)(P1, P2, P3) const, P1 p1) : + myObj(obj), myFunc(func), myP1(p1), myP2(), myP3() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func const member function pointer + @param p1 default first parameter + @param p2 default second parameter + */ + ArConstFunctor3C(T *obj, void (T::*func)(P1, P2, P3) const, P1 p1, P2 p2) : + myObj(obj), myFunc(func), myP1(p1), myP2(p2), myP3() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func const member function pointer + @param p1 default first parameter + @param p2 default second parameter + @param p3 default third parameter + */ + ArConstFunctor3C(T *obj, void (T::*func)(P1, P2, P3) const, P1 p1, P2 p2, P3 p3) : + myObj(obj), myFunc(func), myP1(p1), myP2(p2), myP3(p3) {} + + /// Destructor + virtual ~ArConstFunctor3C() {} + + /// Invokes the functor + virtual void invoke(void) {(myObj->*myFunc)(myP1, myP2, myP3);} + + /// Invokes the functor + /** + @param p1 first parameter + */ + virtual void invoke(P1 p1) {(myObj->*myFunc)(p1, myP2, myP3);} + + /// Invokes the functor + /** + @param p1 first parameter + @param p2 second parameter + */ + virtual void invoke(P1 p1, P2 p2) {(myObj->*myFunc)(p1, p2, myP3);} + + /// Invokes the functor + /** + @param p1 first parameter + @param p2 second parameter + @param p3 third parameter + */ + virtual void invoke(P1 p1, P2 p2, P3 p3) {(myObj->*myFunc)(p1, p2, p3);} + + /// Set the 'this' pointer + /** + @param obj the 'this' pointer + */ + virtual void setThis(T *obj) {myObj=obj;} + + /// Set the 'this' pointer + /** + @param obj the 'this' pointer + */ + virtual void setThis(T &obj) {myObj=&obj;} + + /// Set the default parameter + /** + @param p1 default first parameter + */ + virtual void setP1(P1 p1) {myP1=p1;} + + /// Set the default 2nd parameter + /** + @param p2 default second parameter + */ + virtual void setP2(P2 p2) {myP2=p2;} + + /// Set the default third parameter + /** + @param p3 default third parameter + */ + virtual void setP3(P3 p3) {myP3=p3;} + +protected: + + T *myObj; + void (T::*myFunc)(P1, P2, P3) const; + P1 myP1; + P2 myP2; + P3 myP3; +}; + + + +/// Functor for a const member function with 4 parameters +/** + This is a class for const member functions which take 4 + parameters. This class contains the knowledge on how to call a + const member function on a particular instance of a class. This + class should be instantiated by code that wishes to pass off a + functor to another piece of code. + + For an overall description of functors, see ArFunctor. */ +template +class ArConstFunctor4C : public ArFunctor4 +{ +public: + + /// Constructor + ArConstFunctor4C() {} + + /// Constructor - supply function pointer + /** + @param obj object to call function on + @param func const member function pointer + */ + ArConstFunctor4C(T &obj, void (T::*func)(P1, P2, P3, P4) const) : + myObj(&obj), myFunc(func), myP1(), myP2(), myP3(), myP4() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func const member function pointer + @param p1 default first parameter + */ + ArConstFunctor4C(T &obj, void (T::*func)(P1, P2, P3, P4), P1 p1) : + myObj(&obj), myFunc(func), myP1(p1), myP2(), myP3(), myP4() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func const member function pointer + @param p1 default first parameter + @param p2 default second parameter + */ + ArConstFunctor4C(T &obj, void (T::*func)(P1, P2, P3, P4), P1 p1, P2 p2) : + myObj(&obj), myFunc(func), myP1(p1), myP2(p2), myP3(), myP4() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func const member function pointer + @param p1 default first parameter + @param p2 default second parameter + @param p3 default third parameter + */ + ArConstFunctor4C(T &obj, void (T::*func)(P1, P2, P3, P4), P1 p1, P2 p2, P3 p3) : + myObj(&obj), myFunc(func), myP1(p1), myP2(p2), myP3(p3), myP4() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func const member function pointer + @param p1 default first parameter + @param p2 default second parameter + @param p3 default third parameter + @param p4 default fourth parameter + */ + ArConstFunctor4C(T &obj, void (T::*func)(P1, P2, P3, P4), P1 p1, P2 p2, P3 p3, P4 p4) : + myObj(&obj), myFunc(func), myP1(p1), myP2(p2), myP3(p3), myP4(p4) {} + + /// Constructor - supply function pointer + /** + @param obj object to call function on + @param func const member function pointer + */ + ArConstFunctor4C(T *obj, void (T::*func)(P1, P2, P3, P4) const) : + myObj(obj), myFunc(func), myP1(), myP2(), myP3(), myP4() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func const member function pointer + @param p1 default first parameter + */ + ArConstFunctor4C(T *obj, void (T::*func)(P1, P2, P3, P4), P1 p1) : + myObj(obj), myFunc(func), myP1(p1), myP2(), myP3(), myP4() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func const member function pointer + @param p1 default first parameter + @param p2 default second parameter + */ + ArConstFunctor4C(T *obj, void (T::*func)(P1, P2, P3, P4), P1 p1, P2 p2) : + myObj(obj), myFunc(func), myP1(p1), myP2(p2), myP3(), myP4() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func const member function pointer + @param p1 default first parameter + @param p2 default second parameter + @param p3 default third parameter + */ + ArConstFunctor4C(T *obj, void (T::*func)(P1, P2, P3, P4), P1 p1, P2 p2, P3 p3) : + myObj(obj), myFunc(func), myP1(p1), myP2(p2), myP3(p3), myP4() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func const member function pointer + @param p1 default first parameter + @param p2 default second parameter + @param p3 default third parameter + @param p4 default fourth parameter + */ + ArConstFunctor4C(T *obj, void (T::*func)(P1, P2, P3, P4), P1 p1, P2 p2, P3 p3, P4 p4) : + myObj(obj), myFunc(func), myP1(p1), myP2(p2), myP3(p3), myP4(p4) {} + + + /// Destructor + virtual ~ArConstFunctor4C() {} + + /// Invokes the functor + virtual void invoke(void) {(myObj->*myFunc)(myP1, myP2, myP3, myP4);} + + /// Invokes the functor + /** + @param p1 first parameter + */ + virtual void invoke(P1 p1) {(myObj->*myFunc)(p1, myP2, myP3, myP4);} + + /// Invokes the functor + /** + @param p1 first parameter + @param p2 second parameter + */ + virtual void invoke(P1 p1, P2 p2) {(myObj->*myFunc)(p1, p2, myP3, myP4);} + + /// Invokes the functor + /** + @param p1 first parameter + @param p2 second parameter + @param p3 third parameter + */ + virtual void invoke(P1 p1, P2 p2, P3 p3) {(myObj->*myFunc)(p1, p2, p3, myP4);} + + /// Invokes the functor + /** + @param p1 first parameter + @param p2 second parameter + @param p3 third parameter + @param p4 fourth parameter + */ + virtual void invoke(P1 p1, P2 p2, P3 p3, P4 p4) {(myObj->*myFunc)(p1, p2, p3, p4);} + + /// Set the 'this' pointer + /** + @param obj the 'this' pointer + */ + virtual void setThis(T *obj) {myObj=obj;} + + /// Set the 'this' pointer + /** + @param obj the 'this' pointer + */ + virtual void setThis(T &obj) {myObj=&obj;} + + /// Set the default parameter + /** + @param p1 default first parameter + */ + virtual void setP1(P1 p1) {myP1=p1;} + + /// Set the default 2nd parameter + /** + @param p2 default second parameter + */ + virtual void setP2(P2 p2) {myP2=p2;} + + /// Set the default third parameter + /** + @param p3 default third parameter + */ + virtual void setP3(P3 p3) {myP3=p3;} + + /// Set the default fourth parameter + /** + @param p4 default fourth parameter + */ + virtual void setP4(P4 p4) {myP4=p4;} + + +protected: + + T *myObj; + void (T::*myFunc)(P1, P2, P3, P4) const; + P1 myP1; + P2 myP2; + P3 myP3; + P4 myP4; +}; + +/// Functor for a const member function with 5 parameters +/** + This is a class for const member functions which take 5 + parameters. This class contains the knowledge on how to call a + const member function on a particular instance of a class. This + class should be instantiated by code that wishes to pass off a + functor to another piece of code. + + For an overall description of functors, see ArFunctor. */ +template +class ArConstFunctor5C : public ArFunctor5 +{ +public: + + /// Constructor + ArConstFunctor5C() {} + + /// Constructor - supply function pointer + /** + @param obj object to call function on + @param func const member function pointer + */ + ArConstFunctor5C(T &obj, void (T::*func)(P1, P2, P3, P4, P5) const) : + myObj(&obj), myFunc(func), myP1(), myP2(), myP3(), myP4(), myP5() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func const member function pointer + @param p1 default first parameter + */ + ArConstFunctor5C(T &obj, void (T::*func)(P1, P2, P3, P4, P5), P1 p1) : + myObj(&obj), myFunc(func), myP1(p1), myP2(), myP3(), myP4(), myP5() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func const member function pointer + @param p1 default first parameter + @param p2 default second parameter + */ + ArConstFunctor5C(T &obj, void (T::*func)(P1, P2, P3, P4, P5), P1 p1, P2 p2) : + myObj(&obj), myFunc(func), myP1(p1), myP2(p2), myP3(), myP4(), myP5() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func const member function pointer + @param p1 default first parameter + @param p2 default second parameter + @param p3 default third parameter + */ + ArConstFunctor5C(T &obj, void (T::*func)(P1, P2, P3, P4, P5), P1 p1, P2 p2, P3 p3) : + myObj(&obj), myFunc(func), myP1(p1), myP2(p2), myP3(p3), myP4(), myP5() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func const member function pointer + @param p1 default first parameter + @param p2 default second parameter + @param p3 default third parameter + @param p4 default fourth parameter + */ + ArConstFunctor5C(T &obj, void (T::*func)(P1, P2, P3, P4, P5), P1 p1, P2 p2, P3 p3, P4 p4) : + myObj(&obj), myFunc(func), myP1(p1), myP2(p2), myP3(p3), myP4(p4), myP5() {} + + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func const member function pointer + @param p1 default first parameter + @param p2 default second parameter + @param p3 default third parameter + @param p4 default fourth parameter + @param p5 default fifth parameter + */ + ArConstFunctor5C(T &obj, void (T::*func)(P1, P2, P3, P4, P5), P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) : + myObj(&obj), myFunc(func), myP1(p1), myP2(p2), myP3(p3), myP4(p4), myP5(p5) {} + + /// Constructor - supply function pointer + /** + @param obj object to call function on + @param func const member function pointer + */ + ArConstFunctor5C(T *obj, void (T::*func)(P1, P2, P3, P4, P5) const) : + myObj(obj), myFunc(func), myP1(), myP2(), myP3(), myP4(), myP5() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func const member function pointer + @param p1 default first parameter + */ + ArConstFunctor5C(T *obj, void (T::*func)(P1, P2, P3, P4, P5), P1 p1) : + myObj(obj), myFunc(func), myP1(p1), myP2(), myP3(), myP4(), myP5() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func const member function pointer + @param p1 default first parameter + @param p2 default second parameter + */ + ArConstFunctor5C(T *obj, void (T::*func)(P1, P2, P3, P4, P5), P1 p1, P2 p2) : + myObj(obj), myFunc(func), myP1(p1), myP2(p2), myP3(), myP4(), myP5() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func const member function pointer + @param p1 default first parameter + @param p2 default second parameter + @param p3 default third parameter + */ + ArConstFunctor5C(T *obj, void (T::*func)(P1, P2, P3, P4, P5), P1 p1, P2 p2, P3 p3) : + myObj(obj), myFunc(func), myP1(p1), myP2(p2), myP3(p3), myP4(), myP5() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func const member function pointer + @param p1 default first parameter + @param p2 default second parameter + @param p3 default third parameter + @param p4 default fourth parameter + */ + ArConstFunctor5C(T *obj, void (T::*func)(P1, P2, P3, P4, P5), P1 p1, P2 p2, P3 p3, P4 p4) : + myObj(obj), myFunc(func), myP1(p1), myP2(p2), myP3(p3), myP4(p4), myP5() {} + + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func const member function pointer + @param p1 default first parameter + @param p2 default second parameter + @param p3 default third parameter + @param p4 default fourth parameter + @param p5 default fifth parameter + */ + ArConstFunctor5C(T *obj, void (T::*func)(P1, P2, P3, P4, P5), P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) : + myObj(obj), myFunc(func), myP1(p1), myP2(p2), myP3(p3), myP4(p4), myP5(p5) {} + + + /// Destructor + virtual ~ArConstFunctor5C() {} + + /// Invokes the functor + virtual void invoke(void) {(myObj->*myFunc)(myP1, myP2, myP3, myP4, myP5);} + + /// Invokes the functor + /** + @param p1 first parameter + */ + virtual void invoke(P1 p1) {(myObj->*myFunc)(p1, myP2, myP3, myP4, myP5);} + + /// Invokes the functor + /** + @param p1 first parameter + @param p2 second parameter + */ + virtual void invoke(P1 p1, P2 p2) {(myObj->*myFunc)(p1, p2, myP3, myP4, myP5);} + + /// Invokes the functor + /** + @param p1 first parameter + @param p2 second parameter + @param p3 third parameter + */ + virtual void invoke(P1 p1, P2 p2, P3 p3) {(myObj->*myFunc)(p1, p2, p3, myP4, myP5);} + + /// Invokes the functor + /** + @param p1 first parameter + @param p2 second parameter + @param p3 third parameter + @param p4 fourth parameter + */ + virtual void invoke(P1 p1, P2 p2, P3 p3, P4 p4) {(myObj->*myFunc)(p1, p2, p3, p4, myP5);} + + /// Invokes the functor + /** + @param p1 first parameter + @param p2 second parameter + @param p3 third parameter + @param p4 fourth parameter + @param p5 fifth parameter + */ + virtual void invoke(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) {(myObj->*myFunc)(p1, p2, p3, p4, p5);} + + /// Set the 'this' pointer + /** + @param obj the 'this' pointer + */ + virtual void setThis(T *obj) {myObj=obj;} + + /// Set the 'this' pointer + /** + @param obj the 'this' pointer + */ + virtual void setThis(T &obj) {myObj=&obj;} + + /// Set the default parameter + /** + @param p1 default first parameter + */ + virtual void setP1(P1 p1) {myP1=p1;} + + /// Set the default 2nd parameter + /** + @param p2 default second parameter + */ + virtual void setP2(P2 p2) {myP2=p2;} + + /// Set the default third parameter + /** + @param p3 default third parameter + */ + virtual void setP3(P3 p3) {myP3=p3;} + + /// Set the default fourth parameter + /** + @param p4 default fourth parameter + */ + virtual void setP4(P4 p4) {myP4=p4;} + + /// Set the default fifth parameter + /** + @param p5 default fifth parameter + */ + virtual void setP5(P5 p5) {myP5=p5;} + + +protected: + + T *myObj; + void (T::*myFunc)(P1, P2, P3, P4, P5) const; + P1 myP1; + P2 myP2; + P3 myP3; + P4 myP4; + P4 myP5; +}; + + + + + + +////// +////// +////// +////// +////// +////// +////// ArFunctors for const member functions with return values +////// +////// +////// +////// +////// +////// + + +/// Functor for a const member function with return value +/** + This is a class for const member functions which return a + value. This class contains the knowledge on how to call a const + member function on a particular instance of a class. This class + should be instantiated by code that wishes to pass off a functor to + another piece of code. + + For an overall description of functors, see ArFunctor. */ +template +class ArConstRetFunctorC : public ArRetFunctor +{ +public: + + /// Constructor + ArConstRetFunctorC() {} + + /// Constructor - supply function pointer + /** + @param obj object to call function on + @param func const member function pointer + */ + ArConstRetFunctorC(T &obj, Ret (T::*func)(void) const) : myObj(&obj), myFunc(func) {} + + /// Constructor - supply function pointer + /** + @param obj object to call function on + @param func const member function pointer + */ + ArConstRetFunctorC(T *obj, Ret (T::*func)(void) const) : myObj(obj), myFunc(func) {} + + /// Destructor - supply function pointer + virtual ~ArConstRetFunctorC() {} + + /// Invokes the functor with return value + virtual Ret invokeR(void) {return (myObj->*myFunc)();} + + /// Set the 'this' pointer + /** + @param obj the 'this' pointer + */ + virtual void setThis(T *obj) {myObj=obj;} + + /// Set the 'this' pointer + /** + @param obj the 'this' pointer + */ + virtual void setThis(T &obj) {myObj=&obj;} + +protected: + + T *myObj; + Ret (T::*myFunc)(void) const; +}; + +/// Functor for a const member function with return value and 1 parameter +/** + This is a class for const member functions which take 1 parameter + and return a value. This class contains the knowledge on how to + call a member function on a particular instance of a class. This + class should be instantiated by code that wishes to pass off a + functor to another piece of code. + + For an overall description of functors, see ArFunctor. */ +template +class ArConstRetFunctor1C : public ArRetFunctor1 +{ +public: + + /// Constructor + ArConstRetFunctor1C() {} + + /// Constructor - supply function pointer + /** + @param obj object to call function on + @param func const member function pointer + */ + ArConstRetFunctor1C(T &obj, Ret (T::*func)(P1) const) : + myObj(&obj), myFunc(func), myP1() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func const member function pointer + @param p1 default first parameter + */ + ArConstRetFunctor1C(T &obj, Ret (T::*func)(P1) const, P1 p1) : + myObj(&obj), myFunc(func), myP1(p1) {} + + /// Constructor - supply function pointer + /** + @param obj object to call function on + @param func const member function pointer + */ + ArConstRetFunctor1C(T *obj, Ret (T::*func)(P1) const) : + myObj(obj), myFunc(func), myP1() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func const member function pointer + @param p1 default first parameter + */ + ArConstRetFunctor1C(T *obj, Ret (T::*func)(P1) const, P1 p1) : + myObj(obj), myFunc(func), myP1(p1) {} + + /// Destructor + virtual ~ArConstRetFunctor1C() {} + + /// Invokes the functor with return value + virtual Ret invokeR(void) {return (myObj->*myFunc)(myP1);} + + /// Invokes the functor with return value + /** + @param p1 first parameter + */ + virtual Ret invokeR(P1 p1) {return (myObj->*myFunc)(p1);} + + /// Set the 'this' pointer + /** + @param obj the 'this' pointer + */ + virtual void setThis(T *obj) {myObj=obj;} + + /// Set the 'this' pointer + /** + @param obj the 'this' pointer + */ + virtual void setThis(T &obj) {myObj=&obj;} + + /// Set the default parameter + /** + @param p1 default first parameter + */ + virtual void setP1(P1 p1) {myP1=p1;} + +protected: + + T *myObj; + Ret (T::*myFunc)(P1) const; + P1 myP1; +}; + +/// Functor for a const member function with return value and 2 parameters +/** + This is a class for const member functions which take 2 parameters + and return a value. This class contains the knowledge on how to + call a member function on a particular instance of a class. This + class should be instantiated by code that wishes to pass off a + functor to another piece of code. + + For an overall description of functors, see ArFunctor. */ +template +class ArConstRetFunctor2C : public ArRetFunctor2 +{ +public: + + /// Constructor + ArConstRetFunctor2C() {} + + /// Constructor - supply function pointer + /** + @param obj object to call function on + @param func const member function pointer + */ + ArConstRetFunctor2C(T &obj, Ret (T::*func)(P1, P2) const) : + myObj(&obj), myFunc(func), myP1(), myP2() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func const member function pointer + @param p1 default first parameter + */ + ArConstRetFunctor2C(T &obj, Ret (T::*func)(P1, P2) const, P1 p1) : + myObj(&obj), myFunc(func), myP1(p1), myP2() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func const member function pointer + @param p1 default first parameter + @param p2 default second parameter + */ + ArConstRetFunctor2C(T &obj, Ret (T::*func)(P1, P2) const, P1 p1, P2 p2) : + myObj(&obj), myFunc(func), myP1(p1), myP2(p2) {} + + /// Constructor - supply function pointer + /** + @param obj object to call function on + @param func const member function pointer + */ + ArConstRetFunctor2C(T *obj, Ret (T::*func)(P1, P2) const) : + myObj(obj), myFunc(func), myP1(), myP2() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func const member function pointer + @param p1 default first parameter + */ + ArConstRetFunctor2C(T *obj, Ret (T::*func)(P1, P2) const, P1 p1) : + myObj(obj), myFunc(func), myP1(p1), myP2() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func const member function pointer + @param p1 default first parameter + @param p2 default second parameter + */ + ArConstRetFunctor2C(T *obj, Ret (T::*func)(P1, P2) const, P1 p1, P2 p2) : + myObj(obj), myFunc(func), myP1(p1), myP2(p2) {} + + /// Destructor + virtual ~ArConstRetFunctor2C() {} + + /// Invokes the functor with return value + virtual Ret invokeR(void) {return (myObj->*myFunc)(myP1, myP2);} + + /// Invokes the functor with return value + /** + @param p1 first parameter + */ + virtual Ret invokeR(P1 p1) {return (myObj->*myFunc)(p1, myP2);} + + /// Invokes the functor with return value + /** + @param p1 first parameter + @param p2 second parameter + */ + virtual Ret invokeR(P1 p1, P2 p2) {return (myObj->*myFunc)(p1, p2);} + + /// Set the 'this' pointer + /** + @param obj the 'this' pointer + */ + virtual void setThis(T *obj) {myObj=obj;} + + /// Set the 'this' pointer + /** + @param obj the 'this' pointer + */ + virtual void setThis(T &obj) {myObj=&obj;} + + /// Set the default parameter + /** + @param p1 default first parameter + */ + virtual void setP1(P1 p1) {myP1=p1;} + + /// Set the default 2nd parameter + /** + @param p2 default second parameter + */ + virtual void setP2(P2 p2) {myP2=p2;} + +protected: + + T *myObj; + Ret (T::*myFunc)(P1, P2) const; + P1 myP1; + P2 myP2; +}; + +/// Functor for a const member function with return value and 3 parameters +/** + This is a class for const member functions which take 3 parameters + and return a value. This class contains the knowledge on how to + call a member function on a particular instance of a class. This + class should be instantiated by code that wishes to pass off a + functor to another piece of code. + + For an overall description of functors, see ArFunctor. */ +template +class ArConstRetFunctor3C : public ArRetFunctor3 +{ +public: + + /// Constructor + ArConstRetFunctor3C() {} + + /// Constructor - supply function pointer + /** + @param obj object to call function on + @param func const member function pointer + */ + ArConstRetFunctor3C(T &obj, Ret (T::*func)(P1, P2, P3) const) : + myObj(&obj), myFunc(func), myP1(), myP2(), myP3() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func const member function pointer + @param p1 default first parameter + */ + ArConstRetFunctor3C(T &obj, Ret (T::*func)(P1, P2, P3) const, P1 p1) : + myObj(&obj), myFunc(func), myP1(p1), myP2(), myP3() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func const member function pointer + @param p1 default first parameter + @param p2 default second parameter + */ + ArConstRetFunctor3C(T &obj, Ret (T::*func)(P1, P2, P3) const, P1 p1, P2 p2) : + myObj(&obj), myFunc(func), myP1(p1), myP2(p2), myP3() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func const member function pointer + @param p1 default first parameter + @param p2 default second parameter + @param p3 default third parameter + */ + ArConstRetFunctor3C(T &obj, Ret (T::*func)(P1, P2, P3) const, P1 p1, P2 p2, P3 p3) : + myObj(&obj), myFunc(func), myP1(p1), myP2(p2), myP3(p3) {} + + /// Constructor - supply function pointer + /** + @param obj object to call function on + @param func const member function pointer + */ + ArConstRetFunctor3C(T *obj, Ret (T::*func)(P1, P2, P3) const) : + myObj(obj), myFunc(func), myP1(), myP2(), myP3() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func const member function pointer + @param p1 default first parameter + */ + ArConstRetFunctor3C(T *obj, Ret (T::*func)(P1, P2, P3) const, P1 p1) : + myObj(obj), myFunc(func), myP1(p1), myP2(), myP3() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func const member function pointer + @param p1 default first parameter + @param p2 default second parameter + */ + ArConstRetFunctor3C(T *obj, Ret (T::*func)(P1, P2, P3) const, P1 p1, P2 p2) : + myObj(obj), myFunc(func), myP1(p1), myP2(p2), myP3() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func const member function pointer + @param p1 default first parameter + @param p2 default second parameter + @param p3 default third parameter + */ + ArConstRetFunctor3C(T *obj, Ret (T::*func)(P1, P2, P3) const, P1 p1, P2 p2, P3 p3) : + myObj(obj), myFunc(func), myP1(p1), myP2(p2), myP3(p3) {} + + /// Destructor + virtual ~ArConstRetFunctor3C() {} + + /// Invokes the functor with return value + virtual Ret invokeR(void) {return (myObj->*myFunc)(myP1, myP2, myP3);} + + /// Invokes the functor with return value + /** + @param p1 first parameter + */ + virtual Ret invokeR(P1 p1) {return (myObj->*myFunc)(p1, myP2, myP3);} + + /// Invokes the functor with return value + /** + @param p1 first parameter + @param p2 second parameter + */ + virtual Ret invokeR(P1 p1, P2 p2) {return (myObj->*myFunc)(p1, p2, myP3);} + + /// Invokes the functor with return value + /** + @param p1 first parameter + @param p2 second parameter + @param p3 third parameter + */ + virtual Ret invokeR(P1 p1, P2 p2, P3 p3) + {return (myObj->*myFunc)(p1, p2, p3);} + + /// Set the 'this' pointer + /** + @param obj the 'this' pointer + */ + virtual void setThis(T *obj) {myObj=obj;} + + /// Set the 'this' pointer + /** + @param obj the 'this' pointer + */ + virtual void setThis(T &obj) {myObj=&obj;} + + /// Set the default parameter + /** + @param p1 default first parameter + */ + virtual void setP1(P1 p1) {myP1=p1;} + + /// Set the default 2nd parameter + /** + @param p2 default second parameter + */ + virtual void setP2(P2 p2) {myP2=p2;} + + /// Set the default third parameter + /** + @param p3 default third parameter + */ + virtual void setP3(P3 p3) {myP3=p3;} + +protected: + + T *myObj; + Ret (T::*myFunc)(P1, P2, P3) const; + P1 myP1; + P2 myP2; + P3 myP3; +}; + + + + +// Start 4 + + +/// Functor for a const member function with return value and 4 parameters +/** + This is a class for const member functions which take 4 parameters + and return a value. This class contains the knowledge on how to + call a member function on a particular instance of a class. This + class should be instantiated by code that wishes to pass off a + functor to another piece of code. + + For an overall description of functors, see ArFunctor. */ +template +class ArConstRetFunctor4C : public ArRetFunctor4 +{ +public: + + /// Constructor + ArConstRetFunctor4C() {} + + /// Constructor - supply function pointer + /** + @param obj object to call function on + @param func const member function pointer + */ + ArConstRetFunctor4C(T &obj, Ret (T::*func)(P1, P2, P3, P4) const) : + myObj(&obj), myFunc(func), myP1(), myP2(), myP3(), myP4() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func const member function pointer + @param p1 default first parameter + */ + ArConstRetFunctor4C(T &obj, Ret (T::*func)(P1, P2, P3, P4) const, P1 p1) : + myObj(&obj), myFunc(func), myP1(p1), myP2(), myP3(), myP4() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func const member function pointer + @param p1 default first parameter + @param p2 default second parameter + */ + ArConstRetFunctor4C(T &obj, Ret (T::*func)(P1, P2, P3, P4) const, P1 p1, P2 p2) : + myObj(&obj), myFunc(func), myP1(p1), myP2(p2), myP3(), myP4() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func const member function pointer + @param p1 default first parameter + @param p2 default second parameter + @param p3 default third parameter + */ + ArConstRetFunctor4C(T &obj, Ret (T::*func)(P1, P2, P3, P4) const, P1 p1, P2 p2, P3 p3) : + myObj(&obj), myFunc(func), myP1(p1), myP2(p2), myP3(p3), myP4() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func const member function pointer + @param p1 default first parameter + @param p2 default second parameter + @param p3 default third parameter + @param p4 default fourth parameter + */ + ArConstRetFunctor4C(T &obj, Ret (T::*func)(P1, P2, P3, P4) const, P1 p1, P2 p2, P3 p3, P4 p4) : + myObj(&obj), myFunc(func), myP1(p1), myP2(p2), myP3(p3), myP4(p4) {} + + + + /// Constructor - supply function pointer + /** + @param obj object to call function on + @param func const member function pointer + */ + ArConstRetFunctor4C(T *obj, Ret (T::*func)(P1, P2, P3, P4) const) : + myObj(obj), myFunc(func), myP1(), myP2(), myP3(), myP4() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func const member function pointer + @param p1 default first parameter + */ + ArConstRetFunctor4C(T *obj, Ret (T::*func)(P1, P2, P3, P4) const, P1 p1) : + myObj(obj), myFunc(func), myP1(p1), myP2(), myP3(), myP4() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func const member function pointer + @param p1 default first parameter + @param p2 default second parameter + */ + ArConstRetFunctor4C(T *obj, Ret (T::*func)(P1, P2, P3, P4) const, P1 p1, P2 p2) : + myObj(obj), myFunc(func), myP1(p1), myP2(p2), myP3(), myP4() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func const member function pointer + @param p1 default first parameter + @param p2 default second parameter + @param p3 default third parameter + */ + ArConstRetFunctor4C(T *obj, Ret (T::*func)(P1, P2, P3, P4) const, P1 p1, P2 p2, P3 p3) : + myObj(obj), myFunc(func), myP1(p1), myP2(p2), myP3(p3), myP4() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func const member function pointer + @param p1 default first parameter + @param p2 default second parameter + @param p3 default third parameter + @param p4 default fourth parameter + */ + ArConstRetFunctor4C(T *obj, Ret (T::*func)(P1, P2, P3, P4) const, P1 p1, P2 p2, P3 p3, P4 p4) : + myObj(obj), myFunc(func), myP1(p1), myP2(p2), myP3(p3), myP4(p4) {} + + /// Destructor + virtual ~ArConstRetFunctor4C() {} + + /// Invokes the functor with return value + virtual Ret invokeR(void) {return (myObj->*myFunc)(myP1, myP2, myP3, myP4);} + + /// Invokes the functor with return value + /** + @param p1 first parameter + */ + virtual Ret invokeR(P1 p1) {return (myObj->*myFunc)(p1, myP2, myP3, myP4);} + + /// Invokes the functor with return value + /** + @param p1 first parameter + @param p2 second parameter + */ + virtual Ret invokeR(P1 p1, P2 p2) {return (myObj->*myFunc)(p1, p2, myP3, myP4);} + + /// Invokes the functor with return value + /** + @param p1 first parameter + @param p2 second parameter + @param p3 second parameter + */ + virtual Ret invokeR(P1 p1, P2 p2, P3 p3) + {return (myObj->*myFunc)(p1, p2, p3, myP4);} + + /// Invokes the functor with return value + /** + @param p1 first parameter + @param p2 second parameter + @param p3 third parameter + @param p4 fourth parameter + */ + virtual Ret invokeR(P1 p1, P2 p2, P3 p3, P4 p4) + {return (myObj->*myFunc)(p1, p2, p3, p4);} + + + /// Set the 'this' pointer + /** + @param obj the 'this' pointer + */ + virtual void setThis(T *obj) {myObj=obj;} + + /// Set the 'this' pointer + /** + @param obj the 'this' pointer + */ + virtual void setThis(T &obj) {myObj=&obj;} + + /// Set the default parameter + /** + @param p1 default first parameter + */ + virtual void setP1(P1 p1) {myP1=p1;} + + /// Set the default 2nd parameter + /** + @param p2 default second parameter + */ + virtual void setP2(P2 p2) {myP2=p2;} + + /// Set the default third parameter + /** + @param p3 default third parameter + */ + virtual void setP3(P3 p3) {myP3=p3;} + + /// Set the default fourth parameter + /** + @param p4 default fourth parameter + */ + virtual void setP4(P4 p4) {myP4=p4;} + +protected: + + T *myObj; + Ret (T::*myFunc)(P1, P2, P3, P4) const; + P1 myP1; + P2 myP2; + P3 myP3; + P4 myP4; +}; + + + + +/// Functor for a const member function with return value and 5 parameters +/** + This is a class for const member functions which take 5 parameters + and return a value. This class contains the knowledge on how to + call a member function on a particular instance of a class. This + class should be instantiated by code that wishes to pass off a + functor to another piece of code. + + For an overall description of functors, see ArFunctor. */ +template +class ArConstRetFunctor5C : public ArRetFunctor5 +{ +public: + + /// Constructor + ArConstRetFunctor5C() {} + + /// Constructor - supply function pointer + /** + @param obj object to call function on + @param func const member function pointer + */ + ArConstRetFunctor5C(T &obj, Ret (T::*func)(P1, P2, P3, P4, P5) const) : + myObj(&obj), myFunc(func), myP1(), myP2(), myP3(), myP4(), myP5() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func const member function pointer + @param p1 default first parameter + */ + ArConstRetFunctor5C(T &obj, Ret (T::*func)(P1, P2, P3, P4, P5) const, P1 p1) : + myObj(&obj), myFunc(func), myP1(p1), myP2(), myP3(), myP4(), myP5() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func const member function pointer + @param p1 default first parameter + @param p2 default second parameter + */ + ArConstRetFunctor5C(T &obj, Ret (T::*func)(P1, P2, P3, P4, P5) const, P1 p1, P2 p2) : + myObj(&obj), myFunc(func), myP1(p1), myP2(p2), myP3(), myP4(), myP5() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func const member function pointer + @param p1 default first parameter + @param p2 default second parameter + @param p3 default third parameter + */ + ArConstRetFunctor5C(T &obj, Ret (T::*func)(P1, P2, P3, P4, P5) const, P1 p1, P2 p2, P3 p3) : + myObj(&obj), myFunc(func), myP1(p1), myP2(p2), myP3(p3), myP4(), myP5() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func const member function pointer + @param p1 default first parameter + @param p2 default second parameter + @param p3 default third parameter + @param p4 default fourth parameter + */ + ArConstRetFunctor5C(T &obj, Ret (T::*func)(P1, P2, P3, P4, P5) const, P1 p1, P2 p2, P3 p3, P4 p4) : + myObj(&obj), myFunc(func), myP1(p1), myP2(p2), myP3(p3), myP4(p4), myP5() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func const member function pointer + @param p1 default first parameter + @param p2 default second parameter + @param p3 default third parameter + @param p4 default fourth parameter + @param p5 default fifth parameter + */ + ArConstRetFunctor5C(T &obj, Ret (T::*func)(P1, P2, P3, P4, P5) const, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) : + myObj(&obj), myFunc(func), myP1(p1), myP2(p2), myP3(p3), myP4(p4), myP5(p5) {} + + + + /// Constructor - supply function pointer + /** + @param obj object to call function on + @param func const member function pointer + */ + ArConstRetFunctor5C(T *obj, Ret (T::*func)(P1, P2, P3, P4, P5) const) : + myObj(obj), myFunc(func), myP1(), myP2(), myP3(), myP4(), myP5() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func const member function pointer + @param p1 default first parameter + */ + ArConstRetFunctor5C(T *obj, Ret (T::*func)(P1, P2, P3, P4, P5) const, P1 p1) : + myObj(obj), myFunc(func), myP1(p1), myP2(), myP3(), myP4(), myP5() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func const member function pointer + @param p1 default first parameter + @param p2 default second parameter + */ + ArConstRetFunctor5C(T *obj, Ret (T::*func)(P1, P2, P3, P4, P5) const, P1 p1, P2 p2) : + myObj(obj), myFunc(func), myP1(p1), myP2(p2), myP3(), myP4(), myP5() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func const member function pointer + @param p1 default first parameter + @param p2 default second parameter + @param p3 default third parameter + */ + ArConstRetFunctor5C(T *obj, Ret (T::*func)(P1, P2, P3, P4, P5) const, P1 p1, P2 p2, P3 p3) : + myObj(obj), myFunc(func), myP1(p1), myP2(p2), myP3(p3), myP4(), myP5() {} + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func const member function pointer + @param p1 default first parameter + @param p2 default second parameter + @param p3 default third parameter + @param p4 default fourth parameter + */ + ArConstRetFunctor5C(T *obj, Ret (T::*func)(P1, P2, P3, P4, P5) const, P1 p1, P2 p2, P3 p3, P4 p4) : + myObj(obj), myFunc(func), myP1(p1), myP2(p2), myP3(p3), myP4(p4), myP5() {} + + + /// Constructor - supply function pointer, default parameters + /** + @param obj object to call function on + @param func const member function pointer + @param p1 default first parameter + @param p2 default second parameter + @param p3 default third parameter + @param p4 default fourth parameter + @param p5 default fifth parameter + */ + ArConstRetFunctor5C(T *obj, Ret (T::*func)(P1, P2, P3, P4, P5) const, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) : + myObj(obj), myFunc(func), myP1(p1), myP2(p2), myP3(p3), myP4(p4), myP5(p5) {} + + /// Destructor + virtual ~ArConstRetFunctor5C() {} + + /// Invokes the functor with return value + virtual Ret invokeR(void) {return (myObj->*myFunc)(myP1, myP2, myP3, myP4, myP5);} + + /// Invokes the functor with return value + /** + @param p1 first parameter + */ + virtual Ret invokeR(P1 p1) {return (myObj->*myFunc)(p1, myP2, myP3, myP4, myP5);} + + /// Invokes the functor with return value + /** + @param p1 first parameter + @param p2 second parameter + */ + virtual Ret invokeR(P1 p1, P2 p2) {return (myObj->*myFunc)(p1, p2, myP3, myP4, myP5);} + + /// Invokes the functor with return value + /** + @param p1 first parameter + @param p2 second parameter + @param p3 second parameter + */ + virtual Ret invokeR(P1 p1, P2 p2, P3 p3) + {return (myObj->*myFunc)(p1, p2, p3, myP4, myP5);} + + /// Invokes the functor with return value + /** + @param p1 first parameter + @param p2 second parameter + @param p3 third parameter + @param p4 fourth parameter + */ + virtual Ret invokeR(P1 p1, P2 p2, P3 p3, P4 p4) + {return (myObj->*myFunc)(p1, p2, p3, p4, myP5);} + + + /// Invokes the functor with return value + /** + @param p1 first parameter + @param p2 second parameter + @param p3 third parameter + @param p4 fourth parameter + @param p5 fifth parameter + */ + virtual Ret invokeR(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) + {return (myObj->*myFunc)(p1, p2, p3, p4, p5);} + + + /// Set the 'this' pointer + /** + @param obj the 'this' pointer + */ + virtual void setThis(T *obj) {myObj=obj;} + + /// Set the 'this' pointer + /** + @param obj the 'this' pointer + */ + virtual void setThis(T &obj) {myObj=&obj;} + + /// Set the default parameter + /** + @param p1 default first parameter + */ + virtual void setP1(P1 p1) {myP1=p1;} + + /// Set the default 2nd parameter + /** + @param p2 default second parameter + */ + virtual void setP2(P2 p2) {myP2=p2;} + + /// Set the default third parameter + /** + @param p3 default third parameter + */ + virtual void setP3(P3 p3) {myP3=p3;} + + /// Set the default fourth parameter + /** + @param p4 default fourth parameter + */ + virtual void setP4(P4 p4) {myP4=p4;} + + /// Set the default fifth parameter + /** + @param p5 default fifth parameter + */ + virtual void setP5(P5 p5) {myP5=p5;} + +protected: + + T *myObj; + Ret (T::*myFunc)(P1, P2, P3, P4, P5) const; + P1 myP1; + P2 myP2; + P3 myP3; + P4 myP4; + P5 myP5; +}; + + +#endif // omitting Const functors from SWIG + + + +#endif // ARFUNCTOR_H + + diff --git a/Legacy/Aria/include/ArFunctorASyncTask.h b/Legacy/Aria/include/ArFunctorASyncTask.h new file mode 100644 index 0000000..9371006 --- /dev/null +++ b/Legacy/Aria/include/ArFunctorASyncTask.h @@ -0,0 +1,47 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARFUNCTORASYNCTASK_H +#define ARFUNCTORASYNCTASK_H + +#include "ariaTypedefs.h" +#include "ArASyncTask.h" +#include "ArFunctor.h" + +/// This is like ArASyncTask, but instead of runThread it uses a functor to run +class ArFunctorASyncTask : public ArASyncTask +{ +public: + /// Constructor + AREXPORT ArFunctorASyncTask(ArRetFunctor1 *functor); + /// Destructor + AREXPORT virtual ~ArFunctorASyncTask(); + /// Our reimplementation of runThread + AREXPORT virtual void *runThread(void *arg); +protected: + ArRetFunctor1 *myFunc; +}; + +#endif diff --git a/Legacy/Aria/include/ArGPS.h b/Legacy/Aria/include/ArGPS.h new file mode 100644 index 0000000..bf41e87 --- /dev/null +++ b/Legacy/Aria/include/ArGPS.h @@ -0,0 +1,623 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ + +#ifndef ARGPS_H +#define ARGPS_H + +#include "ariaTypedefs.h" +#include "ArFunctor.h" +#include "ariaUtil.h" +#include "ArMutex.h" +#include "ArNMEAParser.h" +#include +#include +#include + +class ArDeviceConnection; // for pointer in ArGPS + +/** @brief GPS Device Interface + * + * Connects to GPS device over a serial port or other device connection and reads data. + * Supports GPS devices sending standard NMEA format data + * (specifically the GPRMC, GPGGA, GPGSA, GPGRME, and optionally GPGSV, PGRMZ, PGRME, + * HCHDG/T/M and GPHDG/T/M messages). + * If your GPS device supports several data formats or modes, select + * NMEA output in its configuration. + * + * The preferred method of creating and setting up a new ArGPS object is to use + * ArGPSConnector, which creates an instance of ArGPS or a subclass, and + * creates and opens its device connection, based on command-line parameters. + * (To manually create an ArGPS object, create an ArDeviceConnection instance + * and call setDeviceConnection(), then open that device connection and call + * connect(). + * + * For either method, to get new data from the GPS, must call read() or readWithLock() periodically, + * ideally at a rate equal to or faster than your GPS sends data (usually one second). + * You can do this from a Sensor Intetrpretation Task in ArRobot, or a seperate thread. + * If you are calling read() from a loop in a new thread, + * + * Here is an example of calling readWithLock() from a sensor interpretation + * task. The integer argument given to the functor constructor is a milisecond timeout that + * is passed to readWithLock() and prevents it from blocking too long if it doesn't read any data. + * It is important to do this in a robot task, or the robot task cycle will be + * blocked and cause problems. + * @code + * ArRetFunctor1C gpsReadFunc(myGPS, &ArGPS::readWithLock, 10); + * myRobot->addSensorInterpretationTask("GPS read", 100, &gpsReadFunc); + * @endcode + * + * If you use your own loop or thread, then it ought to include a call to ArUtil::sleep() for at least several hundred + * miliseconds to avoid starving other threads, since read() will return + * immediately if there is no data to read rather than blocking. + * + * For each piece of data provided by this class, there is a flag indicating + * whether it was received from the GPS and set. Not all GPS models return all + * kinds of information, or it may be disabled in some way in a GPS's internal + * configuration, or the GPS may not yet have started sending the data (e.g. + * still acquiring satellites). Also, not all data will be received by one call to read(), + * and especially immediately after connecting and starting to read data, it + * may take a few seconds for data to be obtained. Furthermore, it may take + * some time for the GPS to calculate data with full accuracy. + * + * @sa @ref gpsExample.cpp + * @sa @ref gpsRobotTaskExample.cpp + * + * This class is not inherently thread safe. Stored data is updated by read(), so + * if accessing from multiple threads, call lock() before calling any data + * accessor methods (methods starting with "get"), or read(), and call unlock() + * when done. You can also call readWithLock() to do a locked read in one + * function call. + * + * @note ArGPS only provides access to the data reported by a GPS. The position + * reported by a GPS is in degrees on the surface of the earth (WGS84 datum), not in the + * cartesian coordinate system used by the robot odometry or ArMap. You can use + * the subclasses of Ar3DPoint (ArLLACoords, etc) to convert between different + * geographical coordinate systems, which may help you match GPS coordinates to + * the robot pose coordinate system. + + @ingroup OptionalClasses + @ingroup DeviceClasses + */ +class ArGPS { + +public: + AREXPORT ArGPS(); + + virtual ~ArGPS() { } + + /** @brief Set device connection to use */ + void setDeviceConnection(ArDeviceConnection* deviceConn) { myDevice = deviceConn; } + + /** @brief Return device connection in use (or NULL if none) */ + ArDeviceConnection* getDeviceConnection() const { return myDevice; } + + + /** @brief Check that the device connection (e.g. serial port) is open, and + * that data is being received from GPS. + * + * Subclasses may override this method so that device-specific + * initialization commands may be sent. + * + * @return false if there is no device connection or the device connection + * is not open, or if there is an error sending device initialization + * commands, or if no data is received after calling read() every 100 ms + * for @a connectTimeout ms. Otherwise, return true. + * + * @sa blockingConnect() + */ + AREXPORT virtual bool connect(unsigned long connectTimeout = 20000); + + /** Same as connect(). See connect(). */ + bool blockingConnect(unsigned long connectTimeout = 20000) { return connect(connectTimeout); } + +protected: + /** Block until data is read from GPS. + Waits by calling read() every 100 ms for @a timeout ms. + */ + AREXPORT bool waitForData(unsigned long timeout); + + /** Subclasses may override to send device initialization/configuration + * commands and set up device-specific message handlers. (Default behavior + * is to do nothing and return true.) + */ + virtual bool initDevice() { return true; } + +public: + + + /** @brief Flags to indicates what the read() method did. + * i.e. If nothing was done, then the + * result will be 0. To check a read() return result @a result to see if data was updated, use + * (result & ReadUpdated). To check if there was an error, use (result & + * ReadError). + * + * These happen to match the flags in ArNMEAParser. + */ + enum { + ReadFinished = ArNMEAParser::ParseFinished, + ReadError = ArNMEAParser::ParseError, + ReadData = ArNMEAParser::ParseData, + ReadUpdated = ArNMEAParser::ParseUpdated + } ReadFlags; + + /** @brief Read some data from the device connection, and update stored data as complete messages are received. + * @param maxTime If nonzero, return when this time limit is reached, even if there is still data available to read. If zero, then don't return until all available data has been exhausted or an error occurs. + * Be careful setting this parameter to 0: read() could block for + * an arbitrary amount of time, even forever if for some reason data is recieved from + * the device faster than read() can read and parse it. + * @return A mask of ReadFlags codes, combined with bitwise or (|), or 0 if no attempt to read from the device occured (for example because the @a maxTime timeout was reached before the first attempt to read occured). The flags will include + * ReadError if there was as error reading from the device connection, + * ReadData if some data was read, + * ReadUpdated if data was read and a full message was successfully read and + * stored data was updated in ArGPS, + * ReadFinished if all available data was read. + */ + AREXPORT virtual int read(unsigned long maxTime = 0); + + /** Calls lock(), calls read(maxTime), then calls unlock(). Note, this could + * end up keeping ArGPS locked until @a maxTime is reached, or for any amount + * of time if @a maxTime is 0, so watch out for that. */ + int readWithLock(unsigned int maxTime) { lock(); int r = read(maxTime); unlock(); return r; } + + /** Locks a mutex object contained by this class. + * No other method (except readWithLock()) in ArGPS locks or unlocks this + * mutex, it is provided for you to use when accessing ArGPS from multiple + * threads. + */ + void lock() { myMutex.lock(); } + + /** Unlocks a mutex object contained by this class. + * No other method (except readWithLock()) in ArGPS locks or unlocks this + * mutex, it is provided for you to use when accessing ArGPS from multiple + * threads. + */ + void unlock() { myMutex.unlock(); } + + + /** @brief Set whether checksum sent with NMEA messages is ignored */ + void setIgnoreChecksum(bool ignore) { myNMEAParser.setIgnoreChecksum(ignore); } + + /** @brief Log last received data using ArLog. */ + AREXPORT void logData() const; + + /** Print basic navigation data on one line to standard output, with no newline at end. */ + AREXPORT void printData(bool labels = true) const; + + AREXPORT void printDataLabelsHeader() const; + + /** Data accessors + * @brief Access the last received data from the GPS */ + // @{ + + typedef enum { + NoFix, BadFix, GPSFix, DGPSFix, PPSFix, + RTKinFix, FloatRTKinFix, DeadReckFix, + ManualFix, SimulatedFix, UnknownFixType, + OmnistarConverging = FloatRTKinFix, + OmnistarConverged = RTKinFix + } FixType; + + class Data { + public: + AREXPORT Data(); + double latitude; ///< (from NMEA GPRMC) + double longitude; ///< (from NMEA GPRMC) + bool havePosition; ///< (from NMEA GPRMC) + ArTime timeGotPosition; ///< Local computer time when ArGPS class received the position message from the GPS. (From NMEA GPRMC) + double speed; ///< (From NMEA GPRMC, if provided) + bool haveSpeed; ///< (From NMEA GPRMC) + ArTime GPSPositionTimestamp; ///< Timestamp provided by GPS device along with latitude and longitude. (from NMEA GPRMC) + ArGPS::FixType fixType; ///< (from NMEA GPGGA) + unsigned short numSatellitesTracked; + double altitude; ///< receiver provides this based on GPS data. meters above sea level. (from NMEA GPGGA) + bool haveAltitude; //< (from NMEA GPGGA) + double altimeter; ///< from seperate altimeter (if receiver provides PGRMZ message). meters above sea level. + bool haveAltimeter; + unsigned short DGPSStationID; ///< (from NMEA GPGGA) + bool haveDGPSStation; ///< (from NMEA GPGGA) + double garminPositionError; ///< Error in meters, only some GPS devices provide this + bool haveGarminPositionError; ///< Error in meters, only some GPS devices provide this (PGRME) + double garminVerticalPositionError; ///< Error in meters, only some GPS devices provide this (PGRME) + bool haveGarminVerticalPositionError; ///< Error in meters, only some GPS devices provide this (PGRME) + double compassHeadingMag; ///< (from HCDHM message, if device provides it) + double compassHeadingTrue; ///< (from HCHDT, if device provides it) + bool haveCompassHeadingMag; ///< (from HCDHM message, if device provides it) + bool haveCompassHeadingTrue; ///< (from HCHDT message, if device provides it) + unsigned long compassMagCounter; ///< Incremented whenever @a compassHeadingMag is updated with new data + unsigned long compassTrueCounter; ///< Incremented whenever @a compassHeadingMag is updated with new data + bool haveHDOP; ///< Horizontal dilution of precision (from NMEA GPGGA) + double HDOP; ///< Horizontal dilution of precision (from NMEA GPGGA) + bool haveVDOP; ///< Vertical dilution of precision (from NMEA GPGGA) + double VDOP; ///< Vertical dilution of precision (from NMEA GPGGA) + bool havePDOP; ///< Combined dilution of precision (from NMEA GPGGA) + double PDOP; ///< Combined dilution of precision (from NMEA GPGGA) + bool qualityFlag; ///< Some GPS devices set this to false if data quality is below some thresholds. + double meanSNR; ///< Mean of satellite signal-noise ratios (dB) + bool haveSNR; ///< (from NMEA GPGSV) + double beaconSignalStrength; ///< dB (from NMEA GPMSS) + double beaconSNR; ///< dB (from NMEA GPMSS) + double beaconFreq; ///< kHz (from NMEA GPMSS) + unsigned short beaconBPS; ///< Bits/sec (from NMEA GPMSS) + unsigned short beaconChannel; ///< (from NMEA GPMSS) + bool haveBeaconInfo; ///< (from NMEA GPMSS) + double inputsRMS; ///< (from NMEA GPGST) + bool haveInputsRMS; ///< (from NMEA GPGST) + ArPose errorEllipse; ///< Ellipse shows standard deviation, in meters. Orientation is degrees from true north. (from NMEA GPGST) + bool haveErrorEllipse; ///< (from NMEA GPGST) + ArPose latLonError; ///< Std.deviation, meters. Theta is unused. May only be provided by the GPS in certain fix modes. Note, values could be inf or nan (GPS sends these in some situations). Use isinf() and isnan() to check. + bool haveLatLonError; + double altitudeError; ///< Std. deviation, meters. Note, value could be inf or nan (GPS sends these in some situations). use isinf() and isnan() to check. + bool haveAltitudeError; + }; + + /** Access all of the internally stored data directly. @see ArGPS::Data */ + const ArGPS::Data& getCurrentDataRef() const { return myData; } + + /** (from NMEA GPGGA) */ + FixType getFixType() const { return myData.fixType; } + /** (from NMEA GPGGA) */ + AREXPORT const char* getFixTypeName() const; + static AREXPORT const char* getFixTypeName(FixType type); + + /** (from NMEA GPRMC) */ + AREXPORT bool havePosition() const { return myData.havePosition; } + /** (from NMEA GPRMC) */ + AREXPORT bool haveLatitude() const { return myData.havePosition; } + /** (from NMEA GPRMC) */ + AREXPORT bool haveLongitude() const { return myData.havePosition; } + + /** @return latitude in decimal degrees. + (from NMEA GPRMC) */ + double getLatitude() const { return myData.latitude; } + + /** @return longitude in decimal degrees. + (from NMEA GPRMC) */ + double getLongitude() const { return myData.longitude; } + + /** @return copy of an ArTime object set to the time that ArGPS read and received latitude and longitude data from the GPS. + (from NMEA GPRMC) */ + ArTime getTimeReceivedPosition() const { return myData.timeGotPosition; } + + /** (from NMEA GPRMC) */ + bool haveSpeed() const { return myData.haveSpeed; } + + /** @return GPS' measured speed converted to meters per second, if provided + (from NMEA GPRMC, if provided) + */ + double getSpeed() const { return myData.speed; } + + /** Timestamp provided by GPS device along with position. (from NMEA GPRMC) */ + ArTime getGPSPositionTimestamp() const { return myData.GPSPositionTimestamp; } + + int getNumSatellitesTracked() const { return (int) myData.numSatellitesTracked; } + /** (from NMEA GPGGA) */ + bool haveDGPSStation() const { return myData.haveDGPSStation; } + /** (from NMEA GPGGA) */ + unsigned short getDGPSStationID() const { return myData.DGPSStationID; } + + /** @return whether GPS provided a distance error estimation (from a + * Garmin-specific message PGRME, most GPS receivers will not provide this) */ + bool haveGarminPositionError() const { return myData.haveGarminPositionError; } + /** GPS device's error estimation in meters (from a Garmin-specific message PGRME, + * most GPS receivers will not provide this)*/ + double getGarminPositionError() const { return myData.garminPositionError; } + /** @return whether GPS provided an altitude error estimation (from a + * Garmin-specific message PGRME, most GPS receivers will not provide this) */ + bool haveGarminVerticalPositionError() const { return myData.haveGarminVerticalPositionError; } + /** @return An altitude error estimation (from a Garmin-specific message PGRME, + * most GPS receivers will not provide this) */ + double getGarminVerticalPositionError() const { return myData.garminVerticalPositionError; } + + /** Have a compass heading value relative to magnetic north. + @note The GPS or compass device must be configured to send HCHDM messages + to receive compass data. Only some GPS receivers support this. + */ + bool haveCompassHeadingMag() const { return myData.haveCompassHeadingMag; } + /** Have a compass heading value relative to true north (using GPS/compass + device's configured declination). + @note The GPS or compass device must be configured to send HCHDT messages + to receive compass data. Only some GPS receivers support this. + */ + bool haveCompassHeadingTrue() const { return myData.haveCompassHeadingTrue; } + /** Heading from magnetic north + @note The GPS or compass device must be configured to send HCHDM messages + to receive compass data. Only some GPS receivers support this. + */ + double getCompassHeadingMag() const { return myData.compassHeadingMag; } + /** Heading from true north + @note The GPS or compass device must be configured to send HCHDT messages + to receive compass data. Only some GPS receivers support this. + */ + double getCompassHeadingTrue() const { return myData.compassHeadingTrue; } + + + /** Manually set compass value. */ + void setCompassHeadingMag(double val) { + myData.haveCompassHeadingMag = true; + myData.compassHeadingMag = val; + myData.compassMagCounter++; + } + + /** Manually set compass value. */ + void setCompassHeadingTrue(double val) { + myData.haveCompassHeadingTrue = true; + myData.compassHeadingTrue = val; + myData.compassMagCounter++; + } + + /** Manually set compass value. */ + void setCompassHeadingMagWithLock(double val) { lock(); setCompassHeadingMag(val); unlock(); } + /** Manually set compass value. */ + void setCompassHeadingTrueWithLock(double val) { lock(); setCompassHeadingTrue(val); unlock(); } + + /// Altitude above sea level calculated from satellite positions (see also haveAltimiter()) (from NMEA GPGGA, if provided) + bool haveAltitude() const { return myData.haveAltitude; } + /// Altitude above sea level (meters), calculated from satellite positions (see also getAltimiter()) (from NMEA GPGGA, if provided) + double getAltitude() const { return myData.altitude; } + + /// Some receivers may have an additional altitude from an altimiter (meters above sea level) (from PGRMZ, if receiver provides it) + bool haveAltimeter() const { return myData.haveAltimeter; } + /// Some receivers may have an additional altitude from an altimiter (meters above sea level) (from PGRMZ, if receiver provides it) + double getAltimeter() const { return myData.altimeter; } + + /** (from NMEA GPGGA) */ + bool haveHDOP() const { return myData.haveHDOP; } + /** (from NMEA GPGGA) */ + double getHDOP() const { return myData.HDOP; } + /** (from NMEA GPGGA) */ + bool haveVDOP() const { return myData.haveVDOP; } + /** (from NMEA GPGGA) */ + double getVDOP() const { return myData.VDOP; } + /** (from NMEA GPGGA) */ + bool havePDOP() const { return myData.havePDOP; } + /** (from NMEA GPGGA) */ + double getPDOP() const { return myData.PDOP; } + + /** (from NMEA GPGSV) */ + bool haveSNR() const { return myData.haveSNR; } + /// dB (from NMEA GPGSV) + double getMeanSNR() const { return myData.meanSNR; } + + /** Whether we have any DGPS stationary beacon info (from NMEA GPMSS) */ + bool haveBeaconInfo() const { return myData.haveBeaconInfo; } + /** DGPS stationary beacon signal strength (dB) (from NMEA GPMSS) */ + double getBeaconSignalStrength() const { return myData.beaconSignalStrength; } + /** DGPS stationary beacon signal to noise (dB) (from NMEA GPMSS) */ + double getBeaconSNR() const { return myData.beaconSNR; } + /** DGPS stationary beacon frequency (kHz) (from NMEA GPMSS) */ + double getBeaconFreq() const { return myData.beaconFreq; } + /** DGPS stationary beacon bitrate (bits per second) (from NMEA GPMSS) */ + unsigned short getBecaonBPS() const { return myData.beaconBPS; } + /** DGPS stationary beacon channel (from NMEA GPMSS) */ + unsigned short getBeaconChannel() const { return myData.beaconChannel; } + + /** Whether we have a position error estimate (as standard deviations in latitude and longitude) (from NMEA GPGST) */ + bool haveErrorEllipse() const { return myData.haveErrorEllipse; } + /** Standard deviation of position error (latitude and longitude), meters. Theta in ArPose is orientation of ellipse from true north, Y is the length of the major axis on that orientation, X the minor. + (from NMEA GPGST) + @note Values may be inf or NaN (if GPS supplies "Inf" or "NAN") + */ + ArPose getErrorEllipse() const {return myData.errorEllipse; } + + /** Whether we have latitude or longitude error estimates (from NMEA GPGST) */ + bool haveLatLonError() const { return myData.haveLatLonError; } + /** Standard deviation of latitude and longitude error, meters. + Theta value in ArPose is unused. + @note May only be provided by GPS in certain fix modes + (e.g. Trimble AgGPS provides it in Omnistar and RTK modes, but not in GPS + or DGPS modes). + @note Values may be inf or NaN (if GPS supplies "Inf" or "NAN") + (from NMEA GPGST) + */ + ArPose getLatLonError() const { return myData.latLonError; } + /** @copydoc getLatLonError() */ + double getLatitudeError() const { return myData.latLonError.getX(); } + /** @copydoc getLatLonError() */ + double getLongitudeError() const { return myData.latLonError.getY(); } + + bool haveAltitudeError() const { return myData.haveAltitudeError; } + /// Standard deviation of altitude error, meters. (from NMEA GPGST, if provided) + double getAltitudeError() const { return myData.altitudeError; } + + /// (from NMEA GPGST) + bool haveInputsRMS() const { return myData.haveInputsRMS; } + /// (from NMEA GPGST) + double getInputsRMS() const { return myData.inputsRMS; } + + + + /** Set a handler for an NMEA message. Mostly for internal use or to be used + * by related classes, but you could use for ususual or custom messages + * emitted by a device that you wish to be handled outside of the ArGPS + * class. + */ + void addNMEAHandler(const char *message, ArNMEAParser::Handler *handler) { myNMEAParser.addHandler(message, handler); } + void removeNMEAHandler(const char *message) { myNMEAParser.removeHandler(message); } + void replaceNMEAHandler(const char *message, ArNMEAParser::Handler *handler) { + myNMEAParser.removeHandler(message); + myNMEAParser.addHandler(message, handler); + } + +protected: + + + /* Most recent data values received, to return to user */ + Data myData; + + /* Utility to read a double floating point number out of a std::string, if possible. + * @return true if the string was nonempty and @a target was modified. + */ + bool readFloatFromString(const std::string& str, double* target, double(*convf)(double) = NULL) const; + + /* Utility to read an unsigned short integer out of a std::string, if possible. + * @return true if the string was nonempty and @a target was modified. + */ + bool readUShortFromString(const std::string& str, unsigned short* target, unsigned short (*convf)(unsigned short) = NULL) const; + + + /* Utility to read a double from a member of a vector of strings, if it exists. */ + bool readFloatFromStringVec(const std::vector* vec, size_t i, double* target, double (*convf)(double) = NULL) const; + + /* Utility to read a double from a member of a vector of strings, if it exists. */ + bool readUShortFromStringVec(const std::vector* vec, size_t i, unsigned short* target, unsigned short (*convf)(unsigned short) = NULL) const; + + /* Utility to convert DDDMM.MMMM to decimal degrees */ + static double gpsDegminToDegrees(double degmin); + + /* Utility to convert US nautical knots to meters/sec */ + static double knotsToMPS(double knots); + + /** Convert meters per second to miles per hour */ + static double mpsToMph(const double mps) { return mps * 2.23693629; } + + /* Utility to convert meters to US feet */ + static double metersToFeet(double m) { return m * 3.2808399; } + + /* Utility to convert US feet to meters */ + static double feetToMeters(double f) { return f / 3.2808399; } + + + + /* Mutex */ + ArMutex myMutex; + + + /* Connection info */ + ArDeviceConnection *myDevice; + bool myCreatedOwnDeviceCon; + ArRetFunctorC myParseArgsCallback; + ArArgumentParser* myArgParser; + + /* NMEA Parser */ + ArNMEAParser myNMEAParser; + + /* GPS message handlers */ + + void handleGPRMC(ArNMEAParser::Message msg); + ArFunctor1C myGPRMCHandler; + + void handleGPGGA(ArNMEAParser::Message msg); + ArFunctor1C myGPGGAHandler; + + void handlePGRME(ArNMEAParser::Message msg); + ArFunctor1C myPGRMEHandler; + + void handlePGRMZ(ArNMEAParser::Message msg); + ArFunctor1C myPGRMZHandler; + + void handleHCHDx(ArNMEAParser::Message msg); + ArFunctor1C myHCHDxHandler; + + void handleGPGSA(ArNMEAParser::Message msg); + ArFunctor1C myGPGSAHandler; + + void handleGPGSV(ArNMEAParser::Message msg); + ArFunctor1C myGPGSVHandler; + + /* For calculating SNR averages based on multiple GPGSV messages. */ + unsigned int mySNRSum; + unsigned short mySNRNum; + + void handleGPMSS(ArNMEAParser::Message msg); + ArFunctor1C myGPMSSHandler; + + void handleGPGST(ArNMEAParser::Message msg); + ArFunctor1C myGPGSTHandler; + + /* Set an ArTime object using a time read from a string as decimal seconds (SSS.SS) */ + bool readTimeFromString(const std::string& s, ArTime* time) const; + + /** Parse a GPRMC message (in @a msg) and place results in provided + * variables. (Can be used by subclasses to store results of GPRMC differently + * than normal.) + * @since Aria 2.7.2 + */ + void parseGPRMC(const ArNMEAParser::Message &msg, double &latitudeResult, double &longitudeResult, bool &qualityFlagResult, bool &gotPosition, ArTime &timeGotPositionResult, ArTime &gpsTimestampResult, bool &gotSpeedResult, double &speedResult); + +}; + + +class ArRobotPacket; +class ArRobot; + +/// @since Aria 2.7.4 +class ArSimulatedGPS : public virtual ArGPS +{ + bool myHaveDummyPosition; + ArRetFunctor1C mySimStatHandlerCB; + ArRobot *myRobot; +public: + AREXPORT ArSimulatedGPS(ArRobot *robot = NULL); + AREXPORT virtual ~ArSimulatedGPS(); + void setDummyPosition(double latitude, double longitude) { + myData.latitude = latitude; + myData.havePosition = true; + myData.longitude = longitude; + if(!myData.haveHDOP) myData.HDOP = 1.0; + myData.haveHDOP = true; + if(!myData.haveVDOP) myData.VDOP = 1.0; + myData.haveVDOP = true; + if(!myData.havePDOP) myData.PDOP = 1.0; + myData.havePDOP = true; + myData.fixType = SimulatedFix; + myHaveDummyPosition = true; + } + void clearDummyPosition() { + clearPosition(); + myHaveDummyPosition = false; + } + void clearPosition() { + myData.havePosition = false; + myData.latitude = 0; + myData.longitude = 0; + myData.altitude = 0; + myData.HDOP = 0; + myData.VDOP = 0; + myData.PDOP = 0; + myData.fixType = NoFix; + } + void setDummyPosition(double latitude, double longitude, double altitude) { + myData.altitude = altitude; + setDummyPosition(latitude, longitude); + } + AREXPORT void setDummyPosition(ArArgumentBuilder *args); + void setDummyPositionFromArgs(ArArgumentBuilder *args) { setDummyPosition(args); } // non-overloaded function can be used in functors + AREXPORT virtual bool connect(unsigned long connectTimeout = 10000); + virtual bool initDevice() { return true; } + virtual int read(unsigned long maxTime = 0) { + if(myHaveDummyPosition) + { + myData.timeGotPosition.setToNow(); + } + return ReadUpdated | ReadFinished; + } +private: +#ifndef SWIG + bool handleSimStatPacket(ArRobotPacket *pkt); +#endif +}; + +#endif // ifdef ARGPS_H diff --git a/Legacy/Aria/include/ArGPSConnector.h b/Legacy/Aria/include/ArGPSConnector.h new file mode 100644 index 0000000..0e7a0a6 --- /dev/null +++ b/Legacy/Aria/include/ArGPSConnector.h @@ -0,0 +1,142 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ + +#ifndef ARGPSCONNECTOR_H +#define ARGPSCONNECTOR_H + +#include +#include + +#include "ariaTypedefs.h" +#include "ariaUtil.h" +#include "ArFunctor.h" +#include "ArGPS.h" + +class ArDeviceConnection; +class ArRobot; + +/** + * @brief Factory for creating GPS interface object (for any kind of GPS supported by ARIA) based on robot parameter file and command-line arguments. + * + * First, create an ArGPSConnector object before + * calling Aria::parseArgs(). After connecting to the robot, call + * Aria::parseArgs(). Then, call createGPS() to create the GPS object. + * + * ArGPSConnector can connect to a Novatel GPS ("novatel" type), Trimble AgGPS + * ("trimble" type), or any GPS + * supporting the NMEA standard protocol ("standard" type), if that GPS does not need any special + * commands to initialize. + * + * @note The device connection object created by + * ArGPSConnector is destroyed when ArGPSConnector is + * destroyed. Therefore, you must not destroy an ArGPSConnector + * while its associated ArGPS is in use. + * + * The following command-line arguments are checked: + * @verbinclude ArGPSConnector_options + * + * Only one GPS device may be configured and connected to by this object. + * + @ingroup OptionalClasses + @ingroup DeviceClasses +*/ + +class ArGPSConnector { +public: + AREXPORT ArGPSConnector(ArArgumentParser* argParser); + AREXPORT ~ArGPSConnector(); + + /** Gets command line arguments */ + AREXPORT bool parseArgs(); + + + /** Create a new GPS object (may be an ArGPS subclass based on device type) + * and a device connection for that GPS. Use ArGPS::blockingConnect() to open the connection. + * + * @param robot If not NULL, obtain default values for GPS type, port and baud + * from this robot's parameters (given in parameter file), for any of these + * not set from command-line arguments in parseArgs(). + * + * @return NULL if there was an error creating a GPS object or an error + * creating and opening its device connection. Otherwise, return the new GPS + * object. + */ + AREXPORT ArGPS* createGPS(ArRobot *robot = NULL); + /** @copydoc createGPS() */ + AREXPORT ArGPS* create(ArRobot *robot = NULL) { return createGPS(robot); } + +#if 0 + +//doesn't really do anything : + /** Try to establish a device connection between @a gps (created by calling + * createGPS() and the GPS receiver. + */ + AREXPORT bool connectGPS(ArGPS *gps); + /** @copydoc connectGPS() */ + AREXPORT bool connect(ArGPS *gps) { return connectGPS(gps) ; } +#endif + + /** @brief Device type identifiers */ + typedef enum { + /// For a standard NMEA GPS device (no extra initialization or interpretation needed) accessible using ArGPS + Standard, + /// For a Novatel device accessible using ArNovatelGPS + Novatel, + /// For a Trimble device accessible using ArTrimbleGPS + Trimble, + /// Not set or invalid + Invalid, + /// Novatel SPAN + /// @since Aria 2.7.2 + NovatelSPAN, + /// Simulated (program must set dummy positions) + /// @since Aria 2.7.6 + Simulator + } GPSType; + + AREXPORT GPSType getGPSType() const { return myDeviceType; } + +protected: + ArDeviceConnection *myDeviceCon; + ArArgumentParser *myArgParser; + ArRetFunctorC myParseArgsCallback; + ArFunctorC myLogArgsCallback; + int myBaud; + const char *myPort; + const char *myTCPHost; + int myTCPPort; + GPSType myDeviceType; + + + /** Log argument option information */ + AREXPORT void logOptions(); + AREXPORT GPSType deviceTypeFromString(const char *str); +}; + + +#endif // ifdef ARGPSCONNECTOR_H + + diff --git a/Legacy/Aria/include/ArGPSCoords.h b/Legacy/Aria/include/ArGPSCoords.h new file mode 100644 index 0000000..c7327d6 --- /dev/null +++ b/Legacy/Aria/include/ArGPSCoords.h @@ -0,0 +1,234 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARGPSCOORDS_H +#define ARGPSCOORDS_H + +#include "ariaTypedefs.h" + + + +class Ar3DPoint; +class ArLLACoords; +class ArECEFCoords; +class ArENUCoords; +class ArWGS84; + +/** Base class for points in 3 dimensional cartesian space. + @ingroup UtilityClasses +*/ +class Ar3DPoint +{ + public: + + Ar3DPoint(void) : myX(0), myY(0), myZ(0) {} + Ar3DPoint(double x, double y, double z) : myX(x), myY(y), myZ(z) {} + /// Destructor. + ~Ar3DPoint() {} + /// Add + Ar3DPoint operator+(Ar3DPoint c) + { + Ar3DPoint sum(myX + c.myX, + myY + c.myY, + myZ + c.myZ); + + return sum; + } + /// Diff + Ar3DPoint operator-(Ar3DPoint c) + { + Ar3DPoint dif(myX - c.myX, + myY - c.myY, + myZ - c.myZ); + return dif; + } + /// Diff + Ar3DPoint operator*(double c) + { + Ar3DPoint pro(myX*c, myY*c, myZ*c); + return pro; + } + /// Dot product + double dot(Ar3DPoint c) + { + double dotP(myX * c.myX + myY * c.myY + myZ * c.myZ); + return dotP; + } + /// Cross product + Ar3DPoint cross(Ar3DPoint c) + { + Ar3DPoint crossP(myY * c.myZ - myZ * c.myY, + myZ * c.myX - myX * c.myZ, + myX * c.myY - myY * c.myX); + return crossP; + } + /// Print. + /** @swignote Use 'printPoint' instead */ + AREXPORT void print(const char* head=NULL); + + double getX() const {return myX;} + double getY() const {return myY;} + double getZ() const {return myZ;} + void setX(double x) { myX = x; } + void setY(double y) { myY = y; } + void setZ(double z) { myZ = z; } + +protected: + + double myX; + double myY; + double myZ; + +}; + +#ifdef WIN32 +// Need to export some variables on Windows because they are used in inline methods (which is good), but they can't be exported if const. +#define ARGPSCOORDS_CONSTANT +#else +#define ARGPSCOORDS_CONSTANT const +#endif + + +/** + * All the constants defined by the World Geodetic System 1984. + * @ingroup UtilityClasses + */ +class ArWGS84 +{ + public: + ArWGS84(void) {} + + static double getE() {return mye;} + static double getA() {return mya;} + static double getB() {return myb;} + static double getEP() {return myep;} + static double get1byf() {return my1byf;} + static double getOmega() {return myOmega;} + static double getGM() {return myGM;} + + +private: + AREXPORT static ARGPSCOORDS_CONSTANT double mya; // meters + AREXPORT static ARGPSCOORDS_CONSTANT double myb; // meters + AREXPORT static ARGPSCOORDS_CONSTANT double myep; + AREXPORT static ARGPSCOORDS_CONSTANT double myc; // m/sec + AREXPORT static ARGPSCOORDS_CONSTANT double mye; + AREXPORT static ARGPSCOORDS_CONSTANT double my1byf; + AREXPORT static ARGPSCOORDS_CONSTANT double myOmega; // rad/sec + AREXPORT static ARGPSCOORDS_CONSTANT double myGM; // m^3/sec^2 + AREXPORT static ARGPSCOORDS_CONSTANT double myg; // m/sec^2. Ave g. + AREXPORT static ARGPSCOORDS_CONSTANT double myM; // kg. Mass of earth. +}; + + +/** + * Earth Centered Earth Fixed Coordinates. + @ingroup UtilityClasses + */ +class ArECEFCoords : public Ar3DPoint +{ + public: + ArECEFCoords(double x, double y, double z) : Ar3DPoint(x, y, z) {} + AREXPORT ArLLACoords ECEF2LLA(void); + AREXPORT ArENUCoords ECEF2ENU(ArECEFCoords ref); +}; + +/** + * Latitude, Longitude and Altitude Coordinates. + * @ingroup UtilityClasses + */ +class ArLLACoords : public Ar3DPoint +{ + public: + ArLLACoords(void) : Ar3DPoint(0, 0, 0) {} + ArLLACoords(double x, double y, double z) : Ar3DPoint(x, y, z) {} + AREXPORT ArECEFCoords LLA2ECEF(void); + double getLatitude(void) const {return getX();} + double getLongitude(void) const {return getY();} + double getAltitude(void) const {return getZ();} + void setLatitude(double l) { setX(l); } + void setLongitude(double l) { setY(l); } + void setAltitude(double a) { setZ(a); } +}; + +/** + * East North Up coordinates. + @ingroup UtilityClasses + */ +class ArENUCoords : public Ar3DPoint +{ + public: + ArENUCoords(double x, double y, double z) : Ar3DPoint(x, y, z) {} + AREXPORT ArECEFCoords ENU2ECEF(ArLLACoords ref); + double getEast(void) const {return getX();} + double getNorth(void) const {return getY();} + double getUp(void) const {return getZ();} + void setEast(double e) { setX(e); } + void setNorth(double n) { setY(n); } + void setUp(double u) { setZ(u); } +}; + +/** + * Coordinates based on a map with origin in LLA coords with conversion + * methods from LLA to ENU and from ENU to LLA coordinates. + * @ingroup UtilityClasses + */ +class ArMapGPSCoords : public ArENUCoords +{ + public: + ArMapGPSCoords(ArLLACoords org) : ArENUCoords(0.0, 0.0, 0.0), myOriginECEF(0), myOriginLLA(0), myOriginSet(false) + { + setOrigin(org); + } + ArMapGPSCoords() : ArENUCoords(0, 0, 0), myOriginECEF(0), myOriginLLA(0), myOriginSet(false) + { + } + AREXPORT bool convertMap2LLACoords(const double ea, const double no, const double up, + double& lat, double& lon, double& alt) const; + AREXPORT bool convertLLA2MapCoords(const double lat, const double lon, const double alt, + double& ea, double& no, double& up) const; + bool convertLLA2MapCoords(const ArLLACoords& lla, double& ea, double& no, double& up) +{ + return convertLLA2MapCoords(lla.getLatitude(), lla.getLongitude(), lla.getAltitude(), ea, no, up); + } + void setOrigin(ArLLACoords org) { + if(myOriginLLA) + delete myOriginLLA; + if(myOriginECEF) + delete myOriginECEF; + myOriginSet = true; + myOriginLLA = new ArLLACoords(org); + myOriginECEF = new ArECEFCoords(myOriginLLA->LLA2ECEF()); + } + + ArECEFCoords* myOriginECEF; + ArLLACoords* myOriginLLA; + bool myOriginSet; +}; + + + + +#endif // ARGPSCOORDS_H diff --git a/Legacy/Aria/include/ArGripper.h b/Legacy/Aria/include/ArGripper.h new file mode 100644 index 0000000..abc7a96 --- /dev/null +++ b/Legacy/Aria/include/ArGripper.h @@ -0,0 +1,151 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARGRIPPER_H +#define ARGRIPPER_H + +#include "ariaTypedefs.h" +#include "ArRobot.h" + +/// Contains gripper command numbers +/** + A class with an enum of the commands for the gripper, see the Pioneer operations + manual and the gripper guide available at http://robots.mobilerobots.com for more detailed descriptions. The enum + values which start with GRIP are for the gripper paddles, the ones which + start with LIFT are the for the lift, and the ones which start with GRIPPER + are for the entire unit. +*/ +class ArGripperCommands +{ +public: + enum Commands { + GRIP_OPEN = 1, ///< open the gripper paddles fully + GRIP_CLOSE = 2, ///< close the gripper paddles all the way + GRIP_STOP = 3, ///< stop the gripper paddles where they are + LIFT_UP = 4, ///< raises the lift to the top of its range + LIFT_DOWN = 5, ///< lowers the lift to the bottom of its range + LIFT_STOP = 6, ///< stops the lift where it is + GRIPPER_STORE = 7, /**< + closes the paddles and raises the lift simultaneously, + this is for storage not for grasping/carrying an object + */ + GRIPPER_DEPLOY = 8, /**< + opens the paddles and lowers the lieft simultaneously, + this is for getting ready to grasp an object, not for + object drops + */ + GRIPPER_HALT = 15, ///< stops the gripper paddles and lift from moving + GRIP_PRESSURE = 16, /**< + sets the time delay in 20 msec increments after the + gripper paddles first grasp an object before they stop + moving, regulates grasp pressure + */ + LIFT_CARRY = 17 /**< + raises or lowers the lieft, the argument is the number + of 20 msec increments to raise or lower the lift, + poseitive arguments for raise, negative for lower + */ + }; +}; + +/// Provides an interface to the Pioneer gripper device +/// @ingroup OptionalClasses +/// @ingroup DeviceClasses +class ArGripper +{ +public: + /// Constructor + AREXPORT ArGripper(ArRobot *robot, int gripperType = QUERYTYPE); + /// Destructor + AREXPORT virtual ~ArGripper(); + /// Opens the gripper paddles + AREXPORT bool gripOpen(void); + /// Closes the gripper paddles + AREXPORT bool gripClose(void); + /// Stops the gripper paddles + AREXPORT bool gripStop(void); + /// Raises the lift to the top + AREXPORT bool liftUp(void); + /// Lowers the lift to the bottom + AREXPORT bool liftDown(void); + /// Stops the lift + AREXPORT bool liftStop(void); + /// Puts the gripper in a storage position + AREXPORT bool gripperStore(void); + /// Puts the gripper in a deployed position, ready for use + AREXPORT bool gripperDeploy(void); + /// Halts the lift and the gripper paddles + AREXPORT bool gripperHalt(void); + /// Sets the amount of pressure the gripper applies + AREXPORT bool gripPressure(int mSecIntervals); + /// Raises the lift by a given amount of time + AREXPORT bool liftCarry(int mSecIntervals); + /// Returns true if the gripper paddles are moving + AREXPORT bool isGripMoving(void) const; + /// Returns true if the lift is moving + AREXPORT bool isLiftMoving(void) const; + /// Returns the state of the gripper paddles + AREXPORT int getGripState(void) const; + /// Returns the state of each gripper paddle + AREXPORT int getPaddleState(void) const; + /// Returns the state of the gripper's breakbeams + AREXPORT int getBreakBeamState(void) const; + /// Returns the state of the lift + AREXPORT bool isLiftMaxed(void) const; + /// Gets the type of the gripper + AREXPORT int getType(void) const; + /// Sets the type of the gripper + AREXPORT void setType(int type); + /// Gets the number of mSec since the last gripper packet + AREXPORT long getMSecSinceLastPacket(void) const; + /// Gets the grasp time + AREXPORT int getGraspTime(void) const; + /// logs the gripper state + AREXPORT void logState(void) const; + /// Parses the gripper packet + AREXPORT bool packetHandler(ArRobotPacket *packet); + /// The handler for when the robot connects + AREXPORT void connectHandler(void); + /// These are the types for the gripper + enum Type { + QUERYTYPE, ///< Finds out what type from the robot, default + GENIO, ///< Uses general IO + USERIO, ///< Uses the user IO + GRIPPAC, ///< Uses a packet requested from the robot + NOGRIPPER ///< There isn't a gripper + }; +protected: + ArRobot *myRobot; + int myType; + unsigned char myState; + unsigned char mySwitches; + unsigned char myGraspTime; + ArTime myLastDataTime; + ArFunctorC myConnectCB; + ArRetFunctor1C myPacketHandlerCB; +}; + + +#endif // ARGRIPPER_H diff --git a/Legacy/Aria/include/ArHasFileName.h b/Legacy/Aria/include/ArHasFileName.h new file mode 100644 index 0000000..c9603d3 --- /dev/null +++ b/Legacy/Aria/include/ArHasFileName.h @@ -0,0 +1,69 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARHASFILENAME_H +#define ARHASFILENAME_H + +#include "ariaTypedefs.h" + +/// Interface to access an object's associated file name. +/** + * ArHasFileName provides a single abstract method which should be overridden + * to return the complete file path name of the associated file. It is + * implemented by classes that have external persistent storage, such as + * ArConfig and ArMap. + * + * Copyright (c) Adept Technology, Inc. All rights reserved. +**/ +class ArHasFileName +{ +public: + + /// Constructor + AREXPORT ArHasFileName() + {} + + /// Copy constructor + ArHasFileName(ArHasFileName const &) + {} + + /// Assignment operator. + ArHasFileName &operator=(ArHasFileName const & ) + { + return *this; + } + + /// Destructor + AREXPORT virtual ~ArHasFileName() + {} + + /// Returns the complete file path name of the associated file + AREXPORT virtual const char *getFileName() const = 0; + +}; // end class + + +#endif // ARHASFILENAME_H + diff --git a/Legacy/Aria/include/ArIRs.h b/Legacy/Aria/include/ArIRs.h new file mode 100644 index 0000000..f4bbc53 --- /dev/null +++ b/Legacy/Aria/include/ArIRs.h @@ -0,0 +1,59 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARIRS_H +#define ARIRS_H + +#include "ariaTypedefs.h" +#include "ArRangeDevice.h" + + +/// A class that treats a robot's infrared sensors as a range device. +/** + (Only Peoplebot and some Powerbots have IR sensors.) + + @ingroup OptionalClasses + @ingroup DeviceClasses +*/ +class ArIRs : public ArRangeDevice +{ +public: + AREXPORT ArIRs(size_t currentBufferSize = 10, + size_t cumulativeBufferSize = 10, + const char *name = "irs", + int maxSecondsToKeepCurrent = 15); + AREXPORT virtual ~ArIRs(void); + + AREXPORT virtual void setRobot(ArRobot *robot); + AREXPORT void processReadings(void); + +protected: + ArFunctorC myProcessCB; + ArRobotParams myParams; + std::vector cycleCounters; +}; + + +#endif // ARIRS_H diff --git a/Legacy/Aria/include/ArInterpolation.h b/Legacy/Aria/include/ArInterpolation.h new file mode 100644 index 0000000..7a89ba5 --- /dev/null +++ b/Legacy/Aria/include/ArInterpolation.h @@ -0,0 +1,96 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARINTERPOLATION_H +#define ARINTERPOLATION_H + +#include "ariaTypedefs.h" +#include "ariaUtil.h" + +/** + This class takes care of storing in readings of position vs time, and then + interpolating between them to find where the robot was at a particular + point in time. It has two lists, one containing the times, and one + containing the positions at those same times (per position), they must be + walked through jointly to maintain cohesion. The new entries are at the + front of the list, while the old ones are at the back. + numberOfReadings and the setNumberOfReadings control the number of entries + in the list. If a size is set that is smaller than the current size, then + the old ones are chopped off. + + This class now has a couple of variables for when it allows + prediction, they're set with setAllowedMSForPrediction and + setAllowedPercentageForPrediction. If either is below 0 than they + are ignored (if both are below 0 it means any prediction is + allowed, which would be bad). Previous there was no MS limit, and + the percentage limit was 50 (and so that is what the default is + now). +**/ +class ArInterpolation +{ +public: + /// Constructor + AREXPORT ArInterpolation(size_t numberOfReadings = 100); + /// Destructor + AREXPORT virtual ~ArInterpolation(); + /// Adds a new reading + AREXPORT bool addReading(ArTime timeOfReading, ArPose position); + /// Finds a position + AREXPORT int getPose(ArTime timeStamp, ArPose *position, + ArPoseWithTime *lastData = NULL); + /// Sets the name + AREXPORT void setName(const char *name); + /// Gets the name + AREXPORT const char *getName(void); + /// Sets the allowed milliseconds for prediction + AREXPORT void setAllowedMSForPrediction(int ms = -1); + /// Sets the allowed milliseconds for prediction + AREXPORT int getAllowedMSForPrediction(void); + /// Sets the allowed percentage for prediction + AREXPORT void setAllowedPercentageForPrediction(int percentage = 5000); + /// Sets the allowed milliseconds for prediction + AREXPORT int getAllowedPercentageForPrediction(void); + /// Sets if we should log events for this interpolation + AREXPORT void setLogPrediction(bool logPrediction = false); + /// Gets if we should log events for this interpolation + AREXPORT bool getLogPrediction(void); + /// Sets the number of readings this instance holds back in time + AREXPORT void setNumberOfReadings(size_t numberOfReadings); + /// Gets the number of readings this instance holds back in time + AREXPORT size_t getNumberOfReadings(void) const; + /// Empties the interpolated positions + AREXPORT void reset(void); +protected: + ArMutex myDataMutex; + std::string myName; + std::list myTimes; + std::list myPoses; + size_t mySize; + bool myLogPrediction; + int myAllowedMSForPrediction; + int myAllowedPercentageForPrediction; +}; + +#endif diff --git a/Legacy/Aria/include/ArIrrfDevice.h b/Legacy/Aria/include/ArIrrfDevice.h new file mode 100644 index 0000000..f98224d --- /dev/null +++ b/Legacy/Aria/include/ArIrrfDevice.h @@ -0,0 +1,74 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ + +#ifndef ARIRRFDEVICE_H +#define ARIRRFDEVICE_H + +#include "ariaTypedefs.h" +#include "ArRangeDevice.h" +#include "ArFunctor.h" + +#include "ArRobot.h" + +/// A class for connecting to a PB-9 and managing the resulting data +/** + This class is for use with a PB9 IR rangefinder. It has the packethandler + necessary to process the packets, and will put the data into ArRangeBuffers + for use with obstacle avoidance, etc. + + The PB9 is still under development, and only works on an H8 controller + running AROS. +*/ + +class ArIrrfDevice : public ArRangeDevice +{ +public: + /// Constructor + AREXPORT ArIrrfDevice(size_t currentBufferSize = 91, + size_t cumulativeBufferSize = 273, + const char * name = "irrf"); + /// Destructor + AREXPORT virtual ~ArIrrfDevice(); + + /// The packet handler for use when connecting to an H8 micro-controller + AREXPORT bool packetHandler(ArRobotPacket *packet); + + /// Maximum range for a reading to be added to the cumulative buffer (mm) + AREXPORT void setCumulativeMaxRange(double r) { myCumulativeMaxRange = r; } + AREXPORT virtual void setRobot(ArRobot *); + +protected: + ArRetFunctor1C myPacketHandler; + ArTime myLastReading; + AREXPORT void processReadings(void); + double myCumulativeMaxRange; + double myFilterNearDist; + double myFilterFarDist; + std::map myIrrfReadings; +}; + + +#endif // ARIRRFDEVICE_H diff --git a/Legacy/Aria/include/ArJoyHandler.h b/Legacy/Aria/include/ArJoyHandler.h new file mode 100644 index 0000000..7e1ecf0 --- /dev/null +++ b/Legacy/Aria/include/ArJoyHandler.h @@ -0,0 +1,166 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARJOYHANDLER_H +#define ARJOYHANDLER_H + +#include "ariaTypedefs.h" +#include "ariaUtil.h" + +#ifdef WIN32 +#include // for JOYINFO +#else // if not win32 +#include +#include +#include +#include +#include +#endif +#ifdef linux +#include // for JS_DATA_TYPE +#endif + + + +/// Interfaces to a computer joystick +/** + This class is used to read data from a joystick device attached to the computer + (usually via USB). + The joystick handler keeps track of the minimum and maximums for both + axes, updating them to constantly be better calibrated. The speeds set + with setSpeed() influence what is returned by getAdjusted() or getDoubles(). + + The joystick device is not opened until init() is called. If there was + an error connecting to the joystick device, it will return false, and + haveJoystick() will return false. After calling + init(), use getAdjusted() or getDoubles() + to get values, and getButton() to check whether a button is pressed. setSpeed() may be + called at any time to configure or reconfigure the range of the values returned by + getAdjusted() and getDoubles(). + + To get the raw data instead, use getUnfiltered() or getAxis(). + + For example, if you want the X axis output to range from -1000 to 1000, and the Y axis + output to range from -100 to 100, call setSpeed(1000, 100);. + + The X joystick axis is usually the left-right axis, and Y is forward-back. + If a joystick has a Z axis, it is usually a "throttle" slider or dial on the + joystick. The usual way to + drive a robot with a joystick is to use the X joystick axis for rotational velocity, + and Y for translational velocity (note the robot coordinate system, this is its local + X axis), and use the Z axis to adjust the robot's maximum driving speed. + + @ingroup OptionalClasses +*/ +class ArJoyHandler +{ + public: + /// Constructor + AREXPORT ArJoyHandler(bool useOSCal = true, bool useOldJoystick = false); + /// Destructor + AREXPORT ~ArJoyHandler(); + /// Intializes the joystick, returns true if successful + AREXPORT bool init(void); + /// Returns if the joystick was successfully initialized or not + bool haveJoystick(void) { return myInitialized; } + /// Gets the adjusted reading, as floats, between -1.0 and 1.0 + AREXPORT void getDoubles(double *x, double *y, double *z = NULL); + /// Gets the button + AREXPORT bool getButton(unsigned int button); + /// Returns true if we definitely have a Z axis (we don't know in windows unless it moves) + bool haveZAxis(void) { return myHaveZ; } + + /// Sets the maximums for the x, y and optionally, z axes. + void setSpeeds(int x, int y, int z = 0) + { myTopX = x; myTopY = y; myTopZ = z; } + /// Gets the adjusted reading, as integers, based on the setSpeed + AREXPORT void getAdjusted(int *x, int *y, int *z = NULL); + + /// Gets the number of axes the joystick has + AREXPORT unsigned int getNumAxes(void); + /// Gets the floating (-1 to 1) location of the given joystick axis + AREXPORT double getAxis(unsigned int axis); + /// Gets the number of buttons the joystick has + AREXPORT unsigned int getNumButtons(void); + + /// Sets whether to just use OS calibration or not + AREXPORT void setUseOSCal(bool useOSCal); + /// Gets whether to just use OS calibration or not + AREXPORT bool getUseOSCal(void); + /// Starts the calibration process + AREXPORT void startCal(void); + /// Ends the calibration process + AREXPORT void endCal(void); + /// Gets the unfilitered reading, mostly for internal use, maybe + /// useful for Calibration + AREXPORT void getUnfiltered(int *x, int *y, int *z = NULL); + /// Gets the stats for the joystick, useful after calibrating to save values + AREXPORT void getStats(int *maxX, int *minX, int *maxY, int *minY, + int *cenX, int *cenY); + /// Sets the stats for the joystick, useful for restoring calibrated settings + AREXPORT void setStats(int maxX, int minX, int maxY, int minY, + int cenX, int cenY); + /// Gets the maximums for each axis. + AREXPORT void getSpeeds(int *x, int *y, int *z); + + protected: + // function to get the data for OS dependent part + void getData(void); + int myMaxX, myMinX, myMaxY, myMinY, myCenX, myCenY, myTopX, myTopY, myTopZ; + bool myHaveZ; + + std::map myAxes; + std::map myButtons; + + int myPhysMax; + bool myInitialized; + bool myUseOSCal; + bool myUseOld; + bool myFirstData; + ArTime myLastDataGathered; +#ifdef WIN32 + unsigned int myJoyID; + int myLastZ; + JOYINFO myJoyInfo; + JOYCAPS myJoyCaps; +#else // if not win32 + int myJoyNumber; + char myJoyNameTemp[512]; + ArTime myLastOpenTry; + void getOldData(void); + void getNewData(void); + #ifdef linux + struct JS_DATA_TYPE myJoyData; // structure for the buttons and x,y coords + #else + int myJoyData; + #endif + FILE * myOldJoyDesc; + int myJoyDesc; +#endif // linux +}; + + +#endif // ARJOYHANDLER_H + diff --git a/Legacy/Aria/include/ArKeyHandler.h b/Legacy/Aria/include/ArKeyHandler.h new file mode 100644 index 0000000..722b30a --- /dev/null +++ b/Legacy/Aria/include/ArKeyHandler.h @@ -0,0 +1,154 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARKEYHANDLER_H +#define ARKEYHANDLER_H + +#include "ariaTypedefs.h" +#include "ArFunctor.h" +#include +#include + +#ifndef WIN32 +#include +#include +#endif + + +/// Perform actions when keyboard keys are pressed +/** + This class is used for handling input from the keyboard. + Use addKeyHandler() to associate a functor with a keyboard key. + ArKeyHandler will call that functor when the key is pressed. + + You should also register the keyhandler with Aria::setKeyHandler(), + and before you create a key handler you should see if one is + already there with Aria::getKeyHandler(). Only one key handler + can be created in a program, and this lets independent parts + of a program use the same key handler. + + You can attach a key handler to a robot with + ArRobot::attachKeyHandler() which will put a task into the robots + list of tasks to check for new keyboard input in each cycle, and which + will also add a handler to end the robot's task cycle when Escape is pressed + (you can override this by replacing it with your own handler). + If you have mulitple ArRobot objects, only create one key handler and attach + it to one robot. + + Alternatively, you can call checkKeys() periodically to check for new key input. + + @ingroup OptionalClasses +**/ + +class ArKeyHandler +{ +public: + /// This object will take over key capture when constructed, and release + /// key capture when destroyed. + AREXPORT ArKeyHandler(bool blocking = false, bool addAriaExitCB = true, + FILE *stream = NULL, + bool takeKeysInConstructor = true); + + /// Destructor. Reseases control of the keyboard and restores state before + /// this key handler was created. + AREXPORT ~ArKeyHandler(); + + /// These are symbols for the non-ascii keys + enum KEY { + UP = 256, ///< Up arrow (keypad or 4 key dirs) + DOWN, ///< Down arrow (keypad or 4 key dirs) + LEFT, ///< Left arrow (keypad or 4 key dirs) + RIGHT, ///< Right arrow (keypad or 4 key dirs) + ESCAPE, ///< Escape key + SPACE, ///< Space key + TAB, ///< Tab key + ENTER, ///< Enter key + BACKSPACE, ///< Backspace key + _StartFKeys, ///< F key offset (internal; don't use). + F1, ///< F1 + F2, ///< F2 + F3, ///< F3 + F4, ///< F4 + F5, ///< F5 (not supported on Windows yet) + F6, ///< F6 (not supported on Windows yet) + F7, ///< F7 (not supported on Windows yet) + F8, ///< F8 (not supported on Windows yet) + F9, ///< F9 (not supported on Windows yet) + F10, ///< F10 (not supported on Windows yet) + F11, ///< F11 (not supported on Windows yet) + F12, ///< F12 (not supported on Windows yet) + _EndFKeys, ///< F key range (internal; don't use) + PAGEUP, ///< Page Up (not supported on Windows yet) + PAGEDOWN, ///< Page Down (not supported on Windows yet) + HOME, ///< Home key (not supported on Windows yet) + END, ///< End key (not supported on Windows yet) + INSERT, ///< Insert key (not supported on Windows yet) + DEL ///< Special delete key (often forward-delete) (not supported on Windows yet) + }; + + /// This adds a keyhandler, when the keyToHandle is hit, functor will fire + AREXPORT bool addKeyHandler(int keyToHandle, ArFunctor *functor); + + /// This removes a key handler, by key + AREXPORT bool remKeyHandler(int keyToHandler); + /// This removes a key handler, by key + AREXPORT bool remKeyHandler(ArFunctor *functor); + + /// Takes the key control over. For internal or special use, since it's + /// called in the constructor. + AREXPORT void takeKeys(bool blocking = false); + + /// Sets stdin back to its original settings, if its been restored + /// it won't read anymore. For internal or special use, since it's + /// called in the destructor. + AREXPORT void restore(void); + + /// intnernal, use addKeyHandler, Checks for keys and handles them + AREXPORT void checkKeys(void); + + /// internal, use addKeyHandler instead... Gets a key from the stdin if ones + /// available, -1 if there aren't any available + AREXPORT int getKey(void); + +protected: +#ifndef WIN32 + int getChar(void); +#endif + + std::map myMap; + bool myBlocking; + + bool myRestored; + ArFunctorC myAriaExitCB; +#ifndef WIN32 + struct termios myOriginalTermios; +#endif + + FILE *myStream; + bool myTookKeys; +}; + + +#endif // ARKEYHANDLER_H diff --git a/Legacy/Aria/include/ArLCDConnector.h b/Legacy/Aria/include/ArLCDConnector.h new file mode 100644 index 0000000..c6408f5 --- /dev/null +++ b/Legacy/Aria/include/ArLCDConnector.h @@ -0,0 +1,226 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARLCDCONNECTOR_H +#define ARLCDCONNECTOR_H + +#include "ariaTypedefs.h" +#include "ArSerialConnection.h" +#include "ArTcpConnection.h" +#include "ArArgumentBuilder.h" +#include "ArArgumentParser.h" +#include "ariaUtil.h" +#include "ArRobotConnector.h" + +class ArLCDMTX; +class ArRobot; + + + +/// Connect to robot and lcd based on run-time availablitily and command-line arguments +/** + + ArLCDConnector makes a lcd connection either through a serial port + connection, or through a TCP + port (for the simulator or for robots with Ethernet-serial bridge + devices instead of onboard computers). + Normally, it first attempts a TCP connection on + @a localhost port 8101, to use a simulator if running. If the simulator + is not running, then it normally then connects using the serial port + Various connection + parameters are configurable through command-line arguments or in the robot + parameter file. (Though the internal interface used by ARIA to do this is also + available if you need to use it: See addLCD(); otherwise don't use + addLCD(), setupLCD(), etc.). + + When you create your ArLCDConnector, pass it command line parameters via + either the argc and argv variables from main(), or pass it an + ArArgumentBuilder or ArArgumentParser object. (ArArgumentBuilder + is able to obtain command line parameters from a Windows program + that uses WinMain() instead of main()). + ArLCDConnector registers a callback with the global Aria class. Use + Aria::parseArgs() to parse all command line parameters to the program, and + Aria::logOptions() to print out information about all registered command-line parameters. + + The following command-line arguments are checked: + @verbinclude ArLCDConnector_options + + To connect to any lcds that were set up in the robot parameter file or + via command line arguments, call connectLCDs(). If successful, + connectLCDs() will return true and add an entry for each lcd connected + in the ArRobot object's list of lcds. These ArLCDMTX objects can be + accessed from your ArRobot object via ArRobot::findLCD() or ArRobot::getLCDMap(). + + + @since 2.8.0 + + **/ +class ArLCDConnector +{ +public: + /// Constructor that takes argument parser + AREXPORT ArLCDConnector( + ArArgumentParser *parser, + ArRobot *robot, ArRobotConnector *robotConnector, + bool autoParseArgs = true, + ArLog::LogLevel infoLogLevel = ArLog::Verbose, + ArRetFunctor1 *turnOnPowerOutputCB = NULL, + ArRetFunctor1 *turnOffPowerOutputCB = NULL); + /// Destructor + AREXPORT ~ArLCDConnector(void); + /// Connects all the lcds the robot has that should be auto connected + AREXPORT bool connectLCDs(bool continueOnFailedConnect = false, + bool addConnectedLCDsToRobot = true, + bool addAllLCDsToRobot = false, + bool turnOnLCDs = true, + bool powerCycleLCDOnFailedConnect = true); + /// Sets up a lcd to be connected + AREXPORT bool setupLCD(ArLCDMTX *lcd, + int lcdNumber = 1); + /// Connects the lcd synchronously (will take up to a minute) + AREXPORT bool connectLCD(ArLCDMTX *lcd, + int lcdNumber = 1, + bool forceConnection = true); + /// Adds a lcd so parsing will get it + AREXPORT bool addLCD(ArLCDMTX *lcd, + int lcdNumber = 1); + /// Function to parse the arguments given in the constructor + AREXPORT bool parseArgs(void); + /// Function to parse the arguments given in an arbitrary parser + AREXPORT bool parseArgs(ArArgumentParser *parser); + /// Log the options the simple connector has + AREXPORT void logOptions(void) const; + /// Internal function to get the lcd (only useful between parseArgs and connectLCDs) + AREXPORT ArLCDMTX *getLCD(int lcdNumber); + + /// Internal function to replace the lcd (only useful between parseArgs and connectLCDs) but not the lcd data + AREXPORT bool replaceLCD(ArLCDMTX *lcd, int lcdNumber); + + AREXPORT void turnOnPowerCB (int); + AREXPORT void turnOffPowerCB (int); + + AREXPORT void setIdentifier(const char *identifier); + +protected: +/// Class that holds information about the lcd data +class LCDData +{ + public: + LCDData (int number, ArLCDMTX *lcd) { + myNumber = number; + myLCD = lcd; + myConn = NULL; + myConnect = false; myConnectReallySet = false; + myPort = NULL; + myPortType = NULL; + myType = NULL; + myRemoteTcpPort = 0; myRemoteTcpPortReallySet = false; + myBaud = NULL; + myAutoConn = NULL; + myConnFailOption = NULL; + } + virtual ~LCDData() {} + /// The number of this lcd + int myNumber; + /// The actual pointer to this lcd + ArLCDMTX *myLCD; + // our connection + ArDeviceConnection *myConn; + // if we want to connect the lcd + bool myConnect; + // if myConnect was really set + bool myConnectReallySet; + // the port we want to connect the lcd on + const char *myPort; + // the type of port we want to connect to the lcd on + const char *myPortType; + // lcd Type + const char *myType; + // wheather to auto conn + const char *myAutoConn; + // wheather to disconnect on conn faiure + const char *myConnFailOption; + // lcd tcp port if we're doing a remote host + int myRemoteTcpPort; + // if our remote lcd tcp port was really set + bool myRemoteTcpPortReallySet; + /// the baud we want to use + const char *myBaud; +}; + + std::map myLCDs; + + /// Turns on the power for the specific board in the firmware + AREXPORT bool turnOnPower(LCDData *LCDData); + + /// Turns off the power for the specific board in the firmware + AREXPORT bool turnOffPower(LCDData *LCDData); + + /// Verifies the firmware version on the LCD and loads new firmware + /// if there is no match + AREXPORT bool verifyFirmware(LCDData *LCDData); + + AREXPORT std::string searchForFile( + const char *dirToLookIn, const char *prefix, const char *suffix); + + + /// Parses the lcd arguments + AREXPORT bool parseLCDArgs(ArArgumentParser *parser, + LCDData *lcdData); + /// Logs the lcd command line option help text. + AREXPORT void logLCDOptions(LCDData *lcddata, bool header = true, bool metaOpts = true) const; + // Sets the lcd parameters + bool internalConfigureLCD(LCDData *lcdData); + + std::string myLCDTypes; + + // our parser + ArArgumentParser *myParser; + bool myOwnParser; + // if we should autoparse args or toss errors + bool myAutoParseArgs; + bool myParsedArgs; + + ArRobot *myRobot; + ArRobotConnector *myRobotConnector; + + // variables to hold if we're logging or not + bool myLCDLogPacketsReceived; + bool myLCDLogPacketsSent; + + ArLog::LogLevel myInfoLogLevel; + + ArRetFunctor1 *myTurnOnPowerOutputCB; + ArRetFunctor1 *myTurnOffPowerOutputCB; + + ArRetFunctorC myParseArgsCB; + ArConstFunctorC myLogOptionsCB; + + ArFunctor1C myTurnOnPowerCB; + ArFunctor1C myTurnOffPowerCB; + +}; + +#endif // ARLASERCONNECTOR_H diff --git a/Legacy/Aria/include/ArLCDMTX.h b/Legacy/Aria/include/ArLCDMTX.h new file mode 100644 index 0000000..9824beb --- /dev/null +++ b/Legacy/Aria/include/ArLCDMTX.h @@ -0,0 +1,373 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARLCDMTX_H +#define ARLCDMTX_H + +#include "ariaTypedefs.h" +#include "ArRangeDevice.h" +#include "ArFunctor.h" +#include "ArRobot.h" +#include "ArRobotPacket.h" +#include "ArRobotConnector.h" + + + +// Packets are in the format of +// 2 bytes header (0xfa 0xba) +// 1 byte length +// 1 byte command +// xx bytes command specific / args +// 2 bytes checksum +// + +/** Interface to LCD interface panel on an MTX-type robot. + + This interface can be used to display text strings on the MTX LCD panel. + One or more ArLCDMTX objects are automatically created by + ArRobotConnector (or ArLCDConnector if used separately from + ArRobotConnector) if connecting to an MTX robot, and a successful + connection to the LCD panel was also made. A pointer + to the first ArLCDMTX object can be obtained via ArRobot::findLCD(), + passing an index of 1. + + @since 2.8.0 + @ingroup MTX +*/ +class ArLCDMTX : public ArASyncTask +{ +public: + /// Constructor + AREXPORT ArLCDMTX( + int lcdBoardNum = 0, + const char * name = "MTXLCD", + ArDeviceConnection *conn = NULL, + ArRobot *robot = NULL); + /// Destructor + AREXPORT virtual ~ArLCDMTX(); + + // Grabs the new readings from the robot and adds them to the buffers + // (Primarily for internal use.) + //AREXPORT void processReadings(void); + + AREXPORT int getBoardNum(void) + { return myBoardNum; } + + /// Sets the robot pointer, also attaches its process function to the + /// robot as a Sensor Interpretation task. + AREXPORT virtual void setRobot(ArRobot *robot); + + /// Sets the device this instance receives packets from + AREXPORT void setDeviceConnection(ArDeviceConnection *conn); + /// Gets the device this instance receives packets from + AREXPORT ArDeviceConnection *getDeviceConnection(void); + + AREXPORT virtual bool blockingConnect(bool sendTracking, bool recvTracking, + int lcdNumber, ArFunctor1 *onCallback, + ArFunctor1 *offCallback); + AREXPORT virtual bool disconnect(void); + AREXPORT virtual bool isConnected(void) { return myIsConnected; } + AREXPORT virtual bool isTryingToConnect(void) + { + if (myStartConnect) + return true; + else if (myTryingToConnect) + return true; + else + return false; + } + + + /// Lock this device + AREXPORT virtual int lockDevice() { return(myDeviceMutex.lock());} + /// Try to lock this device + AREXPORT virtual int tryLockDevice() {return(myDeviceMutex.tryLock());} + /// Unlock this device + AREXPORT virtual int unlockDevice() {return(myDeviceMutex.unlock());} + + AREXPORT virtual const char *getName(void) const; + + AREXPORT void setInfoLogLevel(ArLog::LogLevel infoLogLevel) + { myInfoLogLevel = infoLogLevel; } + + /// Gets the default port type for the lcd + const char *getDefaultPortType(void) { return myDefaultPortType.c_str(); } + + /// Gets the default port type for the lcd + const char *getDefaultTcpPort(void) { return myDefaultTcpPort.c_str(); } + + AREXPORT bool verifyFwVersion(); + + + /// Sets the numter of seconds without a response until connection assumed lost + AREXPORT virtual void setConnectionTimeoutSeconds(double seconds) + { ArLog::log(ArLog::Normal, + "%s::setConnectionTimeoutSeconds: Setting timeout to %g secs", + getName(), seconds); + myTimeoutSeconds = seconds; } + /// Gets the number of seconds without a response until connection assumed lost + AREXPORT virtual double getConnectionTimeoutSeconds(void) + {return myTimeoutSeconds; } + /// check for lost connections + AREXPORT bool checkLostConnection(void); + /// disconnect + AREXPORT void disconnectOnError(void); + /// Gets the time data was last receieved + ArTime getLastReadingTime(void) { return myLastReading; } + /// Gets the number of lcd readings received in the last second + AREXPORT int getReadingCount(void); + // Function called in sensorInterp to indicate that a + // reading was received + + /// Adds a callback for when disconnection happens because of an error + void addDisconnectOnErrorCB(ArFunctor *functor, + int position = 51) + { myDisconnectOnErrorCBList.addCallback(functor, position); } + + /// Removes a callback for when disconnection happens because of an error + void remDisconnectOnErrorCB(ArFunctor *functor) + { myDisconnectOnErrorCBList.remCallback(functor); } + + const char *getFirmwareVersion(void) const + { return myFirmwareVersion.c_str(); } + + + /// exposed routines to set the various screen status(s) text + /// size is limited to 247 characters... supports new lines (it + /// can show up to 6 lines, with roughly 22-26 chars per line) + + AREXPORT bool setMTXLCDMainScreenText(const char *status); + // we just have one text on the status now + //AREXPORT bool setMTXLCDMainScreenMode(const char *status); + AREXPORT bool setMTXLCDBootScreenText(const char *status); + + // get routines + enum Screens { + BOOT_SCREEN=0x00, + STATUS_SCREEN=0x01 + }; + + // only 2 valid screen numbers + AREXPORT bool setMTXLCDScreenNumber(unsigned char screenNumber); + + // sets backlight on/off + AREXPORT bool setMTXLCDBackLight(bool backLight); + + void setIdentifier(const char *identifier); + + /// internal call (don't use it) that updates from the calling thread instead of the correct thread + AREXPORT bool internalMTXLCDOverrideMainScreenText(const char *status); + /// internal call (don't use it) that updates from the calling thread instead of the correct thread + AREXPORT bool internalMTXLCDOverrideBootScreenText(const char *status); + /// internal call (don't use it) that updates from the calling thread instead of the correct thread + AREXPORT bool internalMTXLCDOverrideBacklight(bool backlight); +protected: + + /// Logs the information about the sensor + AREXPORT void log(void); + + AREXPORT void writeToLCD(); + + AREXPORT bool setMainStatus(const char *status); + AREXPORT bool setTextStatus(const char *status); + AREXPORT bool setRobotIdStatus(const char *status); + AREXPORT bool setRobotIPStatus(const char *status); + AREXPORT bool setBootStatus(const char *status); + AREXPORT bool getMainStatus(const char *status); + AREXPORT bool getTextStatus(const char *status); + AREXPORT bool getBootStatus(const char *status); + + + AREXPORT bool sendKeepAlive(); + AREXPORT bool sendVersion(); + AREXPORT bool sendSystemInfo(unsigned char command); + AREXPORT bool sendReboot(); + + AREXPORT bool getScreenNumber(unsigned char *currentScreenNumber); + + AREXPORT bool getTextField(unsigned char textNumber, char *text); + AREXPORT bool getBacklight(unsigned char *backlight); + AREXPORT bool getSystemMeters(unsigned char *battery, unsigned char *wifi); + + + // set routines + AREXPORT bool setTextField(unsigned char textNumber, const char *text); + AREXPORT bool setBacklight(bool backlight); + AREXPORT bool setSystemMeters(unsigned char battery, unsigned char wifi); + AREXPORT bool setScreenNumber(unsigned char screenNumber); + + AREXPORT unsigned char getBatteryPercentage(); + AREXPORT unsigned char getWifiPercentage(); + + AREXPORT void getIpAddress(); + + + AREXPORT virtual void internalGotReading(void); + + ArDeviceConnection *myConn; + std::string myName; + std::string myDefaultPortType; + std::string myDefaultTcpPort; + + double myTimeoutSeconds; + bool myRobotRunningAndConnected; + bool myConnFailOption; + + ArTime myLastReading; + + // packet count + time_t myTimeLastReading; + int myReadingCurrentCount; + int myReadingCount; + + ArCallbackList myDisconnectOnErrorCBList; + + ArRobot *myRobot; + ArFunctorC myProcessCB; + + AREXPORT virtual void lcdSetName(const char *name); + AREXPORT virtual void * runThread(void *arg); + + AREXPORT bool downloadFirmware(); + AREXPORT std::string searchForFile( + const char *dirToLookIn, const char *prefix, const char *suffix); + + + void sensorInterp(void); + void failedToConnect(void); + void clear(void); + bool myIsConnected; + bool myTryingToConnect; + bool myStartConnect; + + std::string myRobotIdentifier; + bool myRobotIdentifierChanged; + + bool myOnCharger; + ArRobot::ChargeState myChargeState; + + int myBoardNum; + unsigned char myVersion; + + ArLog::LogLevel myLogLevel; + +enum Headers { + HEADER1=0xfa, + HEADER2=0xcd + +// old value HEADER2=0x5c + }; + + ArRobotPacketReceiver *myReceiver; + ArRobotPacketSender *mySender; + + ArMutex myPacketsMutex; + ArMutex myDataMutex; + ArMutex myDeviceMutex; + + ArLog::LogLevel myInfoLogLevel; + + std::list myPackets; + + ArTime myPrevLCDIntTime; + + bool myRequestedSysInfoLCDPackets; + bool myRequestedCellInfoLCDPackets; + + bool mySendTracking; + bool myRecvTracking; + +// Protocol Commands + + +enum Commands { + KEEP_ALIVE=0x00, + VERSION=0x01, + SYSTEM_INFO=0x02, + REBOOT=0x03, + GET_CURRENT_SCREEN_NUM=0x10, + GET_TEXT_FIELD=0x11, + GET_BACKLIGHT=0x12, + GET_SYSTEM_METERS=0x13, + SET_SCREEN_NUM=0x20, + SET_TEXT_FIELD=0x21, + SET_BACKLIGHT=0x22, + SET_BATTERY_WIFI=0x23 + }; + + + +enum TextNumbers { + BOOT_STATUS_TEXT=0x00, + MAIN_STATUS_TEXT=0x01, + MODE_TEXT=0x02, + ROBOT_ID_TEXT=0x03, + ROBOT_IP_TEXT=0x04 + }; + + +enum SYS_INFO { + SYS_INFO_STOP=0x00, + SYS_INFO_ONCE=0x01, + SYS_INFO_CONTINUOUS=0x02 + }; + + // System Info + unsigned char myId; + std::string myFirmwareVersion; + unsigned int mySerialNumber; + long long myCurrentTime; + unsigned char myCurrentScreen; + unsigned char myStatusFlags; + + // end system info + + std::string myNewFwFile; + + bool myScreenNumberChanged; + unsigned char myChangedScreenNumber; + + bool myBootTextChanged; + char myChangedBootText[248]; + + bool myMainScreenStatusChanged; + char myChangedStatusText[248]; + + bool myMainScreenModeChanged; + char myChangedModeText[248]; + + bool myBackLightChanged; + bool myChangedBackLight; + + std::string myIpAddress; + + ArFunctorC mySensorInterpTask; + ArRetFunctorC myAriaExitCB; + +}; + + + +#endif // ARLCDMTX_H diff --git a/Legacy/Aria/include/ArLMS1XX.h b/Legacy/Aria/include/ArLMS1XX.h new file mode 100644 index 0000000..379fec3 --- /dev/null +++ b/Legacy/Aria/include/ArLMS1XX.h @@ -0,0 +1,256 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARLMS1XX_H +#define ARLMS1XX_H + +#include "ariaTypedefs.h" +#include "ArRobotPacket.h" +#include "ArLaser.h" +#include "ArFunctor.h" + +/** @internal */ +class ArLMS1XXPacket : public ArBasePacket +{ +public: + /// Constructor + AREXPORT ArLMS1XXPacket(); + /// Destructor + AREXPORT virtual ~ArLMS1XXPacket(); + + /// Gets the command type + AREXPORT const char *getCommandType(void); + /// Gets the command name + AREXPORT const char *getCommandName(void); + + // only call finalizePacket before a send + AREXPORT virtual void finalizePacket(void); + AREXPORT virtual void resetRead(void); + + /// Gets the time the packet was received at + AREXPORT ArTime getTimeReceived(void); + /// Sets the time the packet was received at + AREXPORT void setTimeReceived(ArTime timeReceived); + + AREXPORT virtual void duplicatePacket(ArLMS1XXPacket *packet); + AREXPORT virtual void empty(void); + + AREXPORT virtual void byteToBuf(ArTypes::Byte val); + AREXPORT virtual void byte2ToBuf(ArTypes::Byte2 val); + AREXPORT virtual void byte4ToBuf(ArTypes::Byte4 val); + AREXPORT virtual void uByteToBuf(ArTypes::UByte val); + AREXPORT virtual void uByte2ToBuf(ArTypes::UByte2 val); + AREXPORT virtual void uByte4ToBuf(ArTypes::UByte4 val); + AREXPORT virtual void strToBuf(const char *str); + + AREXPORT virtual ArTypes::Byte bufToByte(void); + AREXPORT virtual ArTypes::Byte2 bufToByte2(void); + AREXPORT virtual ArTypes::Byte4 bufToByte4(void); + AREXPORT virtual ArTypes::UByte bufToUByte(void); + AREXPORT virtual ArTypes::UByte2 bufToUByte2(void); + AREXPORT virtual ArTypes::UByte4 bufToUByte4(void); + AREXPORT virtual void bufToStr(char *buf, int len); + + // adds a raw char to the buf + AREXPORT virtual void rawCharToBuf(unsigned char c); +protected: + int deascii(char c); + + ArTime myTimeReceived; + bool myFirstAdd; + + char myCommandType[1024]; + char myCommandName[1024]; +}; + + +/// Given a device connection it receives packets from the sick through it +/// @internal +class ArLMS1XXPacketReceiver +{ +public: + /// Constructor with assignment of a device connection + AREXPORT ArLMS1XXPacketReceiver(); + /// Destructor + AREXPORT virtual ~ArLMS1XXPacketReceiver(); + + /// Receives a packet from the robot if there is one available + AREXPORT ArLMS1XXPacket *receivePacket(unsigned int msWait = 0, + bool shortcut = false, + bool ignoreRemainders = false); + + AREXPORT ArLMS1XXPacket *receiveTiMPacket(unsigned int msWait = 0, + bool shortcut = false, + bool ignoreRemainders = false); + + /// Sets the device this instance receives packets from + AREXPORT void setDeviceConnection(ArDeviceConnection *conn); + /// Gets the device this instance receives packets from + AREXPORT ArDeviceConnection *getDeviceConnection(void); + + // PS - added to pass info to this class + AREXPORT void setmyInfoLogLevel(ArLog::LogLevel infoLogLevel) + { myInfoLogLevel = infoLogLevel; } + AREXPORT void setLaserModel(int laserModel) + { myLaserModel = laserModel; } + AREXPORT void setmyName(const char *name ) + { strcpy(myName, name); } + AREXPORT void setReadTimeout(int timeout ) + { myReadTimeout = timeout; } + + +protected: + ArDeviceConnection *myConn; + ArLMS1XXPacket myPacket; + + enum State + { + STARTING, ///< Looking for beginning + DATA, ///< Read the data in a big whack + REMAINDER ///< Have extra data from reading in data + }; + State myState; + char myName[1024]; + unsigned int myNameLength; + char myReadBuf[100000]; + int myReadCount; + int myReadTimeout; + + int myLaserModel; + + ArLog::LogLevel myInfoLogLevel; +}; + +/** + @since Aria 2.7.2 + @see ArLaserConnector + Use ArLaserConnector to connect to a laser, determining type based on robot and program configuration parameters. + + This is the ArLaser implementation for SICK LMS1xx, LMS5xx, and TiM3xx lasers. To use these lasers with ArLaserConnector, specify + the appropriate type in program configuration (lms1xx, lms6xx, or tim3xx). +*/ +class ArLMS1XX : public ArLaser +{ +public: + + enum LaserModel + { + LMS1XX, + LMS5XX, + TiM3XX + }; + + /// Constructor + AREXPORT ArLMS1XX(int laserNumber, + const char *name, + LaserModel laserModel); + + /// Destructor + AREXPORT ~ArLMS1XX(); + AREXPORT virtual bool blockingConnect(void); + + // specific init routine per laser + AREXPORT virtual bool lms5xxConnect(void); + AREXPORT virtual bool lms1xxConnect(void); + AREXPORT virtual bool tim3xxConnect(void); + + AREXPORT virtual bool asyncConnect(void); + AREXPORT virtual bool disconnect(void); + AREXPORT virtual bool isConnected(void) { return myIsConnected; } + AREXPORT virtual bool isTryingToConnect(void) + { + if (myStartConnect) + return true; + else if (myTryingToConnect) + return true; + else + return false; + } + + /// Logs the information about the sensor + AREXPORT void log(void); + + +protected: + AREXPORT virtual void laserSetName(const char *name); + AREXPORT virtual void * runThread(void *arg); + AREXPORT virtual void setRobot(ArRobot *robot); + AREXPORT ArLMS1XXPacket *sendAndRecv( + ArTime timeout, ArLMS1XXPacket *sendPacket, const char *recvName); + void sensorInterp(void); + void failedToConnect(void); + void clear(void); + bool validateCheckSum(ArLMS1XXPacket *packet); + + LaserModel myLaserModel; + //bool myIsLMS5XX; + + bool myIsConnected; + bool myTryingToConnect; + bool myStartConnect; + int myScanFreq; + + int myVersionNumber; + int myDeviceNumber; + int mySerialNumber; + int myDeviceStatus1; + int myDeviceStatus2; + int myMessageCounter; + int myScanCounter; + int myPowerUpDuration; + int myTransmissionDuration; + int myInputStatus1; + int myInputStatus2; + int myOutputStatus1; + int myOutputStatus2; + int myReserved; + int myScanningFreq; + int myMeasurementFreq; + int myNumberEncoders; + int myNumChans16Bit; + int myNumChans8Bit; + int myFirstReadings; + int myYear; + int myMonth; + int myMonthDay; + int myHour; + int myMinute; + int mySecond; + int myUSec; + + ArLog::LogLevel myLogLevel; + + ArLMS1XXPacketReceiver myReceiver; + + ArMutex myPacketsMutex; + ArMutex myDataMutex; + + std::list myPackets; + + ArFunctorC mySensorInterpTask; + ArRetFunctorC myAriaExitCB; +}; + +#endif diff --git a/Legacy/Aria/include/ArLMS2xx.h b/Legacy/Aria/include/ArLMS2xx.h new file mode 100644 index 0000000..dd62711 --- /dev/null +++ b/Legacy/Aria/include/ArLMS2xx.h @@ -0,0 +1,231 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARLMS2XX_H +#define ARLMS2XX_H + + +#include "ariaTypedefs.h" +#include "ArLMS2xxPacket.h" +#include "ArLMS2xxPacketReceiver.h" +#include "ArRobotPacket.h" +#include "ArLaser.h" +#include "ArFunctor.h" +#include "ArCondition.h" + +/// Interface to a SICK LMS-200 laser range device +/** + * This class processes incoming data from a SICK LMS-200 + * laser rangefinding device in a background thread, and provides + * it through the standard ArRangeDevice API, to be used via ArRobot + * (see ArRobot::addRangeDevice()), used by an ArAction, or used directly. + * + * An ArSick instance must be connected to the laser through a serial port + * (or simulator): the typical procedure is to allow your ArSimpleConnector + * to configure the laser based on the robot connection type and command + * line parameters; then initiate the ArSick background thread; and finally + * connect ArSick to the laser device. + * For example: + * @code + * ArRobot robot; + * ArSick laser; + * ArSimpleConnector connector(...); + * ... + * Setup the simple connector and connect to the robot -- + * see the example programs. + * ... + * connector.setupLaser(&laser); + * laser.runAsync(); + * if(!laser.blockingConnect()) + * { + * // Error... + * ... + * } + * ... + * @endcode + * + * The most important methods in this class are the constructor, runAsync(), + * blockingConnect(), getSensorPosition(), isConnected(), addConnectCB(), + * asyncConnect(), configure(), in addition to the ArRangeDevice interface. + * + * @note The "extra int" on the raw readings returned by + * ArRangeDevice::getRawReadings() is like other laser + * devices and is the reflectance value, if enabled, ranging between 0 and 255. + * + * ArLMS2xx uses the following buffer parameters by default (see ArRangeDevice + * documentation): + *
+ *
MinDistBetweenCurrent
50 mm + *
MaxDistToKeepCumulative
6000 mm + *
MinDistBetweenCumulative
200 mm + *
MaxSecondsToKeepCumulative
30 sec + *
MaxINsertDistCumulative
3000 mm + *
+ * The current buffer is replaced for each new set of readings. + * + * @since 2.7.0 +**/ +class ArLMS2xx : public ArLaser +{ +public: + /// Constructor + AREXPORT ArLMS2xx(int laserNumber, + const char *name = "lms2xx", + bool appendLaserNumberToName = true); + + /// Destructor + AREXPORT virtual ~ArLMS2xx(); + + /// Connect to the laser while blocking + AREXPORT virtual bool blockingConnect(void); + /// Connect to the laser asyncronously + AREXPORT bool asyncConnect(void); + /// Disconnect from the laser + AREXPORT virtual bool disconnect(void); + /// Sees if this is connected to the laser + AREXPORT virtual bool isConnected(void) + { if (myState == STATE_CONNECTED) return true; else return false; } + AREXPORT virtual bool isTryingToConnect(void) + { + if (myState != STATE_CONNECTED && myState != STATE_NONE) + return true; + else if (myStartConnect) + return true; + else + return false; + } + + /// Sets the device connection + AREXPORT virtual void setDeviceConnection(ArDeviceConnection *conn); + + /** The internal function used by the ArRangeDeviceThreaded + * @internal + */ + AREXPORT virtual void * runThread(void *arg); + AREXPORT virtual void setRobot(ArRobot *robot); +protected: + // The packet handler for when connected to the simulator + AREXPORT bool simPacketHandler(ArRobotPacket * packet); + // The function called if the laser isn't running in its own thread and isn't simulated + AREXPORT void sensorInterpCallback(void); + // An internal function for connecting to the sim + AREXPORT bool internalConnectSim(void); + /// An internal function, single loop event to connect to laser + AREXPORT int internalConnectHandler(void); + // The internal function which processes the sickPackets + AREXPORT void processPacket(ArLMS2xxPacket *packet, ArPose pose, + ArPose encoderPose, unsigned int counter, + bool deinterlace, ArPose deinterlaceDelta); + // The internal function that gets does the work + AREXPORT void runOnce(bool lockRobot); + // Internal function, shouldn't be used, drops the conn because of error + AREXPORT void dropConnection(void); + // Internal function, shouldn't be used, denotes the conn failed + AREXPORT void failedConnect(void); + // Internal function, shouldn't be used, does the after conn stuff + AREXPORT void madeConnection(void); + + /// Internal function that gets whether the laser is simulated or not (just for the old ArSick) + AREXPORT bool sickGetIsUsingSim(void); + + /// Internal function that sets whether the laser is simulated or not (just for the old ArSick) + AREXPORT void sickSetIsUsingSim(bool usingSim); + + /// internal function to runOnRobot so that ArSick can do that while this class won't + AREXPORT bool internalRunOnRobot(void); + + /// Finishes getting the unset parameters from the robot then + /// setting some internal variables that need it + bool finishParams(void); + + AREXPORT virtual bool laserCheckParams(void); + + AREXPORT virtual void laserSetName(const char *name); + + enum State { + STATE_NONE, ///< Nothing, haven't tried to connect or anything + STATE_INIT, ///< Initializing the laser + STATE_WAIT_FOR_POWER_ON, ///< Waiting for power on + STATE_CHANGE_BAUD, ///< Change the baud, no confirm here + STATE_CONFIGURE, ///< Send the width and increment to the laser + STATE_WAIT_FOR_CONFIGURE_ACK, ///< Wait for the configuration Ack + STATE_INSTALL_MODE, ///< Switch to install mode + STATE_WAIT_FOR_INSTALL_MODE_ACK, ///< Wait until its switched to install mode + STATE_SET_MODE, ///< Set the mode (mm/cm) and extra field bits + STATE_WAIT_FOR_SET_MODE_ACK, ///< Waiting for set-mode ack + STATE_START_READINGS, ///< Switch to monitoring mode + STATE_WAIT_FOR_START_ACK, ///< Waiting for the switch-mode ack + STATE_CONNECTED ///< We're connected and getting readings + }; + /// Internal function for switching states + AREXPORT void switchState(State state); + State myState; + ArTime myStateStart; + ArFunctorC myRobotConnectCB; + ArRetFunctor1C mySimPacketHandler; + ArFunctorC mySensorInterpCB; + std::list::iterator myIter; + bool myStartConnect; + bool myRunningOnRobot; + + // range buffers to hold current range set and assembling range set + std::list *myAssembleReadings; + std::list *myCurrentReadings; + + bool myProcessImmediately; + bool myInterpolation; + // list of packets, so we can process them from the sensor callback + std::list myPackets; + + // these two are just for the sim packets + unsigned int myWhichReading; + unsigned int myTotalNumReadings; + + // some variables so we don't have to do a tedios if every time + double myOffsetAmount; + double myIncrementAmount; + + // packet stuff + ArLMS2xxPacket myPacket; + bool myUseSim; + + int myNumReflectorBits; + bool myInterlaced; + + // stuff for the sim packet + ArPose mySimPacketStart; + ArTransform mySimPacketTrans; + ArTransform mySimPacketEncoderTrans; + unsigned int mySimPacketCounter; + + // connection + ArLMS2xxPacketReceiver myLMS2xxPacketReceiver; + + ArMutex myStateMutex; + ArRetFunctorC myAriaExitCB; +}; + + +#endif diff --git a/Legacy/Aria/include/ArLMS2xxPacket.h b/Legacy/Aria/include/ArLMS2xxPacket.h new file mode 100644 index 0000000..18d89b9 --- /dev/null +++ b/Legacy/Aria/include/ArLMS2xxPacket.h @@ -0,0 +1,87 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARLMS2XXPACKET_H +#define ARLMS2XXPACKET_H + +#include "ariaTypedefs.h" +#include "ArBasePacket.h" +#include "ariaUtil.h" + +/// Represents the packets sent to the LMS2xx as well as those received from it +/** + This class reimplements some of the buf operations since the robot is + little endian. + + You can just look at the documentation for the ArBasePacket except + for these functions here, setAddress, getAddress, verifyCheckSum, + print, getID, and calcCheckSum. +*/ + +class ArLMS2xxPacket: public ArBasePacket +{ +public: + /// Constructor + AREXPORT ArLMS2xxPacket(unsigned char sendingAddress = 0); + /// Destructor + AREXPORT virtual ~ArLMS2xxPacket(); + + /// Sets the address to send this packet to (only use for sending) + AREXPORT void setSendingAddress(unsigned char address); + + /// Sets the address to send this packet to (only use for sending) + AREXPORT unsigned char getSendingAddress(void); + + /// Gets the address this packet was sent from (only use for receiving) + AREXPORT unsigned char getReceivedAddress(void); + + /// returns true if the crc matches what it should be + AREXPORT bool verifyCRC(void); + + /// returns the ID of the packet (first byte of data) + AREXPORT ArTypes::UByte getID(void); + + /// returns the crc, probably used only internally + AREXPORT ArTypes::Byte2 calcCRC(void); + + // only call finalizePacket before a send + AREXPORT virtual void finalizePacket(void); + AREXPORT virtual void resetRead(void); + + /// Gets the time the packet was received at + AREXPORT ArTime getTimeReceived(void); + /// Sets the time the packet was received at + AREXPORT void setTimeReceived(ArTime timeReceived); + + /// Duplicates the packet + AREXPORT virtual void duplicatePacket(ArLMS2xxPacket *packet); +protected: + ArTime myTimeReceived; + unsigned char mySendingAddress; +}; + +typedef ArLMS2xxPacket ArSickPacket; + +#endif // ARSICKPACKET_H diff --git a/Legacy/Aria/include/ArLMS2xxPacketReceiver.h b/Legacy/Aria/include/ArLMS2xxPacketReceiver.h new file mode 100644 index 0000000..0611b2d --- /dev/null +++ b/Legacy/Aria/include/ArLMS2xxPacketReceiver.h @@ -0,0 +1,71 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARLMS2XXPACKETRECEIVER_H +#define ARLMS2XXPACKETRECEIVER_H + +#include "ariaTypedefs.h" +#include "ArDeviceConnection.h" +#include "ArLMS2xxPacket.h" + +/// Given a device connection it receives packets from the sick through it +class ArLMS2xxPacketReceiver +{ +public: + /// Constructor without an already assigned device connection + AREXPORT ArLMS2xxPacketReceiver(unsigned char receivingAddress = 0, + bool allocatePackets = false, + bool useBase0Address = false); + /// Constructor with assignment of a device connection + AREXPORT ArLMS2xxPacketReceiver(ArDeviceConnection *deviceConnection, + unsigned char receivingAddress = 0, + bool allocatePackets = false, + bool useBase0Address = false); + /// Destructor + AREXPORT virtual ~ArLMS2xxPacketReceiver(); + + /// Receives a packet from the robot if there is one available + AREXPORT ArLMS2xxPacket *receivePacket(unsigned int msWait = 0); + + /// Sets the device this instance receives packets from + AREXPORT void setDeviceConnection(ArDeviceConnection *deviceConnection); + /// Gets the device this instance receives packets from + AREXPORT ArDeviceConnection *getDeviceConnection(void); + + /// Gets whether or not the receiver is allocating packets + AREXPORT bool isAllocatingPackets(void) { return myAllocatePackets; } + +protected: + ArDeviceConnection *myDeviceConn; + bool myAllocatePackets; + ArLMS2xxPacket myPacket; + unsigned char myReceivingAddress; + bool myUseBase0Address; + enum { STATE_START, STATE_ADDR, STATE_START_COUNT, STATE_ACQUIRE_DATA }; +}; + +typedef ArLMS2xxPacketReceiver ArSickPacketReceiver; + +#endif // ARSICKPACKETRECEIVER_H diff --git a/Legacy/Aria/include/ArLaser.h b/Legacy/Aria/include/ArLaser.h new file mode 100644 index 0000000..a5838fe --- /dev/null +++ b/Legacy/Aria/include/ArLaser.h @@ -0,0 +1,761 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARRANGEDEVICELASER_H +#define ARRANGEDEVICELASER_H + +#include "ariaTypedefs.h" +#include "ArRangeDeviceThreaded.h" + +class ArDeviceConnection; + + + +/** Range device interface specialized for laser rangefinder sensors. + + This class is a subclass of ArRangeDeviceThreaded meant for any + planar scanning lasers, like the SICK lasers, Hokoyo URG series + lasers, etc. Unlike other base classes this contains the superset + of everything that may need to be configured on any of the sensors, + even though some subclasses may only provide some of those parameters + and features. (This allows the configuration interfaces and parameter + files to work for any laser type.) + + Normally, a program does not define or create any ArLaser objects + directly. Instead, + objects (device-specific subclasses of ArLaser) are created by ArLaserConnector::connectLasers() + based on the robot parameter file and command line arguments, and + the resulting ArLaser objects are stored in the ArRobot object + Use ArRobot::getLaserMap() or ArRobot::findLaser() to access the ArLaser + objects after calling ArLaserConnector::connectLasers(). + + The + canSetDegrees(), canChooseRange(), canSetIncrement(), + canChooseIncrement(), canChooseUnits(), canChooseReflectorBits(), + canSetPowerControlled(), canChooseStartBaud(), and canChooseAutoBaud() and +other similar functions are used by ArLaserConnector to test if a parameter + is relevant to a specific laser type. + + + @par Creating New ArLaser Subclasses + If you want to create your own new class to implement a sensor + not in ARIA, create a subclass of this class. ArUrg + is the best current example of this. + Call the laserAllow* + functions in its constructor depending on what features + that laser sensor has (use the laserAllowSet* functions if it is possible + to set any value in a range, or use the laserAllow*Choices functions if it + is only possible to set specific values). + You may also want to use the override the laserSetName + call so that your own mutexes will get named appropriately. You + can use laserSetDefaultTcpPort to set the default TCP port (which + you should do if the laser normally is connected to over TCP). You + can use laserSetDefaultPortType to the type of port normally used + (so that if a port is passed in we can make a reasonable guess as + to what type, so that people don't always have to pass in a type). + Before you connect you should call laserPullUnsetParams to fill in + the parameters that weren't set explicitly with the default ones in + the .p files. If the maximum range of the laser changes depending + on settings (like on the LMS2xx) you should call + laserSetAbsoluteMaxRange (after you call + laserPullUnsetParamsFromRobot). Implement the blockingConnect, + asyncConnect, disconnect, isConnected, and isTryingToConnect + calls... while calling laserConnect, laserFailedConnect, + laserDisconnectNormally, and laserDisconnectOnError calls to let + the laser base class call the appropriate callbacks. You should + use the laserCheckLostConnection in your runThread to see if the + laser has lost connection (see its documentation for details). + Then after you get your readings call laserProcessReadings to fill + them from the raw buffer into the current and cumulative buffer + (and call the reading callbacks). The internal* calls are all + internal to the base class and shouldn't have to be used by + inheriting classes. After you have created a new laser type you + can add it to Aria by using the Aria::laserAddCreator call and then + it will work like any of the built in laser types (see the + documentation for that function for what the creator needs to do, + and an example is ArLaserCreatorHelper in the ariaUtil.h/cpp + files). Similiarly if you need a new connection type (ie not + serial or tcp) you implement them and then use + Aria::deviceConnectionAddCreator call to add new types so they too + will then be treated the same as the built in Aria ones + (ArDeviceConnectionCreatorHelper in ariaUtil.h/cpp file is the + example for that one). + + @since 2.7.0 + @ingroup ImportantClasses + @ingroup DeviceClasses +**/ + +class ArLaser : public ArRangeDeviceThreaded +{ +public: + /// Constructor + AREXPORT ArLaser(int laserNumber, + const char *name, + unsigned int absoluteMaxRange, + bool locationDependent = false, + bool appendLaserNumberToName = true); + /// Destructor + AREXPORT virtual ~ArLaser(); + + /// Connect to the laser and block for the result + AREXPORT virtual bool blockingConnect(void) = 0; + /// Connect to the laser without blocking + AREXPORT virtual bool asyncConnect(void) = 0; + /// Disconnect from the laser + AREXPORT virtual bool disconnect(void) = 0; + /// See if the laser is connected + AREXPORT virtual bool isConnected(void) = 0; + /// See if the laser is trying to connect + AREXPORT virtual bool isTryingToConnect(void) = 0; + + /// Sets the numter of seconds without a response until connection assumed lost + AREXPORT virtual void setConnectionTimeoutSeconds(double seconds); + /// Gets the number of seconds without a response until connection assumed lost + AREXPORT virtual double getConnectionTimeoutSeconds(void); + + /// Gets the time data was last receieved + ArTime getLastReadingTime(void) { return myLastReading; } + + /// Gets the number of laser readings received in the last second + AREXPORT int getReadingCount(void); + + /// Sets the device connection + AREXPORT virtual void setDeviceConnection(ArDeviceConnection *conn); + /// Gets the device connection + AREXPORT virtual ArDeviceConnection *getDeviceConnection(void); + + /// Sets the position of the sensor on the robot + AREXPORT void setSensorPosition(double x, double y, double th, double z = 0); + /// Sets the position of the sensor on the robot + AREXPORT void setSensorPosition(ArPose pose, double z = 0); + /// Gets if the sensor pose has been set + bool hasSensorPosition(void) { return myHaveSensorPose; } + /// Gets the position of the sensor on the robot + ArPose getSensorPosition(void) { return mySensorPose; } + /// Gets the X position of the sensor on the robot + double getSensorPositionX(void) { return mySensorPose.getX(); } + /// Gets the Y position of the sensor on the robot + double getSensorPositionY(void) { return mySensorPose.getY(); } + /// Gets the Z position of the sensor on the robot (0 is unknown) + double getSensorPositionZ(void) { return mySensorZ; } + /// Gets the heading of the sensor on the robot + double getSensorPositionTh(void) { return mySensorPose.getTh(); } + + /// Gets the number of the laser this is + int getLaserNumber(void) { return myLaserNumber; } + + /// Sets the log level that informational things are logged at + void setInfoLogLevel(ArLog::LogLevel infoLogLevel) + { myInfoLogLevel = infoLogLevel; } + /// Gets the log level that informational things are logged at + ArLog::LogLevel getInfoLogLevel(void) + { return myInfoLogLevel; } + + /// Cumulative readings that are this close to current beams are discarded + void setCumulativeCleanDist(double dist) + { + myCumulativeCleanDist = dist; + myCumulativeCleanDistSquared = dist * dist; + } + /// Cumulative readings that are this close to current beams are discarded + double getCumulativeCleanDist(void) + { + return myCumulativeCleanDist; + } + /// Cumulative readings are cleaned every this number of milliseconds + void setCumulativeCleanInterval(int milliSeconds) + { + myCumulativeCleanInterval = milliSeconds; + } + /// Cumulative readings are cleaned every this number of milliseconds + int getCumulativeCleanInterval(void) + { + return myCumulativeCleanInterval; + } + /// Offset for cumulative cleaning + void setCumulativeCleanOffset(int milliSeconds) + { + myCumulativeCleanOffset = milliSeconds; + } + /// Gets the offset for cumulative cleaning + int getCumulativeCleanOffset(void) + { + return myCumulativeCleanOffset; + } + /// Resets when the cumulative cleaning happened (so offset can help) + void resetLastCumulativeCleanTime(void) + { + myCumulativeLastClean.setToNow(); + myCumulativeLastClean.addMSec(myCumulativeCleanOffset); + } + + /// Adds a series of degree at which to ignore readings (within 1 degree of nearest integer) + AREXPORT bool addIgnoreReadings(const char *ignoreReadings); + /// Adds a degree at which to ignore readings (within 1 degree of nearest integer) + void addIgnoreReading(double ignoreReading) + { myIgnoreReadings.insert(ArMath::roundInt(ignoreReading)); } + /// Clears the degrees we ignore readings at + void clearIgnoreReadings(void) + { myIgnoreReadings.clear(); } + /// Gets the list of readings that we ignore + const std::set *getIgnoreReadings(void) const + { return &myIgnoreReadings; } + + /// Gets if the laser is flipped or not + bool getFlipped(void) { return myFlipped; } + /// Sets if the laser is flipped or not + bool setFlipped(bool flipped) { myFlipped = flipped; return true; } + + /// Gets the default TCP port for the laser + int getDefaultTcpPort(void) { return myDefaultTcpPort; } + + /// Gets the default port type for the laser + const char *getDefaultPortType(void) { return myDefaultPortType.c_str(); } + + /// Sees if this class can set the degrees with doubles or not + /** + Gets if this class can set the start and end degrees with doubles. + + If so, you can use getStartDegreesMin and getStartDegreesMax to see + the valid values that you can use with setStartDegrees (and see + what was set with getStartDegrees), and getEndDegreesMin and + getEndDegreesMax to see the valid values that you can use with + setEndDegrees (and see what was set with getEndDegrees). + + **/ + bool canSetDegrees(void) { return myCanSetDegrees; } + + /// Gets the minimum value for the start angle + /** @see canSetDegrees **/ + double getStartDegreesMin(void) { return myStartDegreesMin; } + /// Gets the maximum value for the start angle + /** @see canSetDegrees **/ + double getStartDegreesMax(void) { return myStartDegreesMax; } + /// Gets the start angle + /** @see canSetDegrees **/ + double getStartDegrees(void) { return myStartDegrees; } + /// Sets the start angle, it must be between getStartDegreesMin and getStartDegreesMax + /** @see canSetDegrees **/ + AREXPORT bool setStartDegrees(double startDegrees); + /// Gets the minimum value for the end angle + /** @see canSetDegrees **/ + double getEndDegreesMin(void) { return myEndDegreesMin; } + /// Gets the maximum value for the end angle + /** @see canSetDegrees **/ + double getEndDegreesMax(void) { return myEndDegreesMax; } + /// Gets the end angle + /** @see canSetDegrees **/ + double getEndDegrees(void) { return myEndDegrees; } + /// Sets the end angle, it must be between getEndDegreesMin and getEndDegreesMax + /** @see canSetDegrees **/ + AREXPORT bool setEndDegrees(double endDegrees); + + + /** + Gets if you can choose the number of degrees + + If so, you can call chooseDegrees with one of the strings from + getDegreesChoices, and get the degrees chosen as a string with + getDegreesChoice or get the degrees chosen as a double with + getDegreesChoiceDouble. + **/ + bool canChooseDegrees(void) { return myCanChooseDegrees; } + /// Gets the list of range choices + /** @see canChooseDegrees **/ + std::list getDegreesChoices(void) + { return myDegreesChoicesList; } + /// Gets a string with the list of degrees choices seperated by |s + /** @see canChooseDegrees **/ + const char *getDegreesChoicesString(void) + { return myDegreesChoicesString.c_str(); } + /// Sets the range to one of the choices from getDegreesChoices + /** @see canChooseDegrees **/ + AREXPORT bool chooseDegrees(const char *range); + /// Gets the range that was chosen + /** @see canChooseDegrees **/ + const char *getDegreesChoice(void) + { return myDegreesChoice.c_str(); } + /// Gets the range that was chosen as a double + /** @see canChooseDegrees **/ + double getDegreesChoiceDouble(void) { return myDegreesChoiceDouble; } + /// Gets the map of degrees choices to what they mean + /** + This is mostly for the simulated laser + @see canChooseDegrees + @internal + **/ + std::map getDegreesChoicesMap(void) + { return myDegreesChoices; } + + + /** + Gets if you can set an increment + + **/ + bool canSetIncrement(void) { return myCanSetIncrement; } + /// Gets the increment minimum + /** @see canSetIncrement **/ + double getIncrementMin(void) { return myIncrementMin; } + /// Gets the increment maximum + /** @see canSetIncrement **/ + double getIncrementMax(void) { return myIncrementMax; } + /// Gets the increment + /** @see canSetIncrement **/ + double getIncrement(void) { return myIncrement; } + /// Sets the increment + /** @see canSetIncrement **/ + AREXPORT bool setIncrement(double increment); + + /** + Gets if you can choose an increment. + + If so, call chooseIncrement with one of the choices in + getIncrementChoices, and get the choice as a string with + getIncrementChoice or the choice as a string with + getIncrementChoiceDouble. + **/ + bool canChooseIncrement(void) { return myCanChooseIncrement; } + /// Gets the list of increment choices + /** @see canChooseIncrement **/ + std::list getIncrementChoices(void) + { return myIncrementChoicesList; } + /// Gets a string with the list of increment choices seperated by |s + /** @see canChooseIncrement **/ + const char *getIncrementChoicesString(void) + { return myIncrementChoicesString.c_str(); } + /// Sets the increment to one of the choices from getIncrementChoices + /** @see canChooseIncrement **/ + AREXPORT bool chooseIncrement(const char *increment); + /// Gets the increment that was chosen + /** @see canChooseIncrement **/ + const char *getIncrementChoice(void) { return myIncrementChoice.c_str(); } + /// Gets the increment that was chosen as a double + /** @see canChooseIncrement **/ + double getIncrementChoiceDouble(void) { return myIncrementChoiceDouble; } + /// Gets the map of increment choices to what they mean + /** + This is mostly for the simulated laser + @see canChooseIncrement + @internal + **/ + std::map getIncrementChoicesMap(void) + { return myIncrementChoices; } + + /** + Gets if you can choose units for the laser. + + If so, call chooseUnits with one of the choices in + getUnitsChoices, and see what the choice was with + getUnitsChoice. + **/ + bool canChooseUnits(void) { return myCanChooseUnits; } + /// Gets the list of units choices + /** @see canChooseUnits **/ + std::list getUnitsChoices(void) + { return myUnitsChoices; } + /// Gets a string with the list of units choices seperated by |s + /** @see canChooseUnits **/ + const char *getUnitsChoicesString(void) + { return myUnitsChoicesString.c_str(); } + /// Sets the units to one of the choices from getUnitsChoices + /** @see canChooseUnits **/ + AREXPORT bool chooseUnits(const char *units); + /// Gets the units that was chosen + /** @see canChooseUnits **/ + const char *getUnitsChoice(void) { return myUnitsChoice.c_str(); } + + /** + Gets if you can choose reflectorBits for the laser. + + If so, call chooseReflectorBits with one of the choices in + getReflectorBitsChoices, and see what the choice was with + getReflectorBitsChoice. + **/ + bool canChooseReflectorBits(void) { return myCanChooseReflectorBits; } + /// Gets the list of reflectorBits choices + /** @see canChooseReflectorBits **/ + std::list getReflectorBitsChoices(void) + { return myReflectorBitsChoices; } + /// Gets a string with the list of reflectorBits choices seperated by |s + /** @see canChooseReflectorBits **/ + const char *getReflectorBitsChoicesString(void) + { return myReflectorBitsChoicesString.c_str(); } + /// Sets the reflectorBits to one of the choices from getReflectorBitsChoices + /** @see canChooseReflectorBits **/ + AREXPORT bool chooseReflectorBits(const char *reflectorBits); + /// Gets the reflectorBits that was chosen + /** @see canChooseReflectorBits **/ + const char *getReflectorBitsChoice(void) { return myReflectorBitsChoice.c_str(); } + + /** + Gets if you can set powerControlled for the laser. + + If so, call setPowerControlled to set if the power is being controlled + or not, and see what the setting is with getPowerControlled. + **/ + bool canSetPowerControlled(void) { return myCanSetPowerControlled; } + /// Sets if the power is controlled + /** @see canChoosePowerControlled **/ + AREXPORT bool setPowerControlled(bool powerControlled); + /// Gets if the power is controlled + /** @see canChoosePowerControlled **/ + bool getPowerControlled(void) { return myPowerControlled; } + + /** + Gets if you can choose startingBaud for the laser. + + If so, call chooseStartingBaud with one of the choices in + getStartingBaudChoices, and see what the choice was with + getStartingBaudChoice. + **/ + bool canChooseStartingBaud(void) { return myCanChooseStartingBaud; } + /// Gets the list of reflectorBits choices + /** @see canChooseStartingBaud **/ + std::list getStartingBaudChoices(void) + { return myStartingBaudChoices; } + /// Gets a string with the list of reflectorBits choices seperated by |s + /** @see canChooseStartingBaud **/ + const char *getStartingBaudChoicesString(void) + { return myStartingBaudChoicesString.c_str(); } + /// Sets the reflectorBits to one of the choices from getStartingBaudChoices + /** @see canChooseStartingBaud **/ + AREXPORT bool chooseStartingBaud(const char *reflectorBits); + /// Gets the reflectorBits that was chosen + /** @see canChooseStartingBaud **/ + const char *getStartingBaudChoice(void) { return myStartingBaudChoice.c_str(); } + + + /** + Gets if you can choose autoBaud for the laser. + + If so, call chooseAutoBaud with one of the choices in + getAutoBaudChoices, and see what the choice was with + getAutoBaudChoice. + **/ + bool canChooseAutoBaud(void) { return myCanChooseAutoBaud; } + /// Gets the list of reflectorBits choices + /** @see canChooseAutoBaud **/ + std::list getAutoBaudChoices(void) + { return myAutoBaudChoices; } + /// Gets a string with the list of reflectorBits choices seperated by |s + /** @see canChooseAutoBaud **/ + const char *getAutoBaudChoicesString(void) + { return myAutoBaudChoicesString.c_str(); } + /// Sets the reflectorBits to one of the choices from getAutoBaudChoices + /** @see canChooseAutoBaud **/ + AREXPORT bool chooseAutoBaud(const char *reflectorBits); + /// Gets the reflectorBits that was chosen + /** @see canChooseAutoBaud **/ + const char *getAutoBaudChoice(void) { return myAutoBaudChoice.c_str(); } + + + /// Adds a connect callback + void addConnectCB(ArFunctor *functor, + int position = 50) + { myConnectCBList.addCallback(functor, position); } + /// Adds a disconnect callback + void remConnectCB(ArFunctor *functor) + { myConnectCBList.remCallback(functor); } + + /// Adds a callback for when a connection to the robot is failed + void addFailedConnectCB(ArFunctor *functor, + int position = 50) + { myFailedConnectCBList.addCallback(functor, position); } + /// Removes a callback for when a connection to the robot is failed + void remFailedConnectCB(ArFunctor *functor) + { myFailedConnectCBList.remCallback(functor); } + + /// Adds a callback for when disconnect is called while connected + void addDisconnectNormallyCB(ArFunctor *functor, + int position = 50) + { myDisconnectNormallyCBList.addCallback(functor, position); } + + /// Removes a callback for when disconnect is called while connected + void remDisconnectNormallyCB(ArFunctor *functor) + { myDisconnectNormallyCBList.remCallback(functor); } + + /// Adds a callback for when disconnection happens because of an error + void addDisconnectOnErrorCB(ArFunctor *functor, + int position = 50) + { myDisconnectOnErrorCBList.addCallback(functor, position); } + + /// Removes a callback for when disconnection happens because of an error + void remDisconnectOnErrorCB(ArFunctor *functor) + { myDisconnectOnErrorCBList.remCallback(functor); } + + /// Adds a callback that is called whenever a laser reading is processed + void addReadingCB(ArFunctor *functor, + int position = 50) + { myDataCBList.addCallback(functor, position); } + + /// Removes a callback that is called whenever a laser reading is processed + void remReadingCB(ArFunctor *functor) + { myDataCBList.remCallback(functor); } + + /// Gets the absolute maximum range on the sensor + unsigned int getAbsoluteMaxRange(void) { return myAbsoluteMaxRange; } + + /// Copies the reading count stuff from another laser (for the laser filter) + AREXPORT void copyReadingCount(const ArLaser* laser); + + /// override the default to bound the maxrange by the absolute max range + AREXPORT virtual void setMaxRange(unsigned int maxRange); + + /// override the default to keep track of its been set or not + AREXPORT virtual void setCumulativeBufferSize(size_t size); + + /// Call the laser can implement to make sure the parameters + /// are all okay or set the maximum range (based on the params) + /** + The base laser should make sure all the parameters make sense + according to what was set up as allowed. + + This is here for two purposes. The first is to check for + parameters that aren't valid because of something the base class + can't check for. The second is to recalculate whatever the + maximum range of the sensor is based on those settings, and call + setAbsoluteMaxRange if the maximum range has changed based on the + settings. + + This is strictly an internal call, mostly for the simulated laser + so that it can more closely match the real laser on complicated + things like the LMS2xx where the settings for the units and bits + affect what the maximum range is. + + @internal + **/ + AREXPORT virtual bool laserCheckParams(void) { return true; } + + /// Applies a transform to the buffers + AREXPORT virtual void applyTransform(ArTransform trans, + bool doCumulative = true); + + /// Makes it so we'll apply simple naming to all the lasers + AREXPORT static void useSimpleNamingForAllLasers(void); +protected: + + /// Converts the raw readings into the buffers (needs to be called + /// by subclasses) + AREXPORT void laserProcessReadings(void); + + /// Returns if the laser has lost connection so that the subclass + /// can do something appropriate + AREXPORT bool laserCheckLostConnection(void); + + /// Pulls the unset params from the robot parameter file + AREXPORT bool laserPullUnsetParamsFromRobot(void); + + /// Allows setting the degrees the laser uses to anything in a range + AREXPORT void laserAllowSetDegrees(double defaultStartDegrees, double startDegreesMin, double startDegreesMax, double defaultEndDegrees, double endDegreesMin, double endDegreesMax); + + /// Allows setting the degrees the laser uses to one of a number of choices + AREXPORT void laserAllowDegreesChoices(const char *defaultDegreesChoice, + std::map degreesChoices); + + /// Allows setting the increment the laser uses to anything in a range + AREXPORT void laserAllowSetIncrement( + double defaultIncrement, double incrementMin, double incrementMax); + + /// Allows setting the increment to one of a number of choices + AREXPORT void laserAllowIncrementChoices(const char *defaultIncrementChoice, + std::map incrementChoices); + + /// Allows setting the units the laser will use to one of a number of choices + AREXPORT void laserAllowUnitsChoices(const char *defaultUnitsChoice, + std::list unitsChoices); + + /// Allows setting the reflector bits the laser will use to one of a + /// number of choices + AREXPORT void laserAllowReflectorBitsChoices( + const char *defaultReflectorBitsChoice, + std::list reflectorBitsChoices); + + /// Allows setting if the power is controlled or not + AREXPORT void laserAllowSetPowerControlled(bool defaultPowerControlled); + + /// Allows setting the starting baud to one of a number of choices + AREXPORT void laserAllowStartingBaudChoices( + const char *defaultStartingBaudChoice, + std::list startingBaudChoices); + + /// Allows setting the auto baud speed to one of a number of choices + AREXPORT void laserAllowAutoBaudChoices( + const char *defaultAutoBaudChoice, + std::list autoBaudChoices); + + /// Called when the lasers name is set + AREXPORT virtual void laserSetName(const char *name); + + /// Sets the laser's default TCP port + AREXPORT void laserSetDefaultTcpPort(int defaultLaserTcpPort); + + /// Sets the laser's default connection port type + AREXPORT void laserSetDefaultPortType(const char *defaultPortType); + + /// Sets the absolute maximum range on the sensor + AREXPORT void laserSetAbsoluteMaxRange(unsigned int absoluteMaxRange); + + /// Function for a laser to call when it connects + AREXPORT virtual void laserConnect(void); + /// Function for a laser to call when it fails to connects + AREXPORT virtual void laserFailedConnect(void); + /// Function for a laser to call when it disconnects normally + AREXPORT virtual void laserDisconnectNormally(void); + /// Function for a laser to call when it loses connection + AREXPORT virtual void laserDisconnectOnError(void); + + // processes the individual reading, helper for base class + AREXPORT void internalProcessReading(double x, double y, unsigned int range, + bool clean, bool onlyClean); + + // internal helper function for seeing if the choice matches + AREXPORT bool internalCheckChoice(const char *check, const char *choice, + std::list *choices, const char *choicesStr); + // internal helper function for seeing if the choice matches + AREXPORT bool internalCheckChoice(const char *check, const char *choice, + std::map *choices, + const char *choicesStr, double *choiceDouble); + // internal helper function for building a string for a list of chocies + void internalBuildChoicesString(std::list *choices, std::string *str); + // internal helper function for building a string for a list of chocies + void internalBuildChoices(std::map *choices, + std::string *str, std::list *choicesList); + + // Function called in laserProcessReadings to indicate that a + // reading was received + AREXPORT virtual void internalGotReading(void); + + int myLaserNumber; + + + ArDeviceConnection *myConn; + ArMutex myConnMutex; + + double myTimeoutSeconds; + + + ArPose mySensorPose; + double mySensorZ; + bool myHaveSensorPose; + + double myCumulativeCleanDist; + double myCumulativeCleanDistSquared; + int myCumulativeCleanInterval; + int myCumulativeCleanOffset; + ArTime myCumulativeLastClean; + std::set myIgnoreReadings; + + unsigned int myAbsoluteMaxRange; + bool myMaxRangeSet; + + bool myCumulativeBufferSizeSet; + + bool myFlippedSet; + bool myFlipped; + + bool myCanSetDegrees; + double myStartDegreesMin; + double myStartDegreesMax; + bool myStartDegreesSet; + double myStartDegrees; + double myEndDegreesMin; + double myEndDegreesMax; + bool myEndDegreesSet; + double myEndDegrees; + + bool myCanChooseDegrees; + std::map myDegreesChoices; + std::list myDegreesChoicesList; + bool myDegreesChoiceSet; + std::string myDegreesChoicesString; + std::string myDegreesChoice; + double myDegreesChoiceDouble; + + + bool myCanSetIncrement; + double myIncrementMin; + double myIncrementMax; + bool myIncrementSet; + double myIncrement; + + bool myCanChooseIncrement; + std::map myIncrementChoices; + std::list myIncrementChoicesList; + std::string myIncrementChoicesString; + bool myIncrementChoiceSet; + std::string myIncrementChoice; + double myIncrementChoiceDouble; + + bool myCanChooseUnits; + std::list myUnitsChoices; + std::string myUnitsChoicesString; + bool myUnitsChoiceSet; + std::string myUnitsChoice; + + bool myCanChooseReflectorBits; + std::list myReflectorBitsChoices; + std::string myReflectorBitsChoicesString; + bool myReflectorBitsChoiceSet; + std::string myReflectorBitsChoice; + + bool myCanSetPowerControlled; + bool myPowerControlledSet; + bool myPowerControlled; + + bool myCanChooseStartingBaud; + std::list myStartingBaudChoices; + std::string myStartingBaudChoicesString; + bool myStartingBaudChoiceSet; + std::string myStartingBaudChoice; + + bool myCanChooseAutoBaud; + std::list myAutoBaudChoices; + std::string myAutoBaudChoicesString; + bool myAutoBaudChoiceSet; + std::string myAutoBaudChoice; + + int myDefaultTcpPort; + std::string myDefaultPortType; + + ArCallbackList myConnectCBList; + ArCallbackList myFailedConnectCBList; + ArCallbackList myDisconnectOnErrorCBList; + ArCallbackList myDisconnectNormallyCBList; + ArCallbackList myDataCBList; + + ArLog::LogLevel myInfoLogLevel; + + ArTime myLastReading; + // packet count + time_t myTimeLastReading; + int myReadingCurrentCount; + int myReadingCount; + bool myRobotRunningAndConnected; + + static bool ourUseSimpleNaming; +}; + +#endif // ARRANGEDEVICELASER_H diff --git a/Legacy/Aria/include/ArLaserConnector.h b/Legacy/Aria/include/ArLaserConnector.h new file mode 100644 index 0000000..290de9f --- /dev/null +++ b/Legacy/Aria/include/ArLaserConnector.h @@ -0,0 +1,250 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARLASERCONNECTOR_H +#define ARLASERCONNECTOR_H + +#include "ariaTypedefs.h" +#include "ArSerialConnection.h" +#include "ArTcpConnection.h" +#include "ArArgumentBuilder.h" +#include "ArArgumentParser.h" +#include "ariaUtil.h" +#include "ArRobotConnector.h" + +class ArLaser; +class ArRobot; + + + +/// Create laser interface objects (for any kind of laser supported by ARIA) and connect to lasers based on parameters from robot parameter file and command-line arguments +/** + + ArLaserConnector makes a laser connection (e.g. through serial port, + TCP network connection, or to simulator connection as a special case if + the robot connection is to a simulator.) + Parameters are configurable through command-line arguments or in the robot + parameter file. + + + When you create your ArLaserConnector, pass it command line parameters via + either the argc and argv variables from main(), or pass it an + ArArgumentBuilder or ArArgumentParser object. (ArArgumentBuilder + is able to obtain command line parameters from a Windows program + that uses WinMain() instead of main()). + ArLaserConnector registers a callback with the global Aria class. Use + Aria::parseArgs() to parse all command line parameters to the program, and + Aria::logOptions() to print out information about all registered command-line parameters. + ArLaserConnector will be included in these. + + Then, to connect to any lasers that were set up in the robot parameter file or + via command line arguments, call connectLasers(). If successful, + connectLasers() will return true and add an entry for each laser connected + in the ArRobot object's list of lasers. These ArLaser objects can be + accessed from your ArRobot object via ArRobot::findLaser() or ArRobot::getLaserMap(). + + (The internal interface used by ARIA to connect to configured lasers and add + them to ArRobot is also + available if you need to use it: See addLaser(); but this is normally not +neccesary for almost all cases.) + + The following command-line arguments are checked: + @verbinclude ArLaserConnector_options + + @since 2.7.0 + @ingroup ImportantClasses + @ingroup DeviceClasses + **/ +class ArLaserConnector +{ +public: + /// Constructor that takes argument parser + AREXPORT ArLaserConnector( + ArArgumentParser *parser, + ArRobot *robot, ArRobotConnector *robotConnector, + bool autoParseArgs = true, + ArLog::LogLevel infoLogLevel = ArLog::Verbose, + ArRetFunctor1 *turnOnPowerOutputCB = NULL, + ArRetFunctor1 *turnOffPowerOutputCB = NULL); + /// Destructor + AREXPORT ~ArLaserConnector(void); + /// Connects all the lasers the robot has that should be auto connected + AREXPORT bool connectLasers(bool continueOnFailedConnect = false, + bool addConnectedLasersToRobot = true, + bool addAllLasersToRobot = false, + bool turnOnLasers = true, + bool powerCycleLaserOnFailedConnect = true, + int *failedOnLaser = NULL); + /// Sets up a laser to be connected + AREXPORT bool setupLaser(ArLaser *laser, + int laserNumber = 1); + /// Connects the laser synchronously (will take up to a minute) + AREXPORT bool connectLaser(ArLaser *laser, + int laserNumber = 1, + bool forceConnection = true); + /// Adds a laser so parsing will get it + AREXPORT bool addLaser(ArLaser *laser, + int laserNumber = 1); + /// Adds a laser for parsing but where connectLaser will be called later + AREXPORT bool addPlaceholderLaser(ArLaser *placeholderLaser, + int laserNumber = 1, + bool takeOwnershipOfPlaceholder = false); + /// Function to parse the arguments given in the constructor + AREXPORT bool parseArgs(void); + /// Function to parse the arguments given in an arbitrary parser + AREXPORT bool parseArgs(ArArgumentParser *parser); + /// Log the options the simple connector has + AREXPORT void logOptions(void) const; + /// Internal function to get the laser (only useful between parseArgs and connectLasers) + AREXPORT ArLaser *getLaser(int laserNumber); + + /// Internal function to replace the laser (only useful between parseArgs and connectLasers) but not the laser data + AREXPORT bool replaceLaser(ArLaser *laser, int laserNumber); + +protected: + /// Class that holds information about the laser data + class LaserData + { + public: + LaserData(int number, ArLaser *laser, + bool laserIsPlaceholder = false, bool ownPlaceholder = false) + { + myNumber = number; + myLaser = laser; + myConn = NULL; + myLaserIsPlaceholder = laserIsPlaceholder; + myOwnPlaceholder = ownPlaceholder; + myConnect = false; myConnectReallySet = false; + myPort = NULL; + myPortType = NULL; + myRemoteTcpPort = 0; myRemoteTcpPortReallySet = false; + myFlipped = false; myFlippedReallySet = false; + myDegreesStart = HUGE_VAL; myDegreesStartReallySet = false; + myDegreesEnd = -HUGE_VAL; myDegreesEndReallySet = false; + myDegrees = NULL; + myIncrementByDegrees = -HUGE_VAL; myIncrementByDegreesReallySet = false; + myIncrement = NULL; + myUnits = NULL; + myReflectorBits = NULL; + myPowerControlled = true; myPowerControlledReallySet = false; + myStartingBaud = NULL; + myAutoBaud = NULL; + myMaxRange = INT_MAX; myMaxRangeReallySet = false; + myAdditionalIgnoreReadings = NULL; + } + virtual ~LaserData() {} + /// The number of this laser + int myNumber; + /// The actual pointer to this laser + ArLaser *myLaser; + // our connection + ArDeviceConnection *myConn; + /// If the laser is a placeholder for parsing + bool myLaserIsPlaceholder; + /// If we own the placeholder laser + bool myOwnPlaceholder; + // if we want to connect the laser + bool myConnect; + // if myConnect was really set + bool myConnectReallySet; + // the port we want to connect the laser on + const char *myPort; + // the type of port we want to connect to the laser on + const char *myPortType; + // laser tcp port if we're doing a remote host + int myRemoteTcpPort; + // if our remote laser tcp port was really set + bool myRemoteTcpPortReallySet; + // if we have the laser flipped + bool myFlipped; + // if our flipped was really set + bool myFlippedReallySet; + // what degrees to start at + double myDegreesStart; + // if our start degrees was really set + bool myDegreesStartReallySet; + // what degrees to end at + double myDegreesEnd; + // if our end degrees was really set + bool myDegreesEndReallySet; + // the degrees we want wto use + const char *myDegrees; + // what increment to use + double myIncrementByDegrees; + // if our end degrees was really set + bool myIncrementByDegreesReallySet; + // the increment we want to use + const char *myIncrement; + /// the units we want to use + const char *myUnits; + /// the reflector bits we want to use + const char *myReflectorBits; + // if we are controlling the laser power + bool myPowerControlled; + // if our flipped was really set + bool myPowerControlledReallySet; + /// the starting baud we want to use + const char *myStartingBaud; + /// the auto baud we want to use + const char *myAutoBaud; + // if we set a new max range from the command line + int myMaxRange; + // if our new max range was really set + bool myMaxRangeReallySet; + /// the additional laser ignore readings + const char *myAdditionalIgnoreReadings; + }; + std::map myLasers; + + /// Parses the laser arguments + AREXPORT bool parseLaserArgs(ArArgumentParser *parser, + LaserData *laserData); + /// Logs the laser command line option help text. + AREXPORT void logLaserOptions(LaserData *laserdata, bool header = true, bool metaOpts = true) const; + // Sets the laser parameters + bool internalConfigureLaser(LaserData *laserData); + + std::string myLaserTypes; + + // our parser + ArArgumentParser *myParser; + bool myOwnParser; + // if we should autoparse args or toss errors + bool myAutoParseArgs; + bool myParsedArgs; + + ArRobot *myRobot; + ArRobotConnector *myRobotConnector; + + ArLog::LogLevel myInfoLogLevel; + + ArRetFunctor1 *myTurnOnPowerOutputCB; + ArRetFunctor1 *myTurnOffPowerOutputCB; + + ArRetFunctorC myParseArgsCB; + ArConstFunctorC myLogOptionsCB; +}; + +#endif // ARLASERCONNECTOR_H diff --git a/Legacy/Aria/include/ArLaserFilter.h b/Legacy/Aria/include/ArLaserFilter.h new file mode 100644 index 0000000..fad2c5c --- /dev/null +++ b/Legacy/Aria/include/ArLaserFilter.h @@ -0,0 +1,108 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARLASERFILTER_H +#define ARLASERFILTER_H + +#include "ArLaser.h" +#include "ArFunctor.h" + +class ArRobot; +class ArConfig; + +/// Range device with data obtained from another range device and filtered +/** + This is a class for generically filtering laser readings, either to + separate out ones that are too far or too close compared to their + neighbors. The filtering parameters can be adjusted on line + through ArConfig options. + + This implements ArLaser and so can be used like any other laser, + though you have to set all its options before you create this and + probably should connect it too. Then you should replace the + original laser on ArRobot with this one, and replace the original + laser as a range device too. +**/ +class ArLaserFilter : public ArLaser +{ +public: + /// Constructor + AREXPORT ArLaserFilter(ArLaser *laser, const char *name = NULL); + /// Destructor + AREXPORT ~ArLaserFilter(); + /// Set robot + AREXPORT virtual void setRobot(ArRobot *robot); + /// Add to the config + AREXPORT void addToConfig(ArConfig *config, const char *sectionName, + const char *prefix = ""); + + AREXPORT virtual bool blockingConnect(void) + { return myLaser->blockingConnect(); } + AREXPORT virtual bool asyncConnect(void) + { return myLaser->asyncConnect(); } + AREXPORT virtual bool disconnect(void) + { return myLaser->disconnect(); } + AREXPORT virtual bool isConnected(void) + { return myLaser->isConnected(); } + AREXPORT virtual bool isTryingToConnect(void) + { return myLaser->isTryingToConnect(); } + + AREXPORT virtual void *runThread(void *arg) { return NULL; } + AREXPORT virtual bool laserCheckParams(void) + { + if (!myLaser->laserCheckParams()) + return false; + + laserSetAbsoluteMaxRange(myLaser->getAbsoluteMaxRange()); + return true; + } + + /// Gets the base laser this is filtering + ArLaser *getBaseLaser(void) { return myLaser; } +protected: + AREXPORT int selfLockDevice(void); + AREXPORT int selfTryLockDevice(void); + AREXPORT int selfUnlockDevice(void); + + ArLaser *myLaser; + + // Parameters + double myAngleToCheck; + double myAllFactor; + double myAnyFactor; + double myAnyMinRange; + double myAnyMinRangeLessThanAngle; + double myAnyMinRangeGreaterThanAngle; + + /// Does the check against all neighbor factor + bool checkRanges(int thisReading, int otherReading, double factor); + + // Callback to do the actual filtering + void processReadings(void); + + ArFunctorC myProcessCB; +}; + +#endif // ARLASERFILTER diff --git a/Legacy/Aria/include/ArLaserLogger.h b/Legacy/Aria/include/ArLaserLogger.h new file mode 100644 index 0000000..ce81842 --- /dev/null +++ b/Legacy/Aria/include/ArLaserLogger.h @@ -0,0 +1,197 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARLASERLOGGER_H +#define ARLASERLOGGER_H + +#include + +#include "ariaUtil.h" +#include "ArFunctor.h" + +class ArLaser; +class ArRobot; +class ArJoyHandler; +class ArRobotJoyHandler; +class ArRobotPacket; + +/// This class can be used to create log files for the laser mapper +/** + This class has a pointer to a robot and a laser... every time the + robot has EITHER moved the distDiff, or turned the degDiff, it will + take the current readings from the laser and log them into the log + file given as the fileName to the constructor. Readings can also + be taken by calling takeReading which explicitly tells the logger + to take a reading. + + The class can also add goals, see the constructor arg addGoals for + information about that... you can also explicitly have it add a + goal by calling addGoal. + + @see @ref LaserLogFileFormat for details on the laser scan log output file format. +**/ +class ArLaserLogger +{ +public: + /// Constructor + AREXPORT ArLaserLogger( + ArRobot *robot, ArLaser *laser, double distDiff, + double degDiff, const char *fileName, + bool addGoals = false, + ArJoyHandler *joyHandler = NULL, + const char *baseDirectory = NULL, + bool useReflectorValues = false, + ArRobotJoyHandler *robotJoyHandler = NULL, + const std::map *, + ArStrCaseCmpOp> *extraLocationData = NULL, + std::list *extraLasers = NULL); + /// Destructor + AREXPORT virtual ~ArLaserLogger(); + +#ifndef SWIG + /** @brief Adds a string to the log file with a tag at the given moment + * @swigomit + */ + AREXPORT void addTagToLog(const char *str, ...); +#endif + + /// Same ass addToLog, but no varargs, wrapper for java + AREXPORT void addTagToLogPlain(const char *str); + +#ifndef SWIG + /** @brief Adds a string to the log file without a tag for where or when we are + * @swigomit + */ + AREXPORT void addInfoToLog(const char *str, ...); +#endif + + /// Same as addToInfo, but does it without marking robot position + AREXPORT void addInfoToLogPlain(const char *str); + /// Sets the distance at which the robot will take a new reading + void setDistDiff(double distDiff) { myDistDiff = ArMath::fabs(distDiff); } + /// Gets the distance at which the robot will take a new reading + double getDistDiff(void) { return myDistDiff; } + /// Sets the degrees to turn at which the robot will take a new reading + void setDegDiff(double degDiff) { myDistDiff = ArMath::fabs(degDiff); } + /// Gets the degrees to turn at which the robot will take a new reading + double getDegDiff(void) { return myDegDiff; } + /// Explicitly tells the robot to take a reading + void takeReading(void) { myTakeReadingExplicit = true; } + /// Adds a goal where the robot is at the moment + void addGoal(void) { myAddGoalExplicit = true; } + /// Sees if the file was opened successfully + bool wasFileOpenedSuccessfully(void) + { if (myFile != NULL) return true; else return false; } + /// Gets if we're taking old (sick1:) readings + bool takingOldReadings(void) { return myOldReadings; } + /// Sets if we're taking old (sick1:) readings + void takeOldReadings(bool takeOld) { myOldReadings = takeOld; } + /// Gets if we're taking new (scan1:) readings + bool takingNewReadings(void) { return myNewReadings; } + /// Sets if we're taking old (scan1:) readings + void takeNewReadings(bool takeNew) { myNewReadings = takeNew; } +protected: + /// The task which gets attached to the robot + AREXPORT void robotTask(void); + // internal function that adds goals if needed (and specified) + void internalAddGoal(void); + // internal function that writes tags + void internalWriteTags(void); + // internal function that takes a reading + void internalTakeReading(void); + // internal function that takes a reading from one laser + void internalTakeLaserReading(ArLaser *laser, int laserNumber); + // internal function that prints the position + void internalPrintPos(ArPose encoderPoseTaken, ArPose goalPoseTaken, + ArTime timeTaken); + // internal function that logs the pose and conf + void internalPrintLaserPoseAndConf(ArLaser *laser, int laserNumber); + // internal packet for handling the loop packets + AREXPORT bool loopPacketHandler(ArRobotPacket *packet); + + + // what type of readings we are taking + bool myOldReadings; + // what type of readings we are taking + bool myNewReadings; + // if we're taking reflector values too + bool myUseReflectorValues; + std::list myTags; + std::list myInfos; + bool myWrote; + ArRobot *myRobot; + // note that this is now in the list of lasers, but this pointer is + // kept to denote the primary laser (so that it can always be called + // number 1) + ArLaser *myLaser; + bool myAddGoals; + ArJoyHandler *myJoyHandler; + ArRobotJoyHandler *myRobotJoyHandler; + std::string myFileName; + std::string myBaseDirectory; + FILE *myFile; + bool myFirstTaken; + + ArPose myLast; + double myLastVel; + double myDistDiff; + double myDegDiff; + ArSectors mySectors; + ArFunctorC myTaskCB; + int myScanNumber; + ArTime myStartTime; + bool myTakeReadingExplicit; + bool myAddGoalExplicit; + bool myAddGoalKeyboard; + bool myLastAddGoalKeyboard; + bool myLastJoyButton; + bool myLastRobotJoyButton; + bool myFirstGoalTaken; + int myNumGoal; + ArPose myLastGoalTakenPose; + ArTime myLastGoalTakenTime; + + void goalKeyCallback(void); + unsigned char myLastLoops; + + // the lasers all have this, so shouldn't need it anymore... + //bool myFlipped; + + bool myIncludeRawEncoderPose; + std::map *, + ArStrCaseCmpOp> myExtraLocationData; + + // holders for the extra lasers + std::list myLasers; + + ArFunctorC myGoalKeyCB; + ArRetFunctor1C myLoopPacketHandlerCB; +}; + +/// @deprecated +typedef ArLaserLogger ArSickLogger; + +#endif // ARLASERLOGGER_H diff --git a/Legacy/Aria/include/ArLaserReflectorDevice.h b/Legacy/Aria/include/ArLaserReflectorDevice.h new file mode 100644 index 0000000..08ccaf5 --- /dev/null +++ b/Legacy/Aria/include/ArLaserReflectorDevice.h @@ -0,0 +1,64 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARLASERREFLECTORDEVICE_H +#define ARLASERREFLECTORDEVICE_H + +#include "ariaTypedefs.h" +#include "ArRangeDevice.h" +#include "ArFunctor.h" + +class ArSick; +class ArRobot; + +/// A class for keeping track of laser reflectors that we see right now +/** + This class is for showing the laser reflectors in MobileEyes. + This requires that the range device you pass in uses the + 'extraInt' in the rawReadings ArSensorReading to note reflector + value and that anything greater than 0 is a reflector. +*/ +class ArLaserReflectorDevice : public ArRangeDevice +{ +public: + /// Constructor + AREXPORT ArLaserReflectorDevice(ArRangeDevice *laser, ArRobot *robot, + const char * name = "reflector"); + /// Destructor + AREXPORT virtual ~ArLaserReflectorDevice(); + /// Grabs the new readings from the robot and adds them to the buffers + AREXPORT void processReadings(void); + /// Specifically does nothing since it was done in the constructor + AREXPORT virtual void setRobot(ArRobot *robot); + /// Adds a reflector threshold to the task + AREXPORT void addToConfig(ArConfig *config, const char *section); +protected: + ArRangeDevice *myLaser; + int myReflectanceThreshold; + ArFunctorC myProcessCB; +}; + + +#endif // ARLASERREFLECTORDEVICE_H diff --git a/Legacy/Aria/include/ArLineFinder.h b/Legacy/Aria/include/ArLineFinder.h new file mode 100644 index 0000000..3b81fe7 --- /dev/null +++ b/Legacy/Aria/include/ArLineFinder.h @@ -0,0 +1,165 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARSICKLINEFINDER_H +#define ARSICKLINEFINDER_H + +#include "ariaTypedefs.h" +#include "ArRangeDevice.h" +#include "ariaUtil.h" +#include + +class ArLineFinderSegment; +class ArConfig; + +/** This class finds lines out of any range device with raw readings (lasers for instance) + @ingroup OptionalClasses + @ingroup UtilityClasses +*/ +class ArLineFinder +{ +public: + /// Constructor + AREXPORT ArLineFinder(ArRangeDevice *dev); + /// Destructor + AREXPORT virtual ~ArLineFinder(); + +#ifndef SWIG + /// Finds the lines and returns a pointer to ArLineFinder's map of them + /** @swigomit */ + AREXPORT std::map *getLines(void); + /// Finds the lines, but then returns a pointer to ArLineFinder's map of the points that AREN'T in lines + /** @swigomit */ + AREXPORT std::map *getNonLinePoints(void); +#endif + /// Finds the lines, then copies @b pointers to them them into a new set + AREXPORT std::set getLinesAsSet(); + /// Finds the lines, and then copies the points that AREN'T in the lines into a new set + AREXPORT std::set getNonLinePointsAsSet(); + + /// Gets the position the last lines were gotten at + ArPose getLinesTakenPose(void) { return myPoseTaken; } + /// Logs all the points and lines from the last getLines + AREXPORT void saveLast(void); + /// Gets the lines, then prints them + AREXPORT void getLinesAndSaveThem(void); + /// Whether to print verbose information about line decisions + void setVerbose(bool verbose) { myPrinting = verbose; } + /// Whether to print verbose information about line decisions + bool getVerbose(void) { return myPrinting; } + /// Sets some parameters for line creation + void setLineCreationParams(int minLineLen = 40, int minLinePoints = 2) + { myMakingMinLen = minLineLen; myMakingMinPoints = minLinePoints; } + /// Sets some parameters for line combining + void setLineCombiningParams(int angleTol = 30, int linesCloseEnough = 75) + { myCombiningAngleTol = angleTol; + myCombiningLinesCloseEnough = linesCloseEnough; } + /// Filter out lines smaller than this + void setLineFilteringParams(int minPointsInLine = 3, int minLineLength = 75) + { myFilteringMinPointsInLine = minPointsInLine; + myFilteringMinLineLength = minLineLength; } + /// Don't let lines happen that have points not close to it + void setLineValidParams(int maxDistFromLine = 30, + int maxAveDistFromLine = 20) + { myValidMaxDistFromLine = maxDistFromLine; + myValidMaxAveFromLine = maxAveDistFromLine; } + /// Sets the maximum distance between points that'll still be included in the same line + void setMaxDistBetweenPoints(int maxDistBetweenPoints = 0) + { myMaxDistBetweenPoints = maxDistBetweenPoints; } + AREXPORT void addToConfig(ArConfig *config, + const char *section); +protected: + // where the readings were taken + ArPose myPoseTaken; + // our points + std::map *myPoints; + std::map *myLines; + std::map *myNonLinePoints; + // fills up the myPoints variable from sick laser + AREXPORT void fillPointsFromLaser(void); + // fills up the myLines variable from the myPoints + AREXPORT void findLines(void); + // cleans the lines and puts them into myLines + AREXPORT bool combineLines(); + // takes two segments and sees if it can average them + AREXPORT ArLineFinderSegment *averageSegments(ArLineFinderSegment *line1, + ArLineFinderSegment *line2); + // removes lines that don't have enough points added in + AREXPORT void filterLines(); + + bool myFlippedFound; + bool myFlipped; + int myValidMaxDistFromLine; + int myValidMaxAveFromLine; + int myMakingMinLen; + int myMakingMinPoints; + int myCombiningAngleTol; + int myCombiningLinesCloseEnough; + int myFilteringMinPointsInLine; + int myFilteringMinLineLength; + int myMaxDistBetweenPoints; + double mySinMultiplier; + bool myPrinting; + ArRangeDevice *myRangeDevice; +}; + +/// Class for ArLineFinder to hold more info than an ArLineSegment +class ArLineFinderSegment : public ArLineSegment +{ +public: + ArLineFinderSegment() {} + ArLineFinderSegment(double x1, double y1, double x2, double y2, + int numPoints = 0, int startPoint = 0, int endPoint = 0) + { newEndPoints(x1, y1, x2, y2, numPoints, startPoint, endPoint); } + virtual ~ArLineFinderSegment() {} + void newEndPoints(double x1, double y1, double x2, double y2, + int numPoints = 0, int startPoint = 0, int endPoint = 0) + { + ArLineSegment::newEndPoints(x1, y1, x2, y2); + myLineAngle = ArMath::atan2(y2 - y1, x2 - x1); + myLength = ArMath::distanceBetween(x1, y1, x2, y2); + myNumPoints = numPoints; + myStartPoint = startPoint; + myEndPoint = endPoint; + myAveDistFromLine = 0; + } + double getLineAngle(void) { return myLineAngle; } + double getLength(void) { return myLength; } + int getNumPoints(void) { return myNumPoints; } + int getStartPoint(void) { return myStartPoint; } + int getEndPoint(void) { return myEndPoint; } + void setAveDistFromLine(double aveDistFromLine) + { myAveDistFromLine = aveDistFromLine; } + double getAveDistFromLine(void) { return myAveDistFromLine; } +protected: + double myLineAngle; + double myLength; + int myNumPoints; + int myStartPoint; + int myEndPoint; + double myAveDistFromLine; +}; + +#endif // ARSICKLINEFINDER_H diff --git a/Legacy/Aria/include/ArLog.h b/Legacy/Aria/include/ArLog.h new file mode 100644 index 0000000..953b689 --- /dev/null +++ b/Legacy/Aria/include/ArLog.h @@ -0,0 +1,166 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARLOG_H +#define ARLOG_H + +#ifndef WIN32 +#include +#endif +#include +#include "ariaTypedefs.h" +#include "ArMutex.h" +#include "ArFunctor.h" + +class ArConfig; + +/// Logging utility class +/** + ArLog is a utility class to log all messages from Aria to a choosen + destintation. Messages can be logged to stdout, stderr, a file, and + turned off completely. Logging by default is set to stdout. The level + of logging can be changed as well. Allowed levels are Terse, Normal, + and Verbose. By default the level is set to Normal. + + @ingroup ImportantClasses +*/ +class ArLog +{ +public: + + typedef enum { + StdOut, ///< Use stdout for logging + StdErr, ///< Use stderr for logging + File, ///< Use a file for logging + Colbert, ///< Use a Colbert stream for logging + None ///< Disable logging + } LogType; + typedef enum { + Terse, ///< Use terse logging + Normal, ///< Use normal logging + Verbose ///< Use verbose logging + } LogLevel; + +#ifndef SWIG + /** @brief Log a message, with formatting and variable number of arguments + * @swignote In Java and Python, this function only takes one + * string argument. Use Java or Python's native facities + * for constructing a formatted string, e.g. the % and + string + * operators in Python, and the methods of the Java String class. + */ + AREXPORT static void log(LogLevel level, const char *str, ...); +#endif + /// Log a message containing just a plain string + AREXPORT static void logPlain(LogLevel level, const char *str); + /// Initialize the logging utility with options + AREXPORT static bool init(LogType type, LogLevel level, + const char *fileName="", + bool logTime = false, bool alsoPrint = false, + bool printThisCall = true); + /// Close the logging utility + AREXPORT static void close(); + + /// Logs an error, adding the error and string the error mean at the + /// end of this message + AREXPORT static void logErrorFromOS(LogLevel level, const char *str, ...); + /// Logs an error, adding the error and string the error mean at the + /// end of this message + AREXPORT static void logErrorFromOSPlain(LogLevel level, const char *str); +#ifndef SWIG // these is internal we don't need to wrap it + /// Logs an error, adding the error and string the error mean at the + /// end of this message... internal version, don't use it + AREXPORT static void logErrorFromOSNoLock(LogLevel level, const char *str, ...); + /// Logs an error, adding the error and string the error mean at the + /// end of this message... internal version, dont' use it + AREXPORT static void logErrorFromOSPlainNoLock(LogLevel level, const char *str); + // Do not use this unless you know what you are doing... + /** @internal + * @swigomit */ + AREXPORT static void logNoLock(LogLevel level, const char *str, ...); +#endif + /// If possible (only in Linux right now) log the backtrace + AREXPORT static void logBacktrace(LogLevel level); + // We use this to print to a Colbert stream, if available + AREXPORT static void (* colbertPrint)(int i, const char *str); + + /// Use an ArConfig object to control ArLog's options + AREXPORT static void addToConfig(ArConfig *config); + +#ifndef ARINTERFACE + /// Init for aram behavior + AREXPORT static void aramInit(const char *prefix, + ArLog::LogLevel defaultLevel = ArLog::Normal, + double defaultSize = 10, + bool daemonized = false); +#endif + + /// Internal functor to be called when a log message is made (this shouldn't really be used) + AREXPORT static void setFunctor(ArFunctor1 *functor); + /// Internal function to force a lockup, only for debugging + AREXPORT static void internalForceLockup(void); +protected: + AREXPORT static bool processFile(void); +#ifndef ARINTERFACE + AREXPORT static bool aramProcessFile(void); + AREXPORT static void filledAramLog(void); +#endif + AREXPORT static void invokeFunctor(const char *message); + AREXPORT static void checkFileSize(void); + + static ArLog *ourLog; + static ArMutex ourMutex; + static LogType ourType; + static LogLevel ourLevel; + static bool ourLoggingTime; + static FILE *ourFP; + static int ourColbertStream; + static std::string ourFileName; + static bool ourAlsoPrint; + static int ourCharsLogged; + + static LogType ourConfigLogType; + static LogLevel ourConfigLogLevel; + static char ourConfigFileName[1024]; + static bool ourConfigLogTime; + static bool ourConfigAlsoPrint; + static ArGlobalRetFunctor ourConfigProcessFileCB; + +#ifndef ARINTERFACE + static char ourAramConfigLogLevel[1024]; + static double ourAramConfigLogSize; + static ArGlobalRetFunctor ourAramConfigProcessFileCB; + static bool ourUseAramBehavior; + static double ourAramLogSize; + static std::string ourAramPrefix; +#endif + + static bool ourAramDaemonized; + + static ArFunctor1 *ourFunctor; + +}; + + +#endif diff --git a/Legacy/Aria/include/ArLogFileConnection.h b/Legacy/Aria/include/ArLogFileConnection.h new file mode 100644 index 0000000..7f29e9e --- /dev/null +++ b/Legacy/Aria/include/ArLogFileConnection.h @@ -0,0 +1,93 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARLOGFILECONNECTION_H +#define ARLOGFILECONNECTION_H + +#include "ArDeviceConnection.h" +#include +#include + +#include "ariaTypedefs.h" + +/// For connecting through a log file +class ArLogFileConnection: public ArDeviceConnection +{ + public: + /// Constructor + AREXPORT ArLogFileConnection(); + /// Destructor also closes connection + AREXPORT virtual ~ArLogFileConnection(); + + /// Opens a connection to the given host and port + AREXPORT int open(const char * fname = NULL); + + AREXPORT void setLogFile(const char *fname = NULL); + AREXPORT virtual bool openSimple(void); + AREXPORT virtual int getStatus(void); + AREXPORT virtual bool close(void); + AREXPORT virtual int read(const char *data, unsigned int size, + unsigned int msWait = 0); + AREXPORT virtual int write(const char *data, unsigned int size); + AREXPORT virtual const char * getOpenMessage(int messageNumber); + AREXPORT virtual ArTime getTimeRead(int index); + AREXPORT virtual bool isTimeStamping(void); + + /// Gets the name of the host connected to + AREXPORT const char *getLogFile(void); + + /* This doens't exist in the C++ file so I'm commenting it out + /// Gets the initial pose of the robot + AREXPORT ArPose getLogPose(void); + */ + + /// Internal function used by open and openSimple + AREXPORT int internalOpen(void); + + enum Open { + OPEN_FILE_NOT_FOUND = 1, ///< Can't find the file + OPEN_NOT_A_LOG_FILE ///< Doesn't look like a log file + }; + + // robot parameters + ArPose myPose; + bool havePose; + char myName[100]; + char myType[20]; + char mySubtype[20]; + +protected: + void buildStrMap(void); + ArStrMap myStrMap; + + int myStatus; + int stopAfter; // temp here for returning one packet at a time + + const char *myLogFile; + FILE *myFD; // file descriptor + +}; + +#endif //ARLOGFILECONNECTION_H diff --git a/Legacy/Aria/include/ArMD5Calculator.h b/Legacy/Aria/include/ArMD5Calculator.h new file mode 100644 index 0000000..cfaed4a --- /dev/null +++ b/Legacy/Aria/include/ArMD5Calculator.h @@ -0,0 +1,150 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +/*! \file ArMD5Calculator.h + * \brief Contains the ArMD5Calculator class. + * \date 06/27/08 + * \author K. Cunningham +**/ +#ifndef ARMD5CALCULATOR_H +#define ARMD5CALCULATOR_H + +#include "ariaTypedefs.h" +#include "ariaUtil.h" + +#include "md5.h" + +/// Calculates the MD5 checksum when reading or writing a text file using ArFunctors. +/** + * ArMD5Calculator is a small helper class used to calculate MD5 checksums + * on text files. It contains a static method that will calculate the + * checksum of a given file, independently performing all I/O. + * + * The calculator also contains a functor that can be used to calculate + * a checksum interactively. For example, it can accumulate the checksum + * while a file is being written using a writeToFunctor method. If the + * optional second functor is specified, then it will be invoked after the + * checksum functor. + * + * @ingroup UtilityClasses +**/ +class ArMD5Calculator { + +public: + + enum { + DIGEST_LENGTH = 16, ///< Number of bytes in the checksum buffer + DISPLAY_LENGTH = (DIGEST_LENGTH * 2) + 1 ///< Number of characters needed to display the checksum + }; + + // --------------------------------------------------------------------------- + // Static Methods + // --------------------------------------------------------------------------- + + /// Converts the given checksum buffer to a displayable text string + /** + * @param digestBuf a pointer to the byte array that contains the checksum + * @param digestLength the length of the disgestBuf; should be DIGEST_LENGTH + * @param displayBuf a pointer to the output text buffer that will contain the + * displayable text string + * @param displayLength the length of the displayBuf; should be at least + * DISPLAY_LENGTH + **/ + AREXPORT static void toDisplay(const unsigned char *digestBuf, + size_t digestLength, + char *displayBuf, + size_t displayLength); + + /// Calculates the checksum for the specified file. + /** + * @param fileName the name of the file of which to calculate the checksum + * @param md5DigestBuffer a pointer to the output buffer in which to store + * the calculated checksum + * @param md5DigestBufferLen the length of the md5DigestBuffer; should be + * DIGEST_LENGTH + * @return bool true if the file was successfully opened and the checksum + * calculated; false, otherwise + **/ + AREXPORT static bool calculateChecksum(const char *fileName, + unsigned char *md5DigestBuffer, + size_t md5DigestBufferLen); + + // --------------------------------------------------------------------------- + // Instance Methods + // --------------------------------------------------------------------------- + + /// Creates a new calculator, with an optional functor. + /** + * @param secondFunctor the optional functor to be invoked on the current + * text string after its checksum has been calculated + **/ + AREXPORT ArMD5Calculator(ArFunctor1 *secondFunctor = NULL); + + /// Destructor + AREXPORT ~ArMD5Calculator(); + + + /// Resets the calculator so that a new checksum can be calculated + AREXPORT void reset(); + + /// Calculates the checksum for the given text line, and accumulates the results. + AREXPORT void append(const char *str); + + /// Returns a pointer to the internal buffer that accumulates the checksum results. + AREXPORT unsigned char *getDigest(); + + + /// Returns the internal functor used to calculate the checksum + /** + * If the calculator is being used interactively with writeToFunctor, then + * this is the functor to use. It calls append on each text line which + * accumulates the checksum and calls the second functor if necessary. + **/ + AREXPORT ArFunctor1 *getFunctor(); + + /// Returns the optional secondary functor to be called on each text line. + AREXPORT ArFunctor1 *getSecondFunctor(); + + /// Sets the optional secondary functor to be called on each text line. + AREXPORT void setSecondFunctor(ArFunctor1 *secondFunctor); + +private: + + /// Functor that accumulates the checksum + ArFunctor1C myFunctor; + /// Optional secondary functor to be invoked on each text line + ArFunctor1 *mySecondFunctor; + /// State of the md5 library + md5_state_t myState; + /// Buffer in which to store the md5 results + md5_byte_t myDigest[DIGEST_LENGTH]; + + /// Whether the calculator is finished, i.e. the md5_finish method has been called. + bool myIsFinished; + +}; // end class ArMD5Calculator + +#endif // ARMD5CALCULATOR_H + diff --git a/Legacy/Aria/include/ArMTXIO.h b/Legacy/Aria/include/ArMTXIO.h new file mode 100644 index 0000000..1b9e1bc --- /dev/null +++ b/Legacy/Aria/include/ArMTXIO.h @@ -0,0 +1,313 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARMTXIO_H +#define ARMTXIO_H + + +#include "ariaTypedefs.h" +#include "ArRobot.h" + +/** @brief Interface to digital and analog I/O and switched power outputs on MTX + * core (used in Pioneer LX and other MTX-based robots). + + On Linux this class uses the mtx driver to interface with the + MTX digital and analog IO, and control switched power outputs. + + The mtx driver module must be loaded for this interface to work. + + The mtx interface (/dev/mtx) is opened automatically + in the ArMTXIO constructor. If successful, isEnabled() will then return true. + + The MTX IO is organized as two sets of 8-bit "banks" of inputs, and two 8-bit + "banks" of outputs. + + To read the state input, use getDigitalIOInputMon1() and + getDigitalIOInputMon2(), or getDigitalBankInputs() with bank index 0 or 1. + + To set state of output, use setDigitalOutputControl1() and + setDigitalOutputControl2(), or setDigitalBankOutputs() with bank index 2 or + 3. + + Multile ArMTXIO objects may be instatiated; a shared may be + locked and unlocked by calling lock() and unlock(). + + @ingroup OptionalClasses + @ingroup DeviceClasses + @ingroup MTX + + @linuxonly + +*/ + +class ArMTXIO +{ +public: + + enum Direction + { + DIGITAL_INPUT, + DIGITAL_OUTPUT, + INVALID + }; + + /// Constructor + AREXPORT ArMTXIO(const char * dev = "/dev/mtx"); + /// Destructor + AREXPORT virtual ~ArMTXIO(void); + + /// tries to close the device. Returns false if operation failed + AREXPORT bool closeIO(void); + + /// returns true if the device is opened and operational + bool isEnabled(void) { return myEnabled; } + + /// returns true if analog values are supported + AREXPORT bool isAnalogSupported(void) { return myAnalogEnabled; } + + /// @note not yet implemented. + bool getAnalogValue(int port, double *val) { return true; } + /// @note not yet implemented + bool getAnalogValueRaw(int port, int *val) { return true; } + + /// Get/set value of digital IO banks (see class description above) + /// Banks are 0-indexed. + /// @{ + AREXPORT Direction getDigitalBankDirection(int bank); + AREXPORT bool setDigitalBankOutputs(int bank, unsigned char val); + AREXPORT bool getDigitalBankInputs(int bank, unsigned char *val); + AREXPORT bool getDigitalBankOutputs(int bank, unsigned char *val); + /// @} + + /// Set one bit of an output bank. @a bank and @a bit are 0-indexed. + bool setDigitalOutputBit(int bank, int bit) { + unsigned char val; + if(!getDigitalBankOutputs(bank, &val)) + return false; + return setDigitalBankOutputs( bank, val | (1 << bit) ); + } + + /// Get one bit of an input bank. @a bank and @a bit are 0-indexed. + bool getDigitalInputBit(int bank, int bit) { + unsigned char val = 0; + getDigitalBankInputs(bank, &val); + return val & (1 << bit); + } + + /// get/set value of power output controls (see robot manual for information + /// on what components and user outputs are controlled). Banks are 0-indexed. + /// @{ + AREXPORT bool setPeripheralPowerBankOutputs(int bank, unsigned char val); + AREXPORT bool getPeripheralPowerBankOutputs(int bank, unsigned char *val); + /// @} + + /// Set one power output. @a bank and @a bit are 0-indexed. + bool setPowerOutput(int bank, int bit, bool on) { + unsigned char val = 0; + if(!getPeripheralPowerBankOutputs(bank, &val)) + return false; + if (on) + return setPeripheralPowerBankOutputs(bank, val & (1 << bit)); + else + return setPeripheralPowerBankOutputs(bank, val ^ (1 << bit)); + } + + /// Lock global (shared) mutex for all ArMTXIO instances. + /// This allows multiple access to MTX IO (through multiple ArMTXIO objects). + AREXPORT int lock(void){ return(ourMutex.lock()); } + /// Unlock global (shared) mutex for all ArMTXIO instances. + /// This allows multiple access to MTX IO (through multiple ArMTXIO objects). + AREXPORT int unlock(void){ return(ourMutex.unlock()); } + + /// Try to lock without blocking (see ArMutex::tryLock()) + AREXPORT int tryLock() {return(ourMutex.tryLock());} + + /// gets the Firmware Revision + AREXPORT unsigned char getFirmwareRevision() + { return myFirmwareRevision; } + + /// gets the Firmware Version + AREXPORT unsigned char getFirmwareVersion() + { return myFirmwareVersion; } + + /// gets the Compatibility Code + AREXPORT unsigned char getCompatibilityCode() + { return myCompatibilityCode; } + + /// gets the MTX FPGA Type + AREXPORT unsigned char getFPGAType() + { return myFPGAType; } + + /// gets the values of digital input/output monitoring registers 1 & 2 + /// @{ + AREXPORT bool getDigitalIOInputMon1(unsigned char *val); + AREXPORT bool getDigitalIOInputMon2(unsigned char *val); + AREXPORT bool getDigitalIOOutputMon1(unsigned char *val); + AREXPORT bool getDigitalIOOutputMon2(unsigned char *val); + /// @} + + /// get the Light Pole IO Output Control Register + AREXPORT bool getLightPole(unsigned char *val); + /// sets the Light Pole IO Output Control Register + AREXPORT bool setLightPole(unsigned char *val); + + /// @internal + AREXPORT bool getLPCTimeUSec(ArTypes::UByte4 *timeUSec); + + /// @internal + AREXPORT ArRetFunctor1 *getLPCTimeUSecCB(void) + { return &myLPCTimeUSecCB; } + + /// gets/sets the Semaphore Registers + /// @internal + //@{ + AREXPORT bool setSemaphore1(unsigned char *val); + AREXPORT bool getSemaphore1(unsigned char *val); + AREXPORT bool setSemaphore2(unsigned char *val); + AREXPORT bool getSemaphore2(unsigned char *val); + AREXPORT bool setSemaphore3(unsigned char *val); + AREXPORT bool getSemaphore3(unsigned char *val); + AREXPORT bool setSemaphore4(unsigned char *val); + AREXPORT bool getSemaphore4(unsigned char *val); + //@} + + /// gets the bumper Input Monitoring Reg + /// @internal + AREXPORT bool getBumperInput(unsigned char *val); + + /// gets the Power Status Register + /// @internal + AREXPORT bool getPowerStatus1(unsigned char *val); + /// gets the Power Status Register 2 + /// @internal + AREXPORT bool getPowerStatus2(unsigned char *val); + + /// gets the LIDAR Safety Status Register + AREXPORT bool getLIDARSafety(unsigned char *val); + + /// gets the ESTOP status Registers + /// @internal + //@{ + AREXPORT bool getESTOPStatus1(unsigned char *val); + AREXPORT bool getESTOPStatus2(unsigned char *val); + AREXPORT bool getESTOPStatus3(unsigned char *val); + AREXPORT bool getESTOPStatus4(unsigned char *val); + /// Compares the high nibble of this byte against the passed in val, returns true if it matches + AREXPORT bool compareESTOPStatus4HighNibbleAgainst(int val); + //@} + + /// gets/sets Digital IO Output Control Registers 1 & 2 + //@{ + AREXPORT bool getDigitalOutputControl1(unsigned char *val); + AREXPORT bool setDigitalOutputControl1(unsigned char *val); + AREXPORT bool getDigitalOutputControl2(unsigned char *val); + AREXPORT bool setDigitalOutputControl2(unsigned char *val); + //@} + + /// gets/sets the Peripheral Power Control Regs 1 & 2 + /// These control power to core and robot components, and to user/auxilliary + /// power outputs. Refer to robot manual for information on which components + /// and outputs are controlled by which bits in the peripheral power bitmasks. + //@{ + AREXPORT bool getPeripheralPower1(unsigned char *val); + AREXPORT bool setPeripheralPower1(unsigned char *val); + AREXPORT bool getPeripheralPower2(unsigned char *val); + AREXPORT bool setPeripheralPower2(unsigned char *val); + AREXPORT bool getPeripheralPower3(unsigned char *val); + AREXPORT bool setPeripheralPower3(unsigned char *val); + //@} + + /// gets the motion power status + AREXPORT bool getMotionPowerStatus(unsigned char *val); + + /// gets/sets the LIDAR Control Reg + /// @internal + //@{ + AREXPORT bool getLIDARControl(unsigned char *val); + AREXPORT bool setLIDARControl(unsigned char *val); + //@} + + + /// gets analog Block 1 & 2 + //@{ + AREXPORT bool getAnalogIOBlock1(int analog, unsigned short *val); + AREXPORT bool getAnalogIOBlock2(int analog, unsigned short *val); + + AREXPORT bool setAnalogIOBlock2(int analog, unsigned short *val); + //@} + + /// This returns a conversion of the bits to a decimal value, + /// currently assumed to be in the 0-5V range + /// @internal + AREXPORT bool getAnalogValue(double *val); + + /// @internal + AREXPORT bool getAnalogValueRaw(int *val); + +protected: + + bool getLPCTimer0(unsigned char *val); + bool getLPCTimer1(unsigned char *val); + bool getLPCTimer2(unsigned char *val); + bool getLPCTimer3(unsigned char *val); + + + static ArMutex ourMutex; + int myFD; + + bool myEnabled; + bool myAnalogEnabled; + + unsigned char myFirmwareRevision; + unsigned char myFirmwareVersion; + unsigned char myCompatibilityCode; + unsigned char myFPGAType; + + struct MTX_IOREQ{ + unsigned short myReg; + unsigned short mySize; + union { + unsigned int myVal; + unsigned int myVal32; + unsigned short myVal16; + unsigned char myVal8; + //unsigned char myVal128[16]; + } myData; + }; + + int myNumBanks; + + unsigned char myDigitalBank1; + unsigned char myDigitalBank2; + unsigned char myDigitalBank3; + unsigned char myDigitalBank4; + + ArRetFunctorC myDisconnectCB; + ArRetFunctor1C myLPCTimeUSecCB; +}; + +//#endif // SWIG + +#endif // ARMTXIO_H diff --git a/Legacy/Aria/include/ArMap.h b/Legacy/Aria/include/ArMap.h new file mode 100644 index 0000000..db83900 --- /dev/null +++ b/Legacy/Aria/include/ArMap.h @@ -0,0 +1,655 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +/* + * + * + * + * Aria maps are implemented by a collection of classes and interfaces. The + * most important is the ArMapInterface, which is defined in ArMapInterface.h + * and specifies the methods that all Aria maps must provide. + * + * This file contains the top-level concrete implementation of the + * ArMapInterface. ArMap is basically the map that is used by the robot + * to navigate its environment. In addition to implementing the methods of + * ArMapInterface, ArMap also provides a means of hooking into the Aria config. + * When the map file name is specified in the Aria config and is changed during + * runtime, ArMap loads the new file and notifies all listeners that the map + * has been changed. + * + * In order to accomplish this, ArMap has been implemented using the Proxy + * design pattern (refer to "Design Patterns", Gamma et al, 1995). The + * participants are as follows: + * + * - Subject: ArMapInterface. The common interface for both the RealSubject + * and the Proxy. It is defined in ArMapInterface.h and is actually + * the combination of several smaller interfaces: ArMapScanInterface, + * ArMapObjectsInterface, ArMapInfoInterface, and ArMapSupplementInterface. + * + * - RealSubject: ArMapSimple. The real object that the Proxy represents. + * It is defined in ArMapComponents.h, and is implemented by a set of + * helper classes that are also defined in that header file. + * + * - Proxy: ArMap. Creates and controls access to the RealSubject. ArMap + * actually contains references to two ArMapSimple objects. One is + * permanent and is the map object that is used by the robot. The other + * is transient and is the map object that is currently being read from + * a file following an Aria configuration update. If the file is + * successfully read, then the loading ArMapSimple object is copied to + * the main permanent one and mapChanged notifications are sent to + * registered listeners. + * + * The following "diagram" illustrates the basic hierarchy: + * + *
  
+ *        ArMapInterface                          , Defined in ArMapInterface.h
+ *        ^ (extends)  ^ 
+ *        |            |
+ *        |            |
+ *     ArMap +-------> ArMapSimple * +-------> ArMapScan *
+ *                 (contains)        |
+ *                                   +-------> ArMapObjects *
+ *                                   |
+ *                                   +-------> ArMapInfo *
+ *                                   |
+ *                                   +-------> ArMapSupplement *
+ *
+ *                                              * : Defined in ArMapComponents.h
+ * 
+ * + * + * This header file originally also contained the definition of ArMapObject. + * That class has been moved into its own header file (ArMapObject.h). + * + * + * Maintenance Note #1: In this case, the use of the Proxy design pattern implies + * that modifying the ArMap external interface requires multiple changes: + * First, the ArMapInterface (or sub-interface) must be updated. Then the ArMap + * and ArMapSimple classes must be modified. Depending on the change, one of the + * helper map components may also need to be modified. It is expected that + * such changes to the interface will be infrequent. + * + * @see ArMapInfo + * @see ArMapObject + * @see ArMapObjects + * @see ArMapScan + * @see ArMapSupplement +**/ +#ifndef ARMAP_H +#define ARMAP_H + +#include "ariaTypedefs.h" +#include "ariaUtil.h" + +#include "ArMapComponents.h" +#include "ArMapInterface.h" +#include "ArMapUtils.h" + +#include "ArFunctor.h" +#include "ArArgumentBuilder.h" +#include "ArMutex.h" + +#include + +class ArFileParser; + +/// A map of a two-dimensional space the robot can navigate within, and which can be updated via the Aria config +/** +* ArMap contains data that represents the operating space of the robot, and can +* be used for space searching, localizing, navigating etc. MobileRobots' ARNL +* and SONARNL localization and navigation libraries use ArMap objects. +* ArMap also provides methods to read and write the map from and to a file, +* along with a mechanism for setting the map file via the global Aria config. +* +* Types of data stored in a map include sensable obstacles (e.g. walls and +* furniture in a room) that are represented either as a collection of data +* points or lines. The data points are similar to a raster or bit map and +* are useful for high resolution sensors like lasers. The lines create a +* vector map that is useful for low resolution sensors like sonar. For +* advanced applications, the sensable obstacle data can be categorized according +* to the type of scan or sensor; see ArMapScanInterface for more information. +* +* In addition to the obstacle data, the Aria map may contain goals, forbidden +* areas, and other points and regions of interest (a.k.a. "map objects"). +* Advanced applications can extend the set of predefined map object types. +* See @ref MapObjects for more information. +* +* If the application needs to be aware of any changes that are made to the +* Aria map at runtime, then it should install "mapChanged" callbacks on the map. +* If the map file is re-read while the robot is running, then the callbacks +* are automatically invoked. If the application makes other changes to the +* map by calling any of the set methods, then it should call mapChanged() when +* it is finished. +* +* See @ref MapFileFormat for the exact format of the actual .map file. +* +* @section MapThreading Thread issuses, and changing the map +* +* Different threads will need to access the same map data (for example ARNL, +* ArForbiddenRangeDevice, networking). However, the ArMap class is not +* inherently thread-safe. You must call lock() and unlock() methods, before +* and after any access to the map data (e.g. calls to getMapObjects(), +* getPoints(), setMapObjects(), setPoints()). +* +* If you are going to use setMapObjects(), setPoints(), setLines(), or +* setMapInfo(), then you should lock() the map beforehand, call the methods, +* then call mapChanged() to invoke the callbacks, and then finally +* unlock() the map when done. Note that mapChanged() will only invoke +* the callbacks if the data has actually changed. +* +* However, there is an exception: the readFile() and writeFile() +* methods @b do automatically lock the map while they read and write. +* +* @section MapObjects Map Objects +* +* In addition to lines and points, maps may contain "map objects", points +* or regions in space that have special meaning. +* +* Certain types of objects are predefined for all maps. These include +* Goal, GoalWithHeading, Dock, ForbiddenLine, ForbiddenArea, and RobotHome. +* +* - Goal and GoalWithHeading are basically named ArPoses, the difference being +* that the "th" (heading) value is only valid for GoalWithHeading. +* - Dock is an ArPose that must always have a heading. +* - ForbiddenLine is a boundary line, and ForbiddenArea is a rectangular +* "sector". The extents of these objects are given as a pair of +* poses, a "from" point and a "to" point. +* - RobotHome may be either an ArPose or a rectangular sector. +* +* Rectangular objects may also have an associated angle of rotation, which is +* stored in the object pose theta value (ArMapObject::getPose().getTh()). +* The actual global coordinates of the rectangle must be calculated +* using this angle and its "from-to" values. You can get a list of the 4 +* ArLineSegment objects that comprise the rectangle's edges using +* ArMapObject::getFromToSegments(). If you want to do your own calculations, +* see ArMapObject::ArMapObject(). +* +* You can get a pointer to the current list of map objects with getMapObjects(), +* and directly modify the list. You can also replace the current list of +* map objects with a new one by calling setMapObjects(); this will destroy +* the old list of map objects. Call mapChanged() to notify other components +* that the map has changed. +* +* In addition to the standard map object types, is also possible to define +* custom types of map objects using the "MapInfo" metadata section of the +* map file. For example, if you wished to program some special behavior that +* would only occur upon reaching certain goals, you could define a new +* "SpecialGoal" type in the map file, and check for it in your program. +* See @ref MapFileFormat for the syntax for defining new object types in the +* map file. Custom types will appear in Mapper3 and MobilePlanner in +* drop-down menus, and instances of the custom types will be displayed in +* MobileEyes. +* +* Important Note: if a map defines special GoalType or DockType items, +* then it must define all possible goal or dock types, including the +* default "Goal", "GoalWithHeading", and "Dock" types if you want those +* types to remain available. +* + * @ingroup OptionalClasses +*/ +class ArMap : public ArMapInterface +{ + +public: + + /// Constructor + /** + * @param baseDirectory the name of the directory in which to search for map + * files that are not fully qualified + * @param addToGlobalConfig a bool set to true if the map file name parameter + * should be added to the global config, Aria::getConfig(); false, otherwise + * @param configSection the char * name of the config section to which to + * add the map file name parameter name; applicable only if addToGlobalConfig + * is true + * @param configParam the char * name of the parameter to be added to the + * specified configSection; applicable only if addToGlobalConfig is true + * @param configDesc the char * description of the configParam; applicable + * only if addToGlobalConfig is true + * @param ignoreEmptyFileName a bool set to true if an empty file name is a + * valid config parameter value; set to false if a failure should be reported + * when the file name is empty; applicable only if addToGlobalConfig is true + * @param priority the ArPriority::Priority of the config parameter; + * applicable only if addToGlobalConfig is true + * @param tempDirectory the name of the directory in which to write temporary + * files when saving a map; if NULL, then the map file is written directly. + * Note that using a temp file reduces the risk that the map will be corrupted + * if the application crashes. + * @param configProcessFilePriority priority at which ArMap's configuration + * parameters should be processed by ArConfig. + **/ + AREXPORT ArMap(const char *baseDirectory = "./", + bool addToGlobalConfig = true, + const char *configSection = "Files", + const char *configParam = "Map", + const char *configDesc = + "Map of the environment that the robot uses for navigation", + bool ignoreEmptyFileName = true, + ArPriority::Priority priority = ArPriority::IMPORTANT, + const char *tempDirectory = NULL, + int configProcessFilePriority = 100); + + /// Copy constructor + AREXPORT ArMap(const ArMap &other); + + /// Assignment operator + AREXPORT ArMap &operator=(const ArMap &other); + + /// Destructor + AREXPORT virtual ~ArMap(void); + + + // =========================================================================== + // ArMapInterface Methods + // =========================================================================== + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Scan Types Methods + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + AREXPORT virtual std::list getScanTypes() const; + + AREXPORT virtual bool setScanTypes(const std::list &scanTypeList); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Locking / Mutex Methods + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + AREXPORT virtual int lock(); + + AREXPORT virtual int tryLock(); + + AREXPORT virtual int unlock(); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // ArMapScanInterface + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + AREXPORT virtual const char *getDisplayString + (const char *scanType = ARMAP_DEFAULT_SCAN_TYPE); + + AREXPORT virtual std::vector *getPoints + (const char *scanType = ARMAP_DEFAULT_SCAN_TYPE); + + AREXPORT virtual ArPose getMinPose(const char *scanType = ARMAP_DEFAULT_SCAN_TYPE); + AREXPORT virtual ArPose getMaxPose(const char *scanType = ARMAP_DEFAULT_SCAN_TYPE); + AREXPORT virtual int getNumPoints(const char *scanType = ARMAP_DEFAULT_SCAN_TYPE); + AREXPORT virtual bool isSortedPoints(const char *scanType = ARMAP_DEFAULT_SCAN_TYPE) const; + + AREXPORT virtual void setPoints(const std::vector *points, + const char *scanType = ARMAP_DEFAULT_SCAN_TYPE, + bool isSortedPoints = false, + ArMapChangeDetails *changeDetails = NULL); + + AREXPORT virtual std::vector *getLines + (const char *scanType = ARMAP_DEFAULT_SCAN_TYPE); + + AREXPORT virtual ArPose getLineMinPose(const char *scanType = ARMAP_DEFAULT_SCAN_TYPE); + AREXPORT virtual ArPose getLineMaxPose(const char *scanType = ARMAP_DEFAULT_SCAN_TYPE); + AREXPORT virtual int getNumLines(const char *scanType = ARMAP_DEFAULT_SCAN_TYPE); + AREXPORT virtual bool isSortedLines(const char *scanType = ARMAP_DEFAULT_SCAN_TYPE) const; + + AREXPORT virtual void setLines(const std::vector *lines, + const char *scanType = ARMAP_DEFAULT_SCAN_TYPE, + bool isSortedLines = false, + ArMapChangeDetails *changeDetails = NULL); + + AREXPORT virtual int getResolution(const char *scanType = ARMAP_DEFAULT_SCAN_TYPE); + + AREXPORT virtual void setResolution(int resolution, + const char *scanType = ARMAP_DEFAULT_SCAN_TYPE, + ArMapChangeDetails *changeDetails = NULL); + + AREXPORT virtual void writeScanToFunctor + (ArFunctor1 *functor, + const char *endOfLineChars, + const char *scanType = ARMAP_DEFAULT_SCAN_TYPE); + + AREXPORT virtual void writePointsToFunctor + (ArFunctor2 *> *functor, + const char *scanType = ARMAP_DEFAULT_SCAN_TYPE, + ArFunctor1 *keywordFunctor = NULL); + + AREXPORT virtual void writeLinesToFunctor + (ArFunctor2 *> *functor, + const char *scanType = ARMAP_DEFAULT_SCAN_TYPE, + ArFunctor1 *keywordFunctor = NULL); + + AREXPORT virtual bool addToFileParser(ArFileParser *fileParser); + + AREXPORT virtual bool remFromFileParser(ArFileParser *fileParser); + + + AREXPORT virtual bool readDataPoint( char *line); + + AREXPORT virtual bool readLineSegment( char *line); + + /** Public for ArQClientMapProducer **/ + + AREXPORT virtual void loadDataPoint(double x, double y); + AREXPORT virtual void loadLineSegment(double x1, double y1, double x2, double y2); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // ArMapObjectsInterface + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + AREXPORT virtual ArMapObject *findFirstMapObject(const char *name, + const char *type, + bool isIncludeWithHeading = false); + + AREXPORT virtual ArMapObject *findMapObject(const char *name, + const char *type = NULL, + bool isIncludeWithHeading = false); + + AREXPORT virtual std::list findMapObjectsOfType + (const char *type, + bool isIncludeWithHeading = false); + + AREXPORT virtual std::list *getMapObjects(void); + + AREXPORT virtual void setMapObjects(const std::list *mapObjects, + bool isSortedObjects = false, + ArMapChangeDetails *changeDetails = NULL); + + AREXPORT virtual void writeObjectListToFunctor + (ArFunctor1 *functor, + const char *endOfLineChars); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // ArMapInfoInterface + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + AREXPORT virtual std::list *getInfo(const char *infoName); + + AREXPORT virtual std::list *getInfo(int infoType); + + AREXPORT virtual std::list *getMapInfo(void); + + AREXPORT virtual int getInfoCount() const; + + AREXPORT virtual std::list getInfoNames() const; + + AREXPORT virtual bool setInfo(const char *infoName, + const std::list *infoList, + ArMapChangeDetails *changeDetails = NULL); + + AREXPORT virtual bool setInfo(int infoType, + const std::list *infoList, + ArMapChangeDetails *changeDetails = NULL); + + AREXPORT virtual bool setMapInfo(const std::list *mapInfo, + ArMapChangeDetails *changeDetails = NULL); + + AREXPORT virtual const char *getInfoName(int infoType); + + AREXPORT virtual void writeInfoToFunctor(ArFunctor1 *functor, + const char *endOfLineChars); + + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // ArMapSupplementInterface + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + AREXPORT virtual bool hasOriginLatLongAlt(); + AREXPORT virtual ArPose getOriginLatLong(); + AREXPORT virtual double getOriginAltitude(); + + AREXPORT virtual void setOriginLatLongAlt + (bool hasOriginLatLong, + const ArPose &originLatLong, + double altitude, + ArMapChangeDetails *changeDetails = NULL); + + + AREXPORT virtual void writeSupplementToFunctor(ArFunctor1 *functor, + const char *endOfLineChars); + + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Remaining ArMapInterface Methods + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + AREXPORT virtual void clear(); + + AREXPORT virtual bool set(ArMapInterface *other); + + AREXPORT virtual ArMapInterface *clone(); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Map Changed / Callback Methods + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + AREXPORT virtual void mapChanged(void); + + AREXPORT virtual void addMapChangedCB(ArFunctor *functor, int position = 50); + + AREXPORT virtual void remMapChangedCB(ArFunctor *functor); + + AREXPORT virtual void addPreMapChangedCB(ArFunctor *functor, + int position = 50); + + AREXPORT virtual void remPreMapChangedCB(ArFunctor *functor); + + AREXPORT virtual void setMapChangedLogLevel(ArLog::LogLevel level); + + AREXPORT virtual ArLog::LogLevel getMapChangedLogLevel(void); + + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Persistence + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + AREXPORT virtual void writeToFunctor(ArFunctor1 *functor, + const char *endOfLineChars); + + AREXPORT virtual void writeObjectsToFunctor(ArFunctor1 *functor, + const char *endOfLineChars, + bool isOverrideAsSingleScan = false, + const char *maxCategory = NULL); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // File I/O Methods + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + AREXPORT virtual void addPreWriteFileCB(ArFunctor *functor, + ArListPos::Pos position = ArListPos::LAST); + AREXPORT virtual void remPreWriteFileCB(ArFunctor *functor); + + AREXPORT virtual void addPostWriteFileCB(ArFunctor *functor, + ArListPos::Pos position = ArListPos::LAST); + AREXPORT virtual void remPostWriteFileCB(ArFunctor *functor); + + /// Forces the map to reload if the config is changed/reloaded + AREXPORT void forceMapLoadOnConfigProcessFile(void) + { myForceMapLoad = true; } + +#ifndef SWIG + /** @swigomit (can't write to arguments yet) */ + AREXPORT virtual bool readFile(const char *fileName, + char *errorBuffer, + size_t errorBufferLen, + unsigned char *md5DigestBuffer, + size_t md5DigestBufferLen); + AREXPORT bool readFile(const char *fileName, char *errorBuffer, size_t errorBufferLen); +#endif + AREXPORT bool readFile(const char *fileName); + +#ifndef SWIG + /** @swigomit (can't write to arguments yet) */ + AREXPORT virtual bool writeFile(const char *fileName, + bool internalCall, + unsigned char *md5DigestBuffer = NULL, + size_t md5DigestBufferLen = 0, + time_t fileTimestamp = -1); +#endif + + virtual bool writeFile(const char *fileName) + { + return writeFile(fileName, false, NULL, 0, -1); + } + +#ifndef SWIG + /// @swigomit + AREXPORT virtual struct stat getReadFileStat() const; +#endif + + AREXPORT virtual bool getMapId(ArMapId *mapIdOut, + bool isInternalCall = false); + + AREXPORT virtual bool calculateChecksum(unsigned char *md5DigestBuffer, + size_t md5DigestBufferLen); + + + AREXPORT virtual const char *getBaseDirectory(void) const; + + AREXPORT virtual void setBaseDirectory(const char *baseDirectory); + + AREXPORT virtual const char *getTempDirectory(void) const; + + AREXPORT virtual void setTempDirectory(const char *tempDirectory); + + + AREXPORT virtual std::string createRealFileName(const char *fileName); + + AREXPORT virtual const char *getFileName(void) const; + + AREXPORT virtual void setSourceFileName(const char *sourceName, + const char *fileName, + bool isInternalCall = false); + + AREXPORT virtual bool refresh(); + + AREXPORT virtual void setIgnoreEmptyFileName(bool ignore); + + AREXPORT virtual bool getIgnoreEmptyFileName(void); + + AREXPORT virtual void setIgnoreCase(bool ignoreCase = false); + + AREXPORT virtual bool getIgnoreCase(void); + + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Inactive Section + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + AREXPORT virtual ArMapInfoInterface *getInactiveInfo(); + + AREXPORT virtual ArMapObjectsInterface *getInactiveObjects(); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Child Objects Section + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + AREXPORT virtual ArMapObjectsInterface *getChildObjects(); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Miscellaneous + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + AREXPORT virtual ArArgumentBuilder *findMapObjectParams + (const char *mapObjectName); + + AREXPORT virtual bool setMapObjectParams(const char *mapObjectName, + ArArgumentBuilder *params, + ArMapChangeDetails *changeDetails = NULL); + + + AREXPORT virtual std::list *getRemainder(); + + AREXPORT virtual void setQuiet(bool isQuiet); + + AREXPORT virtual bool parseLine(char *line); + + AREXPORT virtual void parsingComplete(void); + + AREXPORT virtual bool isLoadingDataStarted(); + + AREXPORT virtual bool isLoadingLinesAndDataStarted(); + + // =========================================================================== + // End of ArMapInterface + // =========================================================================== + + + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // ArMap Methods + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + /// Reads a map and changes the config map name to that file + AREXPORT bool readFileAndChangeConfig(const char *fileName); + /// Changes the config map name + AREXPORT void changeConfigMapName(const char *fileName); + + + + protected: + + /// Processes changes to the Aria configuration; loads a new map file if necessary + bool processFile(char *errorBuffer, size_t errorBufferLen); + + protected: + + // Lock to protect data during file I/O operations + ArMutex myMutex; + + /// File path in which to find the map file name + std::string myBaseDirectory; + /// Name of the map file + std::string myFileName; + /// File statistics for the map file + struct stat myReadFileStat; + + /// Name of the Aria config parameter that specifies the map file name + std::string myConfigParam; + /// Whether to ignore (not process) an empty Aria config parameter + bool myIgnoreEmptyFileName; + /// Whether to ignore case when comparing map file names + bool myIgnoreCase; + + /// Whether the Aria config has already been processed at least once + bool myConfigProcessedBefore; + /// The name of the map file specified in the Aria config parameter + char myConfigMapName[MAX_MAP_NAME_LENGTH]; + /// Whether we want to force loading the map for some reasing + bool myForceMapLoad; + + /// The current map used by the robot + ArMapSimple * const myCurrentMap; + /// The map that is being loaded, i.e. read from a file; will be copied to the current map if successful + ArMapSimple * myLoadingMap; + + /// Whether to run in "quiet mode", i.e. logging less information + bool myIsQuiet; + + /// Callback that processes changes to the Aria config. + ArRetFunctor2C myProcessFileCB; + +}; // end class ArMap + + +#endif // ARMAP_H + + diff --git a/Legacy/Aria/include/ArMapComponents.h b/Legacy/Aria/include/ArMapComponents.h new file mode 100644 index 0000000..6908e69 --- /dev/null +++ b/Legacy/Aria/include/ArMapComponents.h @@ -0,0 +1,1376 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +/*! \file ArMapComponents.h + * \brief Contains the set of component classes used to implement Aria maps. + * \date 06/27/08 + * \author K. Cunningham + * + * The ArMap class (defined in ArMap.h) is composed of several smaller + * classes that are defined in this header file. These include: + * + * - ArMapScan: An implementation of the ArMapScanInterface. This + * contains all of the data related to the sensed obstacles (i.e. + * data points and lines). An instance of this class is created + * for each scan type that is defined in the map. + * + * - ArMapObjects: An implementation of the ArMapObjectsInterface. + * This stores all of the map objects for the Aria map. + * + * - ArMapInfo: An implementation of the ArMapInfoInterface. This + * contains all of the info (ArArgumentBuilder) tags defined for + * the map, including MapInfo, TaskInfo, and RouteInfo. + * + * - ArMapSupplement: An implementation of the ArMapSupplementInterface. + * This is a repository for all of the extra data that does not fit + * into any of the above categories. + * + * - ArMapSimple: The RealSubject of the ArMap Proxy. This implements + * the ArMapInterface and is an aggregate of all of the above map + * components. + * + * The following "diagram" illustrates the basic hierarchy: + * + *
  
+ *
+ *          ________ArMapSupplementInterface________
+ *         ^                                        ^
+ *         |   ________ArMapInfoInterface________   |
+ *         |   ^                                ^   |
+ *         |   |   __ArMapObjectsInterface___   |   |
+ *         |   |   ^                        ^   |   |
+ *         |   |   |   ArMapScanInterface   |   |   |
+ *         |   |   |   ^                ^   |   |   |
+ *         |   |   |   |                |   |   |   |
+ *        ArMapInterface                |   |   |   |  
+ *        ^ (extends)                   |   |   |   | (extends)
+ *        |                             |   |   |   |
+ *        |                             |   |   |   |
+ *     ArMapSimple +----------> ArMapScan   |   |   |
+ *                 | (contains)             |   |   |
+ *                 +-----------> ArMapObjects   |   |
+ *                 |                            |   |
+ *                 +------------------> ArMapInfo   |
+ *                 |                                |
+ *                 +----------------> ArMapSupplement
+ *
+ * 
+ + * @see ArMapInterface + * @see ArMap +**/ +#ifndef ARMAPCOMPONENTS_H +#define ARMAPCOMPONENTS_H + +#include "ArMapInterface.h" + +class ArMapChangeDetails; +class ArMapFileLineSet; +class ArFileParser; +class ArMD5Calculator; + + +// ============================================================================ +// ArMapScan +// ============================================================================ + +/// The map data related to the sensable obstacles in the environment. +/** + * ArMapScan encapsulates the data for a particular sensor that is generated + * during the scanning process (i.e. during the creation of a .2d file). + * The class's primary attributes are the points and line segments that + * were detected during the scan. It contains methods to get and set these + * coordinates, and to read and write the data from and to a file. + *

+ * The scanType parameters identify the sensor used for scanning. + * The parameter is used in the constructor, but it is generally disregarded + * in the other methods. (The method signatures are defined in + * ArMapScanInterface, which is also implemented by ArMap. The map provides + * access to the scan data for all of the sensors -- and therefore uses the + * scanType parameters. This interface was chosen in order + * to maintain backwards compatibility with the original map.) + *

+ * If the scanType is specified, then it is used as a prefix to the DATA and + * LINES tags that are contained in the map file. +**/ +class ArMapScan : public ArMapScanInterface +{ +public: + + /// Constructor + /** + * Creates a new map scan object for the specified scan type. + * @param scanType the const char * identifier of the scan; must be + * non-NULL and must not contain whitespaces + **/ + AREXPORT ArMapScan(const char *scanType = ARMAP_DEFAULT_SCAN_TYPE); + + /// Copy constructor + AREXPORT ArMapScan(const ArMapScan &other); + + /// Assignment operator + AREXPORT ArMapScan &operator=(const ArMapScan &other); + + /// Destructor + AREXPORT virtual ~ArMapScan(); + + + // -------------------------------------------------------------------------- + // ArMapScanInterface Methods + // -------------------------------------------------------------------------- + + AREXPORT virtual const char *getDisplayString + (const char *scanType = ARMAP_DEFAULT_SCAN_TYPE); + + AREXPORT virtual std::vector *getPoints + (const char *scanType = ARMAP_DEFAULT_SCAN_TYPE); + + AREXPORT virtual std::vector *getLines + (const char *scanType = ARMAP_DEFAULT_SCAN_TYPE); + + AREXPORT virtual ArPose getMinPose(const char *scanType = ARMAP_DEFAULT_SCAN_TYPE); + + AREXPORT virtual ArPose getMaxPose(const char *scanType = ARMAP_DEFAULT_SCAN_TYPE); + + AREXPORT virtual int getNumPoints(const char *scanType = ARMAP_DEFAULT_SCAN_TYPE); + + AREXPORT virtual bool isSortedPoints(const char *scanType = ARMAP_DEFAULT_SCAN_TYPE) const; + + AREXPORT virtual void setPoints(const std::vector *points, + const char *scanType = ARMAP_DEFAULT_SCAN_TYPE, + bool isSortedPoints = false, + ArMapChangeDetails *changeDetails = NULL); + + + AREXPORT virtual ArPose getLineMinPose(const char *scanType = ARMAP_DEFAULT_SCAN_TYPE); + + AREXPORT virtual ArPose getLineMaxPose(const char *scanType = ARMAP_DEFAULT_SCAN_TYPE); + + AREXPORT virtual int getNumLines(const char *scanType = ARMAP_DEFAULT_SCAN_TYPE); + + AREXPORT virtual bool isSortedLines(const char *scanType = ARMAP_DEFAULT_SCAN_TYPE) const; + + AREXPORT virtual void setLines(const std::vector *lines, + const char *scanType = ARMAP_DEFAULT_SCAN_TYPE, + bool isSortedLines = false, + ArMapChangeDetails *changeDetails = NULL); + + + AREXPORT virtual int getResolution(const char *scanType = ARMAP_DEFAULT_SCAN_TYPE); + + AREXPORT virtual void setResolution(int resolution, + const char *scanType = ARMAP_DEFAULT_SCAN_TYPE, + ArMapChangeDetails *changeDetails = NULL); + + + AREXPORT virtual void writeScanToFunctor + (ArFunctor1 *functor, + const char *endOfLineChars, + const char *scanType = ARMAP_DEFAULT_SCAN_TYPE); + + AREXPORT virtual void writePointsToFunctor + (ArFunctor2 *> *functor, + const char *scanType = ARMAP_DEFAULT_SCAN_TYPE, + ArFunctor1 *keywordFunctor = NULL); + + AREXPORT virtual void writeLinesToFunctor + (ArFunctor2 *> *functor, + const char *scanType = ARMAP_DEFAULT_SCAN_TYPE, + ArFunctor1 *keywordFunctor = NULL); + + AREXPORT virtual bool addToFileParser(ArFileParser *fileParser); + + AREXPORT virtual bool remFromFileParser(ArFileParser *fileParser); + + AREXPORT virtual bool readDataPoint( char *line); + + AREXPORT virtual bool readLineSegment( char *line); + + AREXPORT virtual void loadDataPoint(double x, double y); + + AREXPORT virtual void loadLineSegment(double x1, double y1, double x2, double y2); + + // -------------------------------------------------------------------------- + // Other Methods + // -------------------------------------------------------------------------- + + /// Resets the scan data, clearing all points and line segments + AREXPORT virtual void clear(); + + /// Combines the given other scan with this one. + /** + * @param other the ArMapScan * to be united with this one + * @param isIncludeDataPointsAndLines a bool set to true if the other scan's + * data points and lines should be copied to this scan; if false, then only + * the summary (bounding box, counts, etc) information is copied. + **/ + AREXPORT virtual bool unite(ArMapScan *other, + bool isIncludeDataPointsAndLines = false); + + /// Returns the time at which the scan data was last changed. + AREXPORT virtual ArTime getTimeChanged() const; + + // TODO: Which of these need to be in the ArMapScanInterface? + + /// Returns the unique string identifier of the associated scan type. + AREXPORT virtual const char *getScanType() const; + + /// Returns the keyword that designates the scan's data points in the map file. + AREXPORT virtual const char *getPointsKeyword() const; + /// Returns the keyword that designates the scan's data lines in the map file. + AREXPORT virtual const char *getLinesKeyword() const; + + /// Writes the scan's data points (and introductory keyword) to the given functor. + AREXPORT virtual void writePointsToFunctor + (ArFunctor1 *functor, + const char *endOfLineChars, + const char *scanType = ARMAP_DEFAULT_SCAN_TYPE); + + /// Writes the scan's data lines (and introductory keyword) to the given functor. + AREXPORT virtual void writeLinesToFunctor + (ArFunctor1 *functor, + const char *endOfLineChars, + const char *scanType = ARMAP_DEFAULT_SCAN_TYPE); + + + /// Adds the handlers for the data points and lines keywords to the given file parser. + /** + * These handlers are "extra" because they are added after all of the summary + * keyword have been parsed. + **/ + AREXPORT virtual bool addExtraToFileParser(ArFileParser *fileParser, + bool isAddLineHandler); + + /// Removes the handlers for the data points and lines keywords from the given file parser. + AREXPORT virtual bool remExtraFromFileParser(ArFileParser *fileParser); + + +protected: + + /// Writes the list of data lines to the given functor. + /** + * @param functor the ArFunctor1 * to which to write the + * data lines + * @param lines the vector of ArLineSegments to be written to the functor + * @param endOfLineChars an optional string to be appended to the end of + * each text line written to the functor + * @param scanType the unique string identifier of the scan type associated + * with the data lines + **/ + AREXPORT virtual void writeLinesToFunctor + (ArFunctor1 *functor, + const std::vector &lines, + const char *endOfLineChars, + const char *scanType = ARMAP_DEFAULT_SCAN_TYPE); + + + // Function to read the minimum pos + bool handleMinPos(ArArgumentBuilder *arg); + // Function to read the maximum pos + bool handleMaxPos(ArArgumentBuilder *arg); + // Function to read the number of points + bool handleNumPoints(ArArgumentBuilder *arg); + // Function to read whether the points are sorted + bool handleIsSortedPoints(ArArgumentBuilder *arg); + + // Function to read the line minimum pos + bool handleLineMinPos(ArArgumentBuilder *arg); + // Function to read the line maximum pos + bool handleLineMaxPos(ArArgumentBuilder *arg); + // Function to read the number of lines + bool handleNumLines(ArArgumentBuilder *arg); + // Function to read whether the lines are sorted + bool handleIsSortedLines(ArArgumentBuilder *arg); + + // Function to handle the resolution + bool handleResolution(ArArgumentBuilder *arg); + /// Callback to handle the Display string. + bool handleDisplayString(ArArgumentBuilder *arg); + + // Function to snag the map points (mainly for the getMap over the network) + bool handlePoint(ArArgumentBuilder *arg); + // Function to snag the line segments (mainly for the getMap over the network) + bool handleLine(ArArgumentBuilder *arg); + + /// Adds the specified argument handler to the given file parser. + bool addHandlerToFileParser(ArFileParser *fileParser, + const char *keyword, + ArRetFunctor1 *handler); + + /// Returns the keyword prefix for this scan type. + const char *getKeywordPrefix() const; + + /// Parses a pose from the given arguments. + bool parsePose(ArArgumentBuilder *arg, + const char *keyword, + ArPose *poseOut); + + /// Parses an integer from the given text line. + bool parseNumber(char *line, + size_t lineLen, + size_t *charCountOut, + int *numOut) const; + + /// Parses whitespace from the given text line. + bool parseWhitespace(char *line, + size_t lineLen, + size_t *charCountOut) const; + + +private: + + /// Constant appended to the end of each scan data text line. + static const char *EOL_CHARS; + +protected: + + /// The unique string identifier of this scan type. + std::string myScanType; + /// Whether this is a special summary of the other scans. + bool myIsSummaryScan; + + /// The prefix prepended to the output log file messages. + std::string myLogPrefix; + /// The prefix prepended to the map file keywords (e.g. DATA and LINES) + std::string myKeywordPrefix; + /// The keyword that designates this scan's data points in the map file. + std::string myPointsKeyword; + /// The keyword that designates this scan's data lines in the map file. + std::string myLinesKeyword; + + /// Time that this scan data was last modified. + ArTime myTimeChanged; + + /// Displayable text for this scan type. + std::string myDisplayString; + + /// Number of data points in the scan. + int myNumPoints; + /// Number of data lines in the scan. + int myNumLines; + /// Resolution of the data points (in mm). + int myResolution; + /// Maximum x/y values of all of the data points in the scan. + ArPose myMax; + /// Minimum x/y values of all of the data points in the scan. + ArPose myMin; + /// Maximum x/y values of all of the data lines in the scan. + ArPose myLineMax; + /// Minimum x/y values of all of the data lines in the scan. + ArPose myLineMin; + + /// Whether the data points in myPoints have been sorted in ascending order. + bool myIsSortedPoints; + /// Whether the data lines in myLines have been sorted in ascending order. + bool myIsSortedLines; + + /// List of data points contained in this scan data. + std::vector myPoints; + /// List of data lines contained in this scan data. + std::vector myLines; + + /// Callback to parse the minimum poise from the map file. + ArRetFunctor1C myMinPosCB; + /// Callback to parse the maximum pose from the map file. + ArRetFunctor1C myMaxPosCB; + /// Callback to parse whether the points in the map file have been sorted. + ArRetFunctor1C myIsSortedPointsCB; + /// Callback to parse the number of data points in the map file. + ArRetFunctor1C myNumPointsCB; + + /// Callback to parse the minimum line pose from the map file. + ArRetFunctor1C myLineMinPosCB; + /// Callback to parse the maximum line pose from the map file. + ArRetFunctor1C myLineMaxPosCB; + /// Callback to parse whether the lines in the map file have been sorted. + ArRetFunctor1C myIsSortedLinesCB; + /// Callback to parse the number of data lines in the map file. + ArRetFunctor1C myNumLinesCB; + + /// Callback to parse the resolution in the map file. + ArRetFunctor1C myResolutionCB; + /// Callback to parse the displayable text for this scan type. + ArRetFunctor1C myDisplayStringCB; + + /// Callback to parse a data point. + ArRetFunctor1C myPointCB; + /// Callback to parse a data line. + ArRetFunctor1C myLineCB; + +}; // end class ArMapScan + +// ============================================================================ +// ArMapObjects +// ============================================================================ + +/// The collection of map objects that are contained in an Aria map. +/** + * ArMapObjects contains a list of objects defined in an Aria map. There are + * two basic classes of objects: user-defined objects such as goals and + * forbidden areas; and, special data objects that are usually automatically + * generated during the scanning process. +**/ +class ArMapObjects : public ArMapObjectsInterface +{ + +public : + + /// Default keyword that prefixes each map object line in the map file + static const char *DEFAULT_KEYWORD; + + /// Constructor + /** + * @param keyword the char * keyword that prefixes each map object line in + * the map file + **/ + AREXPORT ArMapObjects(const char *keyword = "Cairn:"); + + /// Copy constructor + AREXPORT ArMapObjects(const ArMapObjects &other); + + /// Assignment operator + AREXPORT ArMapObjects &operator=(const ArMapObjects &other); + + /// Destructor + AREXPORT virtual ~ArMapObjects(); + + + // --------------------------------------------------------------------------- + // ArMapObjectsInterface Methods + // --------------------------------------------------------------------------- + + AREXPORT virtual ArMapObject *findFirstMapObject(const char *name, + const char *type, + bool isIncludeWithHeading = false); + + AREXPORT virtual ArMapObject *findMapObject(const char *name, + const char *type = NULL, + bool isIncludeWithHeading = false); + + AREXPORT virtual std::list findMapObjectsOfType + (const char *type, + bool isIncludeWithHeading = false); + + AREXPORT virtual std::list *getMapObjects(void); + + AREXPORT virtual void setMapObjects(const std::list *mapObjects, + bool isSortedObjects = false, + ArMapChangeDetails *changeDetails = NULL); + + AREXPORT void writeObjectListToFunctor(ArFunctor1 *functor, + const char *endOfLineChars); + + + // --------------------------------------------------------------------------- + // Other Methods + // --------------------------------------------------------------------------- + + /// Clears the map objects and deletes them. + AREXPORT virtual void clear(); + + /// Adds the keyword and handler for the map objects to the given file parser. + AREXPORT virtual bool addToFileParser(ArFileParser *fileParser); + + /// Removes the keyword and handler for the map objects from the given file parser. + AREXPORT virtual bool remFromFileParser(ArFileParser *fileParser); + + /// Returns the time at which the map objects were last changed. + AREXPORT virtual ArTime getTimeChanged() const; + +protected: + + // Function to handle the cairns + bool handleMapObject(ArArgumentBuilder *arg); + + /// Sorts the given list of map objects in order of increasing object pose. + void sortMapObjects(std::list *mapObjects); + + /// Writes the map objects to the given ArMapFileLineSet. + void createMultiSet(ArMapFileLineSet *multiSet); + + /// Writes the given ArMapFileLineSet to the output log with the specified prefix. + void logMultiSet(const char *prefix, + ArMapFileLineSet *multiSet); + +protected: + + /// Time at which the map objects were last changed. + ArTime myTimeChanged; + /// Whether the myMapObjects list has been sorted in increasing (pose) order. + bool myIsSortedObjects; + + /// Keyword that prefixes each map object in the map file. + std::string myKeyword; + + /// List of map objects contained in the Aria map. + std::list myMapObjects; + + /// Callback to parse the map object from the map file. + ArRetFunctor1C myMapObjectCB; + +}; // end class ArMapObjects + + +// ============================================================================ +// ArMapInfo +// ============================================================================ + + +/// A container for the various "info" tags in an Aria map. +/** + * ArMapInfo is an implementation of ArMapInfoInterface that provides access + * to a collection of "info" arguments (such as MapInfo and RouteInfo). An Aria + * map may have one or more categories of info, each implemented by an ordered + * list of ArArgumentBuilder's. + * + * Info types are currently identified by a unique integer. The default types + * are defined in ArMapInfoInterface::InfoType, but applications may define + * additional types. (See ArMapInfo::ArMapInfo(int*, char**, size_t)) +**/ +class ArMapInfo : public ArMapInfoInterface +{ +public: + + /// Contructor + /** + * @param infoNameList an array of the char * keywords for each of the + * standard ArMapInfo::InfoType's; if NULL, then the default keywords are + * used + * @param infoNameCount the size_t length of the infoNameList array + * @param keywordPrefix optional prefix to add to keywords. + **/ + AREXPORT ArMapInfo(const char **infoNameList = NULL, + size_t infoNameCount = 0, + const char *keywordPrefix = NULL); + + /// Copy contructor + AREXPORT ArMapInfo(const ArMapInfo &other); + /// Assignment operator + AREXPORT ArMapInfo &operator=(const ArMapInfo &other); + /// Destructor + AREXPORT virtual ~ArMapInfo(); + + // --------------------------------------------------------------------------- + // ArMapInfoInterface Methods + // --------------------------------------------------------------------------- + + AREXPORT virtual std::list *getInfo(const char *infoName); + + AREXPORT virtual std::list *getInfo(int infoType); + AREXPORT virtual std::list *getMapInfo(void); + + AREXPORT virtual int getInfoCount() const; + + AREXPORT virtual std::list getInfoNames() const; + + AREXPORT virtual bool setInfo(const char *infoName, + const std::list *infoList, + ArMapChangeDetails *changeDetails); + + + AREXPORT virtual bool setInfo(int infoType, + const std::list *infoList, + ArMapChangeDetails *changeDetails = NULL); + AREXPORT virtual bool setMapInfo(const std::list *mapInfo, + ArMapChangeDetails *changeDetails = NULL); + + + AREXPORT virtual const char *getInfoName(int infoType); + + AREXPORT virtual void writeInfoToFunctor(ArFunctor1 *functor, + const char *endOfLineChars); + + // --------------------------------------------------------------------------- + // Other Methods + // --------------------------------------------------------------------------- + + /// Clears all info arguments and deletes them. + AREXPORT virtual void clear(); + + /// Adds handlers for all of the info types to the given file parser. + AREXPORT virtual bool addToFileParser(ArFileParser *fileParser); + /// Removes handlers for all of the info types from the given file parser. + AREXPORT virtual bool remFromFileParser(ArFileParser *fileParser); + + /// Returns the time at which the info were last changed. + AREXPORT virtual ArTime getTimeChanged() const; + +protected: + + /// Processes the given argument for the specified info. + bool handleInfo(ArArgumentBuilder *arg); + + /// Give ArMapSimple access to the createMultiSet() and setChanged() methods + friend class ArMapSimple; + + /// Writes the specified info arguments to the given ArMapFileLineSet. + /** + * @param infoName unique identifier for the info to be written + * @param multiSet the ArMapFileLineSet * to which to write the info; + * must be non-NULL + * @param changeDetails the ArMapChangeDetails * that specifies the + * parent/child relationship amongst info lines + * @see ArMapChangeDetails::isChildArg + **/ + void createMultiSet(const char *infoName, + ArMapFileLineSet *multiSet, + ArMapChangeDetails *changeDetails); + + /// Basically updates the timeChanged to now. + void setChanged(); + + /// Populates this object with the default info names / keywords + void setDefaultInfoNames(); + + + +protected: + + struct ArMapInfoData { + + ArMapInfo *myParent; + int myType; + std::string myKeyword; + std::list myInfo; + ArRetFunctor1C *myInfoCB; + + ArMapInfoData(ArMapInfo *parent, + const char *name = NULL, + int type = -1); + ~ArMapInfoData(); + ArMapInfoData(ArMapInfo *parent, + const ArMapInfoData &other); + ArMapInfoData &operator=(const ArMapInfoData &other); + + }; // end struct ArMapInfoData + + typedef std::map ArInfoNameToDataMap; + + + AREXPORT ArMapInfoData *findData(const char *infoName); + + AREXPORT ArMapInfoData *findDataByKeyword(const char *keyword); + + + /// Time at which the info was last changed + ArTime myTimeChanged; + + // Sigh... In retrospect, this should have been structured differently + // and we probably should've used a string for the info identifier... + + /// Number of info types contained in this collection + int myNumInfos; + std::string myPrefix; + + std::map myInfoTypeToNameMap; + ArInfoNameToDataMap myInfoNameToDataMap; + std::map myKeywordToInfoNameMap; + +}; // end class ArMapInfo + + +// ============================================================================ +// ArMapSupplement +// ============================================================================ + +/// Supplemental data associated with an Aria map. +/** + * ArMapSupplement is a repository for extra, miscellaneous data that is + * associated with an Aria map but which does not fit neatly into any of the + * other components. +**/ +class ArMapSupplement : public ArMapSupplementInterface +{ +public: + + /// Constructor + AREXPORT ArMapSupplement(); + + /// Copy constructor + AREXPORT ArMapSupplement(const ArMapSupplement &other); + + /// Assignment operator + AREXPORT ArMapSupplement &operator=(const ArMapSupplement &other); + + /// Destructor + AREXPORT virtual ~ArMapSupplement(); + + + // -------------------------------------------------------------------------- + // ArMapSupplementInterface Methods + // -------------------------------------------------------------------------- + + AREXPORT virtual bool hasOriginLatLongAlt(); + + AREXPORT virtual ArPose getOriginLatLong(); + + AREXPORT virtual double getOriginAltitude(); + + AREXPORT virtual void setOriginLatLongAlt(bool hasOriginLatLong, + const ArPose &originLatLong, + double altitude, + ArMapChangeDetails *changeDetails = NULL); + + AREXPORT virtual void writeSupplementToFunctor + (ArFunctor1 *functor, + const char *endOfLineChars); + + // -------------------------------------------------------------------------- + // Other Methods + // -------------------------------------------------------------------------- + + /// Resets the map supplement to its default values. + AREXPORT virtual void clear(); + + /// Adds handlers for all of the supplement keywords to the given file parser. + AREXPORT virtual bool addToFileParser(ArFileParser *fileParser); + /// Removes handlers for all of the supplement keywords from the given file parser. + AREXPORT virtual bool remFromFileParser(ArFileParser *fileParser); + + /// Returns the time at which the supplement data were last changed. + AREXPORT virtual ArTime getTimeChanged() const; + +protected: + + // Function to get the origin lat long altitude + bool handleOriginLatLongAlt(ArArgumentBuilder *arg); + +private: + + /// Constant appended to the end of each supplement text line. + static const char *EOL_CHARS; + +protected: + + /// Time at which the supplement was last changed + ArTime myTimeChanged; + + /// Whether the supplement data contains latitude/longitude information for the origin + bool myHasOriginLatLongAlt; + /// The latitude/longitude of the origin; only if myHasOriginLatLongAlt is true + ArPose myOriginLatLong; + /// The altitude (in m) of the origin; only if myHasOriginLatLongAlt is true + double myOriginAltitude; + + /// Callback that parses the origin latitude/longitude/altitude information + ArRetFunctor1C myOriginLatLongAltCB; + +}; // end class ArMapSupplement + + +// ============================================================================= +// ArMapSimple +// ============================================================================= + +/// Comparator used to sort scan data types in a case-insensitive manner. +struct ArDataTagCaseCmpOp +{ +public: + bool operator() (const std::string &s1, const std::string &s2) const + { + size_t s1Len = s1.length(); + size_t s2Len = s2.length(); + + if (s1Len < s2Len) { + return strncasecmp(s1.c_str(), s2.c_str(), s1Len) < 0; + } + else { + return strncasecmp(s1.c_str(), s2.c_str(), s2Len) < 0; + } + } +}; // end struct ArDataTagCaseCmpOp + +/// Type definition for a map of scan types to scan data. +typedef std::map ArTypeToScanMap; + +/// Type definition for a map of data tags to scan types +typedef std::map ArDataTagToScanTypeMap; + + +/// Simple map that can be read from and written to a file +/** + * ArMapSimple is the real subject of the ArMap proxy. Functionally, it is identical + * to the ArMap, @b except that it is not well-suited for for loading from a file at + * runtime and therefore doesn't provide any hooks into the Aria config. In general, + * ArMap should be used instead. The exception to this rule may be in off-line + * authoring tools where error checking can be performed at a higher level. +**/ +class ArMapSimple : public ArMapInterface +{ +public: + + /// Constructor + /** + * @param baseDirectory the name of the directory in which to search for map + * files that are not fully qualified + * @param tempDirectory the name of the directory in which to write temporary + * files when saving a map; if NULL, then the map file is written directly. + * Note that using a temp file reduces the risk that the map will be corrupted + * if the application crashes. + * @param overrideMutexName an optional name to be used for the map object's + * mutex; useful for debugging when multiple maps are active + **/ + AREXPORT ArMapSimple(const char *baseDirectory = "./", + const char *tempDirectory = NULL, + const char *overrideMutexName = NULL); + + /// Copy constructor + AREXPORT ArMapSimple(const ArMapSimple &other); + /// Assignment operator + AREXPORT ArMapSimple &operator=(const ArMapSimple &other); + /// Destructor + AREXPORT virtual ~ArMapSimple(void); + + + AREXPORT virtual void clear(); + + AREXPORT virtual bool set(ArMapInterface *other); + + AREXPORT virtual ArMapInterface *clone(); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Scan Types Methods + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + AREXPORT virtual std::list getScanTypes() const; + + AREXPORT virtual bool setScanTypes(const std::list &scanTypeList); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Locking / Semaphore Method + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + AREXPORT virtual int lock(); + + AREXPORT virtual int tryLock(); + + AREXPORT virtual int unlock(); + + + // --------------------------------------------------------------------------- + // ArMapInfoInterface + // --------------------------------------------------------------------------- + + AREXPORT virtual std::list *getInfo(const char *infoName); + AREXPORT virtual std::list *getInfo(int infoType); + AREXPORT virtual std::list *getMapInfo(void); + + AREXPORT virtual int getInfoCount() const; + + AREXPORT virtual std::list getInfoNames() const; + + AREXPORT virtual bool setInfo(const char *infoName, + const std::list *infoList, + ArMapChangeDetails *changeDetails = NULL); + + AREXPORT virtual bool setInfo(int infoType, + const std::list *infoList, + ArMapChangeDetails *changeDetails = NULL); + + AREXPORT virtual bool setMapInfo(const std::list *mapInfo, + ArMapChangeDetails *changeDetails = NULL); + + AREXPORT virtual void writeInfoToFunctor + (ArFunctor1 *functor, + const char *endOfLineChars); + + AREXPORT virtual const char *getInfoName(int infoType); + + // --------------------------------------------------------------------------- + // ArMapObjectsInterface + // --------------------------------------------------------------------------- + + AREXPORT virtual ArMapObject *findFirstMapObject(const char *name, + const char *type, + bool isIncludeWithHeading = false); + + AREXPORT virtual ArMapObject *findMapObject(const char *name, + const char *type = NULL, + bool isIncludeWithHeading = false); + + AREXPORT virtual std::list findMapObjectsOfType + (const char *type, + bool isIncludeWithHeading = false); + + AREXPORT virtual std::list *getMapObjects(void); + + AREXPORT virtual void setMapObjects(const std::list *mapObjects, + bool isSortedObjects = false, + ArMapChangeDetails *changeDetails = NULL); + + + AREXPORT virtual void writeObjectListToFunctor(ArFunctor1 *functor, + const char *endOfLineChars); + + // --------------------------------------------------------------------------- + // ArMapSupplementInterface + // --------------------------------------------------------------------------- + + AREXPORT virtual bool hasOriginLatLongAlt(); + + AREXPORT virtual ArPose getOriginLatLong(); + + AREXPORT virtual double getOriginAltitude(); + + AREXPORT virtual void setOriginLatLongAlt + (bool hasOriginLatLong, + const ArPose &originLatLong, + double altitude, + ArMapChangeDetails *changeDetails = NULL); + + + AREXPORT virtual void writeSupplementToFunctor(ArFunctor1 *functor, + const char *endOfLineChars); + + // --------------------------------------------------------------------------- + // ArMapScanInterface + // --------------------------------------------------------------------------- + + AREXPORT virtual const char *getDisplayString + (const char *scanType = ARMAP_DEFAULT_SCAN_TYPE); + + AREXPORT virtual std::vector *getPoints + (const char *scanType = ARMAP_DEFAULT_SCAN_TYPE); + + AREXPORT virtual ArPose getMinPose(const char *scanType = ARMAP_DEFAULT_SCAN_TYPE); + AREXPORT virtual ArPose getMaxPose(const char *scanType = ARMAP_DEFAULT_SCAN_TYPE); + AREXPORT virtual int getNumPoints(const char *scanType = ARMAP_DEFAULT_SCAN_TYPE); + AREXPORT virtual bool isSortedPoints(const char *scanType = ARMAP_DEFAULT_SCAN_TYPE) const; + + AREXPORT virtual void setPoints(const std::vector *points, + const char *scanType = ARMAP_DEFAULT_SCAN_TYPE, + bool isSortedPoints = false, + ArMapChangeDetails *changeDetails = NULL); + + + AREXPORT virtual std::vector *getLines + (const char *scanType = ARMAP_DEFAULT_SCAN_TYPE); + + AREXPORT virtual ArPose getLineMinPose(const char *scanType = ARMAP_DEFAULT_SCAN_TYPE); + AREXPORT virtual ArPose getLineMaxPose(const char *scanType = ARMAP_DEFAULT_SCAN_TYPE); + AREXPORT virtual int getNumLines(const char *scanType = ARMAP_DEFAULT_SCAN_TYPE); + AREXPORT virtual bool isSortedLines(const char *scanType = ARMAP_DEFAULT_SCAN_TYPE) const; + + AREXPORT virtual void setLines(const std::vector *lines, + const char *scanType = ARMAP_DEFAULT_SCAN_TYPE, + bool isSortedLines = false, + ArMapChangeDetails *changeDetails = NULL); + + + AREXPORT virtual int getResolution(const char *scanType = ARMAP_DEFAULT_SCAN_TYPE); + + AREXPORT virtual void setResolution(int resolution, + const char *scanType = ARMAP_DEFAULT_SCAN_TYPE, + ArMapChangeDetails *changeDetails = NULL); + + + AREXPORT virtual void writeScanToFunctor + (ArFunctor1 *functor, + const char *endOfLineChars, + const char *scanType = ARMAP_DEFAULT_SCAN_TYPE); + + AREXPORT virtual void writePointsToFunctor + (ArFunctor2 *> *functor, + const char *scanType = ARMAP_DEFAULT_SCAN_TYPE, + ArFunctor1 *keywordFunctor = NULL); + + AREXPORT virtual void writeLinesToFunctor + (ArFunctor2 *> *functor, + const char *scanType = ARMAP_DEFAULT_SCAN_TYPE, + ArFunctor1 *keywordFunctor = NULL); + + AREXPORT virtual bool addToFileParser(ArFileParser *fileParser); + AREXPORT virtual bool remFromFileParser(ArFileParser *fileParser); + + + AREXPORT virtual bool readDataPoint( char *line); + AREXPORT virtual bool readLineSegment( char *line); + + + /** Public for ArQClientMapProducer **/ + + AREXPORT virtual void loadDataPoint(double x, double y); + AREXPORT virtual void loadLineSegment(double x1, double y1, double x2, double y2); + + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Map Changed / Callback Methods + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + AREXPORT virtual void mapChanged(void); + + AREXPORT virtual void addMapChangedCB(ArFunctor *functor, + int position = 50); + + AREXPORT virtual void remMapChangedCB(ArFunctor *functor); + + AREXPORT virtual void addPreMapChangedCB(ArFunctor *functor, + int position = 50); + + AREXPORT virtual void remPreMapChangedCB(ArFunctor *functor); + + AREXPORT virtual void setMapChangedLogLevel(ArLog::LogLevel level); + + AREXPORT virtual ArLog::LogLevel getMapChangedLogLevel(void); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Persistence + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + AREXPORT virtual void writeToFunctor(ArFunctor1 *functor, + const char *endOfLineChars); + + AREXPORT virtual void writeObjectsToFunctor(ArFunctor1 *functor, + const char *endOfLineChars, + bool isOverrideAsSingleScan = false, + const char *maxCategory = NULL); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // File I/O Methods + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + AREXPORT virtual void addPreWriteFileCB(ArFunctor *functor, + ArListPos::Pos position = ArListPos::LAST); + AREXPORT virtual void remPreWriteFileCB(ArFunctor *functor); + + AREXPORT virtual void addPostWriteFileCB(ArFunctor *functor, + ArListPos::Pos position = ArListPos::LAST); + AREXPORT virtual void remPostWriteFileCB(ArFunctor *functor); + + AREXPORT virtual bool readFile(const char *fileName, + char *errorBuffer = NULL, + size_t errorBufferLen = 0, + unsigned char *md5DigestBuffer = NULL, + size_t md5DigestBufferLen = 0); + + AREXPORT virtual bool writeFile(const char *fileName, + bool internalCall = false, + unsigned char *md5DigestBuffer = NULL, + size_t md5DigestBufferLen = 0, + time_t fileTimestamp = -1); + +#ifndef SWIG + /// @swigomit + AREXPORT virtual struct stat getReadFileStat() const; +#endif + + AREXPORT virtual bool getMapId(ArMapId *mapIdOut, + bool isInternalCall = false); + + AREXPORT virtual bool calculateChecksum(unsigned char *md5DigestBuffer, + size_t md5DigestBufferLen); + + AREXPORT virtual const char *getBaseDirectory(void) const; + + AREXPORT virtual void setBaseDirectory(const char *baseDirectory); + + AREXPORT virtual const char *getTempDirectory(void) const; + + AREXPORT virtual void setTempDirectory(const char *tempDirectory); + + AREXPORT virtual std::string createRealFileName(const char *fileName); + + AREXPORT virtual const char *getFileName(void) const; + + AREXPORT virtual void setSourceFileName(const char *sourceName, + const char *fileName, + bool isInternalCall = false); + + AREXPORT virtual bool refresh(); + + + virtual void setIgnoreEmptyFileName(bool ignore); + virtual bool getIgnoreEmptyFileName(void); + virtual void setIgnoreCase(bool ignoreCase = false); + virtual bool getIgnoreCase(void); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Inactive Section + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + AREXPORT virtual ArMapInfoInterface *getInactiveInfo(); + + AREXPORT virtual ArMapObjectsInterface *getInactiveObjects(); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Child Objects Section + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + AREXPORT virtual ArMapObjectsInterface *getChildObjects(); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Miscellaneous + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + AREXPORT virtual ArArgumentBuilder *findMapObjectParams(const char *mapObjectName); + + AREXPORT virtual bool setMapObjectParams(const char *mapObjectName, + ArArgumentBuilder *params, + ArMapChangeDetails *changeDetails = NULL); + + + + AREXPORT virtual std::list *getRemainder(); + + AREXPORT virtual void setQuiet(bool isQuiet); + + AREXPORT bool parseLine(char *line); + AREXPORT void parsingComplete(void); + + AREXPORT bool isLoadingDataStarted(); + AREXPORT bool isLoadingLinesAndDataStarted(); + + + // --------------------------------------------------------------------- + + /// Searches the given CairnInfo list for an entry that matches the given mapObject. + /** + * The CairnInfo list stores the parameter information (if any) for map + * objects. If a map object is removed (or activated), then the CairnInfo + * must also be updated. + * @param mapObjectName the ArMapObject for which to find the parameters + * @param cairnInfoList the list of ArArgumentBuilder *'s that contain the + * map object parameters (also may be set to the inactive section) + * @return iterator that points to the parameter information for the map + * object, or cairnInfoList.end() if not found + **/ + AREXPORT static std::list::iterator findMapObjectParamInfo + (const char *mapObjectName, + std::list &cairnInfoList); + +protected: + + AREXPORT bool setInactiveInfo(const char *infoName, + const std::list *infoList, + ArMapChangeDetails *changeDetails = NULL); + + AREXPORT void setInactiveObjects(const std::list *mapObjects, + bool isSortedObjects = false, + ArMapChangeDetails *changeDetails = NULL); + + AREXPORT void setChildObjects(const std::list *mapObjects, + bool isSortedObjects = false, + ArMapChangeDetails *changeDetails = NULL); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + /// Callback that handles the different types of map categories (e.g. 2D-Map, 2D-Map-Ex) + /** + * This method replaces the old handle2DMap method. It determines which category + * was detected and sets the myMapCategory attribute accordingly. + * @param arg a pointer to the parsed ArArgumentBuilder; no arguments are expected + **/ + bool handleMapCategory(ArArgumentBuilder *arg); + + /// Callback that handles the Sources keyword + /** + * @param arg a pointer to the parsed ArArgumentBuilder; a list of string scan type + * arguments are expected + **/ + bool handleSources(ArArgumentBuilder *arg); + + + /// Callback that handles the different types of data introductions (e.g. DATA, LINES) + /** + * This method replaces the old handleData and handleLines methods. It determines + * which keyword was detected and updates the myLoadingDataTag and myLoadingScan + * attributes accordingly. + * @param arg a pointer to the parsed ArArgumentBuilder; no arguments are expected + **/ + bool handleDataIntro(ArArgumentBuilder *arg); + + + bool handleRemainder(ArArgumentBuilder *arg); + + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + /// Returns the ArMapScan for the specified scan type. + AREXPORT virtual ArMapScan *getScan(const char *scanType) const; + + /// Sets up the map to contain teh specified scan types. + /** + * Any scans which are currently in the map are cleared and removed. + * This method is not virtual because it is called by the constructor. + * @param scanTypeList a list of the scan type string identifiers to be + * created; the list must be non-empty and must not contain duplicates; + * if the list contains more than one entry, then they all must be + * non-empty + * @return bool true if the scans were successfully created; false otherwise + **/ + bool createScans(const std::list &scanTypeList); + + /// Adds all of the map's scan types to the current file parser. + /** + * This method calls addToFileParser() on each of the map's scans. It also + * adds handlers for each of the scans' data point and line introduction + * keywords. + * @return bool true if the scans were successfully added to the current + * file parser + **/ + bool addScansToParser(); + + /// Removes all of the map's scan types from the current file parser. + bool remScansFromParser(bool isRemovePointsAndLinesKeywords = true); + + AREXPORT void writeScanTypesToFunctor(ArFunctor1 *functor, + const char *endOfLineChars); + + AREXPORT ArTime findMaxMapScanTimeChanged(); + + AREXPORT ArMapScan *findScanWithDataKeyword(const char *myLoadingDataTag, + bool *isLineDataTagOut); + + AREXPORT void updateSummaryScan(); + + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + AREXPORT virtual const char *getMapCategory(); + + + AREXPORT virtual void updateMapCategory(const char *updatedInfoName = NULL); + + AREXPORT virtual bool mapInfoContains(const char *arg0Text); + + AREXPORT bool isDataTag(const char *line); + + AREXPORT void reset(); + + AREXPORT void updateMapFileInfo(const char *realFileName); + + + + AREXPORT static int getNextFileNumber(); + + AREXPORT void invokeCallbackList(std::list *cbList); + + AREXPORT void addToCallbackList(ArFunctor *functor, + ArListPos::Pos position, + std::list *cbList); + + AREXPORT void remFromCallbackList(ArFunctor *functor, + std::list *cbList); + +protected: + + // static const char *ourDefaultInactiveInfoNames[INFO_COUNT]; + + + static int ourTempFileNumber; + static ArMutex ourTempFileNumberMutex; + + // lock for our data + ArMutex myMutex; + + std::list myMapCategoryList; + std::string myMapCategory; + + + ArMD5Calculator *myChecksumCalculator; + + std::string myBaseDirectory; + std::string myFileName; + struct stat myReadFileStat; + + std::list myPreWriteCBList; + std::list myPostWriteCBList; + + bool myIsWriteToTempFile; + std::string myTempDirectory; + + ArMapId myMapId; + + ArFileParser *myLoadingParser; + + // std::string myConfigParam; + bool myIgnoreEmptyFileName; + bool myIgnoreCase; + + ArMapChangedHelper *myMapChangedHelper; + + /*** + // things for our config + bool myConfigProcessedBefore; + char myConfigMapName[MAX_MAP_NAME_LENGTH]; + ***/ + + bool myLoadingGotMapCategory; + // TODO: Need to change for multi scans + bool myLoadingDataStarted; + bool myLoadingLinesAndDataStarted; + + ArMapInfo * const myMapInfo; + ArMapObjects * const myMapObjects; + ArMapSupplement * const myMapSupplement; + + std::list myScanTypeList; + ArTypeToScanMap myTypeToScanMap; + ArMapScan * mySummaryScan; + + ArDataTagToScanTypeMap myDataTagToScanTypeMap; + + std::string myLoadingDataTag; + ArMapScan * myLoadingScan; + + ArMapInfo * const myInactiveInfo; + ArMapObjects * const myInactiveObjects; + + ArMapObjects * const myChildObjects; + + std::map myMapObjectNameToParamsMap; + + /// List of map file lines that were not recognized + std::list myRemainderList; + + ArTime myTimeMapInfoChanged; + ArTime myTimeMapObjectsChanged; + ArTime myTimeMapScanChanged; + ArTime myTimeMapSupplementChanged; + + // callbacks + ArRetFunctor1C myMapCategoryCB; + ArRetFunctor1C mySourcesCB; + ArRetFunctor1C myDataIntroCB; + + // Handler for unrecognized lines + ArRetFunctor1C myRemCB; + + bool myIsQuiet; + bool myIsReadInProgress; + bool myIsCancelRead; + +}; // end class ArMapSimple + +/// --------------------------------------------------------------------------- + +#endif // ARMAPCOMPONENTS_H + diff --git a/Legacy/Aria/include/ArMapInterface.h b/Legacy/Aria/include/ArMapInterface.h new file mode 100644 index 0000000..eee37f4 --- /dev/null +++ b/Legacy/Aria/include/ArMapInterface.h @@ -0,0 +1,1494 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +/*! \file ArMapInterface.h + * \brief Contains the set of interfaces that define the Aria maps. + * \date 06/27/08 + * \author K. Cunningham + * + * The methods that define the Aria maps are grouped into a set of smaller + * interfaces which are contained in this file. These include: + * + * - ArMapScanInterface : Methods related to scan data (e.g. points and + * lines) generally obtained from a specific sensor (such as the SICK laser + * or Hokuyo URG). + * + * - ArMapObjectsInterface : Methods related to the objects in a map. + * These include user-defined objects such as goals, docks, and forbidden + * lines. They also include special "data" types of objects that may be + * automatically created during the scanning process. + * + * - ArMapInfoInterface : Methods related to the various info arguments + * stored in a map. Examples of info include the map object type + * definitions and the routes and macros. + * + * - ArMapSupplementInterface : Methods used to access supplemental data + * associated with the map. This currently consists only of the latitude / + * longitude of the origin, but may be extended in the future. + * + * The primary interface implemented by all Aria maps is also contained in + * this file: + * + * - ArMapInterface : All of the methods that are available for an Aria map. + * This interface extends all of the above interfaces and contains a + * few additional file-related methods. + * + * In general, when passing an Aria map (pointer) as a parameter to a method, + * it is preferable to pass ArMapInterface *. This will allow for extension + * and different implementations of the interface. + * + *

  
+ *      ArMapScanInterface
+ *      ^
+ *      |    ArMapObjectsInterface
+ *      |    ^
+ *      |    |    ArMapInfoInterface
+ *      |    |    ^
+ *      |    |    |    ArMapSupplementInterface
+ *      |    |    |    ^  
+ *      |    |    |    | (extends)
+ *      |    |    |    |
+ *       ArMapInterface
+ *
+ * 
+**/ +#ifndef ARMAPINTERFACE_H +#define ARMAPINTERFACE_H + +#include "ariaTypedefs.h" +#include "ariaUtil.h" + +#include "ArMapObject.h" +#include "ArMapUtils.h" + +#include "ArArgumentBuilder.h" +#include "ArFunctor.h" +#include "ArHasFileName.h" +#include "ArMutex.h" + +#include +#include + +class ArFileParser; +class ArMapChangeDetails; +class ArMapObject; + + +// ============================================================================= +// ArMapScanInterface +// ============================================================================= + +/// The default scan type indicator, when an Aria map only has obstacle data of one type +#define ARMAP_DEFAULT_SCAN_TYPE "" +/// The scan type indicator used to obtain collective data from most or all obstacle data (see individual methods for how it is used for specific kinds of map data) +#define ARMAP_SUMMARY_SCAN_TYPE NULL + +/// Methods related to setting and retrieving the scan-related data in an Aria map. +/** + * ArMapScanInterface is an abstract class that defines the methods used + * to manipulate obstacle data in an Aria map. These generally include the + * points and lines detected by a particular sensor (a.k.a. scan type). +**/ +class ArMapScanInterface +{ +public: + + /// Determines whether the given scan type is the default (i.e. no prefix on the map tags) + AREXPORT static bool isDefaultScanType(const char *scanType); + /// Determines whether the given scan type represents the summary of all other scan types + AREXPORT static bool isSummaryScanType(const char *scanType); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + /// Default constructor + AREXPORT ArMapScanInterface() {} + /// Destructor + AREXPORT virtual ~ArMapScanInterface() {} + + AREXPORT virtual const char *getDisplayString + (const char *scanType = ARMAP_DEFAULT_SCAN_TYPE) = 0; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Point Methods + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + /// Returns a pointer to the map points for the specified scan. + /** + * Note that this returns a pointer to the object's internal vector. + * The map must be locked before this method is called, and must be + * unlocked after the caller has finished using the vector. + * @param scanType the const char * identifier of the scan type for + * which to return the points; must be non-NULL + * @return a pointer to the std::vector that contains the + * specified scan's points; NULL if the scanType is undefined for + * the map + **/ + AREXPORT virtual std::vector *getPoints + (const char *scanType = ARMAP_DEFAULT_SCAN_TYPE) = 0; + + /// Returns the lower left point (minimum x and y) of the scan's points. + /** + * @param scanType the const char * identifier of the scan type for + * which to return the minimum pose; if ARMAP_SUMMARY_SCAN_TYPE, then the + * minimum pose for all scans is returned + **/ + AREXPORT virtual ArPose getMinPose + (const char *scanType = ARMAP_DEFAULT_SCAN_TYPE) = 0; + + /// Returns the upper right point (maximum x and y) of the scan's points. + /** + * @param scanType the const char * identifier of the scan type for + * which to return the maximum pose; if ARMAP_SUMMARY_SCAN_TYPE, then the + * maximum pose for all scans is returned + **/ + AREXPORT virtual ArPose getMaxPose + (const char *scanType = ARMAP_DEFAULT_SCAN_TYPE) = 0; + + /// Returns the number of points in the specified scan. + /** + * @param scanType the const char * identifier of the scan type for + * which to return the point count; if ARMAP_SUMMARY_SCAN_TYPE, then the + * point count for all scans is returned + **/ + AREXPORT virtual int getNumPoints + (const char *scanType = ARMAP_DEFAULT_SCAN_TYPE) = 0; + + + /// Returns whether the point vector for the specified scan is sorted + /** + * Note that this method returns the state of the point vector when it + * was read from the file, or after setPoints has been called. If the + * application calls getPoints and directly manipulates the point vector's + * contents, then isSortedPoints will not necessarily be correct. + * + * @param scanType the const char * identifier of the scan type for + * which to return the sorted state; if ARMAP_SUMMARY_SCAN_TYPE, then this method + * returns true if and only if all scans have sorted points + **/ + AREXPORT virtual bool isSortedPoints + (const char *scanType = ARMAP_DEFAULT_SCAN_TYPE) const = 0; + + /// Sets the points (copies those passed in) + /** + * This method will sort the given points in ascending order (according + * to the ArPose less-than operator. If the points vector is already sorted, + * then set the isSortedPoints parameter to true in order to improve performance. + * @param points a pointer to the ArPose vector to be copied to the scan data + * @param scanType the const char * identifier of the scan type for which + * to set the points; must not be ARMAP_SUMMARY_SCAN_TYPE or NULL + * @param isSortedPoints a bool set to true if the points vector has already + * been sorted in ascending order + * @param changeDetails a pointer to the optional ArMapChangeDetails in which + * to store a description of the changes to the scan data; if NULL then the + * changes are not tracked. + * @see ArMapChangeDetails + **/ + AREXPORT virtual void setPoints(const std::vector *points, + const char *scanType = ARMAP_DEFAULT_SCAN_TYPE, + bool isSortedPoints = false, + ArMapChangeDetails *changeDetails = NULL) = 0; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Line Segment Methods + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + /// Returns a pointer to the line segments for the specified scan. + /** + * Note that this returns a pointer to the object's internal vector. + * The map must be locked before this method is called, and must be + * unlocked after the caller has finished using the vector. + * @param scanType the const char * identifier of the scan type for + * which to return the line segments; must be non-NULL + * @return a pointer to the std::vector that contains the + * specified scan's points; NULL if the scanType is undefined for + * the map + **/ + AREXPORT virtual std::vector *getLines + (const char *scanType = ARMAP_DEFAULT_SCAN_TYPE) = 0; + + /// Returns the lower left point (minimum x and y) of the scan's line segments. + /** + * @param scanType the const char * identifier of the scan type for + * which to return the minimum line segment pose; if ARMAP_SUMMARY_SCAN_TYPE, + * then the minimum line segment pose for all scans is returned + **/ + AREXPORT virtual ArPose getLineMinPose + (const char *scanType = ARMAP_DEFAULT_SCAN_TYPE) = 0; + + /// Returns the upper right point (maximum x and y) of the scan's line segments. + /** + * @param scanType the const char * identifier of the scan type for + * which to return the maximum line segment pose; if ARMAP_SUMMARY_SCAN_TYPE, + * then the maximum line segment pose for all scans is returned + **/ + AREXPORT virtual ArPose getLineMaxPose + (const char *scanType = ARMAP_DEFAULT_SCAN_TYPE) = 0; + + /// Returns the number of line segments in the specified scan. + /** + * @param scanType the const char * identifier of the scan type for + * which to return the line segment count; if ARMAP_SUMMARY_SCAN_TYPE, then the + * line segment count for all scans is returned + **/ + AREXPORT virtual int getNumLines + (const char *scanType = ARMAP_DEFAULT_SCAN_TYPE) = 0; + + /// Returns whether the line segment vector for the specified scan is sorted + /** + * Note that this method returns the state of the line segment vector when it + * was read from the file, or after setLines has been called. If the + * application calls getLines and directly manipulates the line segment vector's + * contents, then isSortedLines will not necessarily be correct. + * + * @param scanType the const char * identifier of the scan type for + * which to return the sorted state; if ARMAP_SUMMARY_SCAN_TYPE, then this method + * returns true if and only if all scans have sorted line segments + **/ + AREXPORT virtual bool isSortedLines(const char *scanType = ARMAP_DEFAULT_SCAN_TYPE) const = 0; + + + /// Sets the lines (copies those passed in) + /** + * This method will sort the given line segments in ascending order (according + * to the ArLineSegment less-than operator. If the vector is already sorted, + * then set the isSortedLiens parameter to true in order to improve performance. + * @param lines a pointer to the ArLineSegment vector to be copied to the scan data + * @param scanType the const char * identifier of the scan type for which + * to set the points; must not be ARMAP_SUMMARY_SCAN_TYPE or NULL + * @param isSortedLines a bool set to true if the line segment vector has already + * been sorted in ascending order + * @param changeDetails a pointer to the optional ArMapChangeDetails in which + * to store a description of the changes to the scan data; if NULL then the + * changes are not tracked. + * @see ArMapChangeDetails + **/ + AREXPORT virtual void setLines(const std::vector *lines, + const char *scanType = ARMAP_DEFAULT_SCAN_TYPE, + bool isSortedLines = false, + ArMapChangeDetails *changeDetails = NULL) = 0; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Other Attributes + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + /// Gets the resolution (-1 if none specified) + /** + * @param scanType the const char * identifier of the scan for which to return + * the resolution; if ARMAP_SUMMARY_SCAN_TYPE then the lowest resolution (highest + * numerical value) of all scans is returned + **/ + AREXPORT virtual int getResolution + (const char *scanType = ARMAP_DEFAULT_SCAN_TYPE) = 0; + + /// Sets the resolution (-1 if none specified) + /** + * @param resolution the int number of mm between the scan data point readings + * @param scanType the const char * identifier of the scan for which to return + * the resolution; must not be ARMAP_SUMMARY_SCAN_TYPE or NULL + * @param changeDetails a pointer to the optional ArMapChangeDetails in which + * to store a description of the changes to the scan data; if NULL then the + * changes are not tracked. + * @see ArMapChangeDetails + **/ + AREXPORT virtual void setResolution(int resolution, + const char *scanType = ARMAP_DEFAULT_SCAN_TYPE, + ArMapChangeDetails *changeDetails = NULL) = 0; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Persistence + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + // Writes the scan header information to the given functor; does not write the points or lines. + /** + * This method writes a text line for each of the scan header attributes + * (such as MinPose, MaxPose, NumPoints). Depending on the scan type, a + * prefix may be prepended to the keyword (e.g. HokuyoURGMinPose). + * + * @param functor the ArFunctor1 to which to write the scan header information + * (as text lines) + * @param endOfLineChars the const char * string to be appended to the end + * of each text line + * @param scanType the const char * identifier of the scan data to be written to + * the functor; must not be ARMAP_SUMMARY_SCAN_TYPE or NULL + * + **/ + AREXPORT virtual void writeScanToFunctor + (ArFunctor1 *functor, + const char *endOfLineChars, + const char *scanType = ARMAP_DEFAULT_SCAN_TYPE) = 0; + + /// Writes the scan data points to a functor. + /** + * A pointer to the entire data point vector is passed directly to the + * functor in order to improve performance. The functor must not + * modify the vector's contents. + * @param functor a pointer to the ArFunctor2 that takes the number of points + * and the vector of ArPoses, and writes the information + * @param scanType the const char * identifier of the scan points to be written; + * must not be ARMAP_SUMMARY_SCAN_TYPE or NULL + * @param keywordFunctor a pointer to an optional ArFunctor1 that writes a + * text line to introduce the associated ArPoses; if NULL, then the header is not + * written + **/ + AREXPORT virtual void writePointsToFunctor + (ArFunctor2 *> *functor, + const char *scanType = ARMAP_DEFAULT_SCAN_TYPE, + ArFunctor1 *keywordFunctor = NULL) = 0; + + /// Writes the map line segments to a functor. + /** + * A pointer to the entire data line segment vector is passed directly to the + * functor in order to improve performance. The functor must not + * modify the vector's contents. + * @param functor a pointer to the ArFunctor2 that takes the number of line + * segments and the vector of ArLineSegments, and writes the information + * @param scanType the const char * identifier of the scan points to be written; + * must not be ARMAP_SUMMARY_SCAN_TYPE or NULL + * @param keywordFunctor a pointer to an optional ArFunctor1 that writes a + * text line to introduce the associated ArLineSegments; if NULL, then the + * header is not written + **/ + AREXPORT virtual void writeLinesToFunctor + (ArFunctor2 *> *functor, + const char *scanType = ARMAP_DEFAULT_SCAN_TYPE, + ArFunctor1 *keywordFunctor = NULL) = 0; + + + /// Adds handlers for this scan data's header information to the given file parser + /** + * @param fileParser a pointer to the ArFileParser to which to add the handlers + * @return bool true if the handlers were successfully added; false if an error + * occurred + **/ + AREXPORT virtual bool addToFileParser(ArFileParser *fileParser) = 0; + + /// Removes the handlers for this scan data's header information from the given file parser + /** + * @param fileParser a pointer to the ArFileParser from which to remove the handlers + * @return bool true if the handlers were successfully removed; false if an error + * occurred + **/ + AREXPORT virtual bool remFromFileParser(ArFileParser *fileParser) = 0; + + + /// Reads a data point from the given line and adds it to this scan data. + /** + * The data point is expected to be two integers (x y), separated by whitespace. + * @param line the char * text line to be parsed + * @return bool true if the point was successfully read and added to this scan + * data; false if an error occurred + **/ + AREXPORT virtual bool readDataPoint( char *line) = 0; + + /// Reads a line segment from the given line and adds it to this scan data. + /** + * The line segment is expected to be four integers (x1 y1 x2 y2), separated + * by whitespace + * @param line the char * text line to be parsed + * @return bool true if the line segment was successfully read and added to + * this scan data; false if an error occurred + **/ + AREXPORT virtual bool readLineSegment( char *line) = 0; + + /*** Public for ArQClientMapProducer ***/ + /// Adds the specified data point to the scan data. + AREXPORT virtual void loadDataPoint(double x, double y) = 0; + /// Adds the specified line segment to the scan data. + AREXPORT virtual void loadLineSegment(double x1, double y1, + double x2, double y2) = 0; + +}; // end class ArMapScanInterface + + +// ============================================================================= +// ArMapObjectsInterface +// ============================================================================= + +/// Methods related to setting and retrieving the objects in an Aria map. +/** + * ArMapObjectsInterface is an abstract class that defines the methods used + * to manipulate the ArMapObjects that are contained in an Aria map. +**/ +class ArMapObjectsInterface +{ + +public : + + /// Constructor + AREXPORT ArMapObjectsInterface() {} + + /// Destructor + AREXPORT virtual ~ArMapObjectsInterface() {} + + + /// Returns the first map object of given name and type, or NULL if none is found + /** + * A pointer to the actual map object is returned. It is not safe to + * store this pointer because it will be deleted when the map is changed. + * If the caller needs the map object, then it should create its own copy. + * This method is not thread-safe. + * + * @param name the const char * name of the object to be found; if NULL then + * any object of the specified type is a match + * @param type the const char * type of the object to be found; if NULL then + * search all object types + * @param isIncludeWithHeading a bool set to true if the given type represents a + * pose and both "heading-less" and "with-heading" objects should be searched; + * if false, then only objects of the exact type are searched + * @return ArMapObject * the matching map object, or NULL if none found + **/ + AREXPORT virtual ArMapObject *findFirstMapObject(const char *name, + const char *type, + bool isIncludeWithHeading = false) = 0; + + /// Returns the map object of given name and type, or NULL if none is found + /** + * A pointer to the actual map object is returned. It is not safe to + * store this pointer because it will be deleted when the map is changed. + * If the caller needs the map object, then it should create its own copy. + * This method is not thread-safe. + * + * @param name the const char * name of the object to be found + * @param type the const char * type of the object to be found; if NULL then + * search all object types + * @param isIncludeWithHeading a bool set to true if the given type represents a + * pose and both "heading-less" and "with-heading" objects should be searched; + * if false, then only objects of the exact type are searched + * @return ArMapObject * the matching map object, or NULL if none found + **/ + AREXPORT virtual ArMapObject *findMapObject(const char *name, + const char *type = NULL, + bool isIncludeWithHeading = false) = 0; + + + /// Returns a list of all map objects of the specified type. + /** + * A list of pointers to the actual map objects is returned. It is not + * safe to store these pointers because they will be deleted when the map + * is changed. If the caller needs the map objects at a later time, then + * it should create its own copy of each object in the list. + * This method is not thread-safe. + * + * @param type the const char * type of the objects to be found; if NULL then + * all objects are returned + * @param isIncludeWithHeading a bool set to true if the given type represents a + * pose and both "heading-less" and "with-heading" objects should be searched; + * if false, then only objects of the exact type are searched + * @return a list of pointers to all of the ArMapObject's that match the given + * type + **/ + AREXPORT virtual std::list findMapObjectsOfType + (const char *type, + bool isIncludeWithHeading = false) = 0; + + /// Returns a pointer to the internal list of map objects. + /** + * Ideally, callers of this method should not use the pointer to modify + * the map objects directly. It is preferable to modify a copy and then + * call setMapObjects. + * + * It is not safe to store the returned pointer list because the pointers will + * be deleted when the map is changed. If the caller needs the map objects at + * a later time, then it should create its own copy of each object in the list. + * This method is not thread-safe. + * @return a list of pointers to all of the ArMapObject's in the map + **/ + AREXPORT virtual std::list *getMapObjects(void) = 0; + + /// Sets the map objects (copies those passed in) + /** + * This method sets its internal list to contain a copy of all of the given + * map objects. Any map objects which were originally in the list but are + * no longer referenced are deleted. The list of map objects will be sorted + * by increasing pose (i.e. objects in the upper left will be placed before + * objects in the lower right). + * This method is not thread-safe. + * + * @param mapObjects a pointer to the list of ArMapObject *'s to be copied + * @param isSortedObjects a bool set to true if the objects in the given + * list have already been sorted by increasing pose; this can improve + * the performance of this method + * @param changeDetails an optional pointer to the ArMapChangeDetails in + * which to accumulate a description of the changes to the map objects; + * if NULL, then changes are not tracked + * @see ArMapChangeDetails + **/ + AREXPORT virtual void setMapObjects + (const std::list *mapObjects, + bool isSortedObjects = false, + ArMapChangeDetails *changeDetails = NULL) = 0; + + + // TODO Seems like it would be awfully nice to have an addMapObject and a + // removeMapObject method + + + /// Writes the list of map objects to a text-based functor. + /** + * This method writes a Cairn text line for each of the ArMapObject's. + * This method is not thread-safe. + * + * @param functor a pointer to the ArFunctor1 that writes the text lines + * @param endOfLineChars the const char * string that indicates the end of + * each text line + **/ + AREXPORT virtual void writeObjectListToFunctor(ArFunctor1 *functor, + const char *endOfLineChars) = 0; + + }; // end class ArMapObjectsInterface + + +// ============================================================================= +// ArMapInfoInterface +// ============================================================================= + +/// Methods related to setting and retrieving the various "info" tags in an Aria map. +/** + * ArMapInfoInterface is an abstract class that defines the methods used to + * get and set an Aria map's "info" arguments. An Aria map may have one or more + * categories of info, each implemented by an ordered list of ArArgumentBuilder's. + * The ArMapInfoInterface defines access to a collection of these info categories. +**/ +class ArMapInfoInterface +{ +public : + + + AREXPORT static const char *MAP_INFO_NAME; + AREXPORT static const char *META_INFO_NAME; + AREXPORT static const char *TASK_INFO_NAME; + AREXPORT static const char *ROUTE_INFO_NAME; + AREXPORT static const char *SCHED_TASK_INFO_NAME; + AREXPORT static const char *SCHED_INFO_NAME; + AREXPORT static const char *CAIRN_INFO_NAME; + AREXPORT static const char *CUSTOM_INFO_NAME; + + + + /// Constructor + AREXPORT ArMapInfoInterface() {} + + /// Destructor + AREXPORT virtual ~ArMapInfoInterface() {} + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Getters + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + /// Returns the number of info categories that are contained in this collection. + AREXPORT virtual int getInfoCount() const = 0; + + /// Returns a list of the info category names that are contained in this collection. + /** + * @return the list of string names of the info categories (for example, + * MAP_INFO_NAME, META_INFO_NAME, ...) + * This method is not thread-safe. + **/ + AREXPORT virtual std::list getInfoNames() const = 0; + + + /// Returns the arguments for the specified info category; or NULL if none found + /** + * This method returns a pointer to the actual ArArgumentBuilder list that is + * contained in the map. It is not safe to store these pointers because they + * will be deleted when the map is changed. If the caller needs the info + * arguments at a later time, then it should create its own copy of each + * argument in the list. + * This method is not thread-safe. + * + * @param infoName the unique char * identifier of the info category to be + * returned; must be non-NULL and a member of + * @return std::list * a pointer to the specified Info + * list; NULL if infoType was invalid + **/ + AREXPORT virtual std::list *getInfo(const char *infoName) = 0; + + + /// Gets the strings for the specified Info category. + /** + * @deprecated use getInfo(const char *) instead + * + * This method returns a pointer to the actual ArArgumentBuilder list that is + * contained in the map. It is not safe to store these pointers because they + * will be deleted when the map is changed. If the caller needs the info + * arguments at a later time, then it should create its own copy of each + * argument in the list. + * This method is not thread-safe. + * + * @param infoType the int ID of the Info category; must be >= 0 and less than + * numInfos + * @return std::list * a pointer to the specified Info + * list; NULL if infoType was invalid + **/ + AREXPORT virtual std::list *getInfo(int infoType) = 0; + + /// Gets the map info strings + /** + * This method is equivalent to getInfo(MAP_INFO_NAME). + * @see getInfo + **/ + AREXPORT virtual std::list *getMapInfo(void) = 0; + + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Setters + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + /// Sets the contents of the specified Info category (copies those passed in) + /** + * This method is not thread-safe. + * @param infoName the unique const char * identifier of the + * @param infoList the std::list * that defines the + * Info category's contents; NULL to clear the Info + * @param changeDetails a pointer to the ArMapChangeDetails in which to + * accumulate changes to the map's info lines; if NULL, then changes are + * not tracked + * @return bool set to true if the contents were successfully set; false, + * if an error occurred + * @see ArMapChangeDetails + * @see setInfoNames + **/ + AREXPORT virtual bool setInfo(const char *infoName, + const std::list *infoList, + ArMapChangeDetails *changeDetails = NULL) = 0; + + + /// Sets the contents of the specified Info category (copies those passed in) + /** + * @deprecated use setInfo(const char *,const std::list *,ArMapChangeDetails*) + * + * This method is not thread-safe. + * @param infoType the int ID of the Info category to be set + * @param infoList the std::list * that defines the + * Info category's contents; NULL to clear the Info + * @param changeDetails a pointer to the ArMapChangeDetails in which to + * accumulate changes to the map's info lines; if NULL, then changes are + * not tracked + * @return bool set to true if the contents were successfully set; false, + * if infoType was invalid + * @see ArMapChangeDetails + **/ + AREXPORT virtual bool setInfo(int infoType, + const std::list *infoList, + ArMapChangeDetails *changeDetails = NULL) = 0; + + + /// Sets the map info (copies those passed in) + /** + * This method is equivalent to setInfo(MAP_INFO, mapInfo, changeDetails); + **/ + AREXPORT virtual bool setMapInfo(const std::list *mapInfo, + ArMapChangeDetails *changeDetails = NULL) = 0; + + + //AREXPORT virtual bool setInfoNames(const std::list &infoNameList) = 0; + + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Miscellaneous + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + /// Writes the info collection to a text-based functor. + /** + * This method writes a text line for each of the info's ArArgumentBuilders. + * This method is not thread-safe. + * + * @param functor a pointer to the ArFunctor1 that writes the text lines + * @param endOfLineChars the const char * string that indicates the end of + * each text line + **/ + AREXPORT virtual void writeInfoToFunctor + (ArFunctor1 *functor, + const char *endOfLineChars) = 0; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Deprecated + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + /// List of the standard Info categories defined for Aria maps + /** + * @deprecated + **/ + enum InfoType { + MAP_INFO, ///< MapInfo lines that define the valid map object types + FIRST_INFO = MAP_INFO, ///< First value in the enumeration + META_INFO, ///< MetaInfo lines that provide overview info about the map + TASK_INFO, ///< TaskInfo lines that define the available robot tasks + ROUTE_INFO, ///< RouteInfo lines that are the goal assocs, macros, and routes + SCHED_TASK_INFO, ///< SchedTaskInfo that define special tasks that may be scheduled + SCHED_INFO, ///< SchedInfo lines that are the schedules of route patrols + CAIRN_INFO, ///< CairnInfo lines that contain optional arguments for map objects + CUSTOM_INFO, ///< CustomInfo lines contain application specific data + LAST_INFO = CUSTOM_INFO ///< Last value in the enumeration + }; + + /** + * @deprecated + **/ + enum { + INFO_COUNT = LAST_INFO + 1 ///< Number of standard Info categories + }; + + + /// Returns the name of the specified Info type + /** + * @deprecated + * The info name is the "xInfo:" tag that appears at the beginning of each text + * line. If subclasses define additional Info categories, then they must override + * this method. + * @param infoType the int ID of the Info category + * @return const char * the name of the specified Info category; or NULL if not + * found + **/ + AREXPORT virtual const char *getInfoName(int infoType) = 0; + + +}; // end class ArMapInfoInterface + + +// ============================================================================= +// ArMapSupplementInterface +// ============================================================================= + +/// Methods related to miscellaneous extra data in an Aria map. +/** + * ArMapSupplementInterface is basically a repository for any pieces of data + * that do not fit in the other categories (i.e. scan data, map objects, or + * info). It currently stores the optional latitude/longitude information. +**/ +class ArMapSupplementInterface +{ +public: + + /// Default constructor + AREXPORT ArMapSupplementInterface() {} + + /// Destructor + AREXPORT virtual ~ArMapSupplementInterface() {} + + /// Returns whether this map has an origin specified in latitude/longitude (and altitude) + AREXPORT virtual bool hasOriginLatLongAlt() = 0; + + /// Returns the latitude/longitude origin; valid only if hasOriginLatLongAlt returns true + AREXPORT virtual ArPose getOriginLatLong() = 0; + + /// Gets the altitude of the origin; valid only if hasOriginLatLongAlt returns true + /** + * @return double the altitude (in meters) of the origin + **/ + AREXPORT virtual double getOriginAltitude() = 0; + + /// Sets the latitude/longitude and altitude of the origin. + /** + * @param hasOriginLatLong a bool set to true if the map has latitude/longitude + * information for the origin + * @param originLatLong the ArPose that specifies the latitude/longitude of the + * origin + * @param altitude the double altitude (in meters) of the origin + * @param changeDetails a pointer to the optional ArMapChangeDetails in which + * to store a description of the changes to the scan data; if NULL then the + * changes are not tracked. + **/ + AREXPORT virtual void setOriginLatLongAlt + (bool hasOriginLatLong, + const ArPose &originLatLong, + double altitude, + ArMapChangeDetails *changeDetails = NULL) = 0; + + /// Writes the supplemental data to the given functor + /** + * @param functor the ArFunctor1 to which to write the supplemental data + * (as text lines) + * @param endOfLineChars the const char * string to be appended to the end + * of each text line + **/ + AREXPORT virtual void writeSupplementToFunctor + (ArFunctor1 *functor, + const char *endOfLineChars) = 0; + +}; // end class ArMapSupplementInterface + + +// ============================================================================= +// ArMapInterface +// ============================================================================= + +/** + * ArMapInterface defines the methods that are available on all Aria maps. + * These maps represent the operating space of a robot, and can be used for + * space searching, localizing, navigating etc. The types of data stored + * in a map include sensable obstacles (e.g. walls and furniture in a room) + * represented either as a collection of data points (similar to a raster + * or bit map, useful for high resolution sensors like a laser), or lines + * (a vector map, useful for low resolution sensors like the sonar), + * goals, and other points or regions of interest ("map objects"). + * + * The methods in ArMapInterface can be broadly categorized as follows: + * - Scan Methods: These provide access the sensable obstacles that are + * represented as a collection of data points or lines. These are + * typically generated during the scanning process (i.e. the creation of + * the .2d file). If more than one sensor is used, then the data is + * organized on a per-sensor basis. The scan methods are grouped into + * the ArMapScanInterface. + * - Object Methods: These provide access to the "high-level" objects + * in the environment. Such objects include goals, docks, forbidden + * areas, and other user-defined points of interest. They may also + * include special data objects that are actually part of the operating + * environment and are generally added automatically and are not editable + * by the user. The object methods are grouped into the + * ArMapObjectsInterface. + * - Info Methods: A wide variety of supporting information is included + * in various "info" categories. This includes definitions for the + * types of map objects that can be stored in the map. It also includes + * various optional features such as macros and schedules. The info + * methods are grouped into the ArMapInfoInterface. + * - Extra Data Methods: These are essentially the "leftovers" -- i.e. + * methods that are related directly to map data but which do not + * fit into any of the above categories. They are defined in the + * ArMapSupplementInterface. + * - Callback Methods: Users of the Aria map may install callbacks onto + * the map in order to be notified when the map contents has changed. + * These methods are defined below. + * - File and I/O Methods: Methods to read and write map files are also + * included below. In addition, the MD5 checksum of the map contents + * may be calculated. + * + * TODO: + * - Possibly make the calculation of checksums optional? +**/ +class ArMapInterface : public ArHasFileName, + public ArMapInfoInterface, + public ArMapObjectsInterface, + public ArMapScanInterface, + public ArMapSupplementInterface +{ +public: + + enum { + MAX_MAP_NAME_LENGTH = 512 ///< Maximum length of the map file's name + }; + + AREXPORT static const char *MAP_CATEGORY_2D; + AREXPORT static const char *MAP_CATEGORY_2D_MULTI_SOURCES; + /// Superset of multi-sources; includes advanced Info types, CairnInfo and CustomInfo + AREXPORT static const char *MAP_CATEGORY_2D_EXTENDED; + /// Superset of extended; includes group objects and parent maps + AREXPORT static const char *MAP_CATEGORY_2D_COMPOSITE; + + + /// Helper method creates a full file path name from the given components. + AREXPORT static std::string createRealFileName(const char *baseDirectory, + const char *fileName, + bool isIgnoreCase); + + /// Constructor + AREXPORT ArMapInterface() {} + + /// Destructor + AREXPORT virtual ~ArMapInterface(void) {} + + + /// Clears the map, removing all info, objects and data points and lines. + AREXPORT virtual void clear() = 0; + + /// Sets this map to be "equivalent" to the given other map. + /** + * Modifies this map so that is effectively a copy of the given map. All info, + * objects, and data points and lines in the other map are copied and stored in + * this map. + * @param other a pointer to the ArMapInterface to be copied; must not be NULL + * @return bool true if the map was successfully copied to this one; false if + * an error occurred + **/ + AREXPORT virtual bool set(ArMapInterface *other) = 0; + + /// Creates a new map that is "equivalent" to this map. + /** + * Creates a new map that is effectively a copy of this map. Note, however, + * that the returned map may not be of exactly the same class (so the term + * "clone" is being used somewhat loosely). In particular, if the active ArMap + * that is associated with the robot configuration is cloned, then the resulting + * map will be simpler and not associated with the robot configuration. + * @return ArMapInterface * a new copy of this map + * @javanote Use cloneMap() instead + **/ + AREXPORT virtual ArMapInterface *clone() = 0; + + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Scan Types Methods + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + /// Returns a list of the scan types that are defined for this map + /** + * This method is not thread-safe. + * + * @return std::list a list of the scan types that are defined + * for this map + **/ + AREXPORT virtual std::list getScanTypes() const = 0; + + /// Sets the scan types that are defined for this map + /** + * This method clears all of the exisiting scans (i.e. point and line data). + * This method is not thread-safe. + * + * @param scanTypeList the list of scan type string identifiers to be set; + * the list must not contain any duplicate entries + * @return bool true if the scan types were successfully set; false otherwise + **/ + AREXPORT virtual bool setScanTypes(const std::list &scanTypeList) = 0; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Locking / Semaphore Method + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + /// Lock the map instance + AREXPORT virtual int lock() = 0; + /// Try to lock the map instance without blocking + AREXPORT virtual int tryLock() = 0; + /// Unlock the map instance + AREXPORT virtual int unlock() = 0; + + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Map Changed / Callback Methods + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + /// Function that will call the map changed CBs if needed + /** + * Users of Aria maps should invoke this method after making any changes to the + * map. It causes the installed map changed handlers to be invoked. + * + * This method is not thread-safe. It should be surrounded by calls to lock() + * and unlock(). For example: + * + * + * std::list newMapObjects; + * // Add some objects... + * myMap->lock(); + * myMap->setMapObjects(&newMapObjects); + * myMap->mapChanged(); + * myMap->unlock(); + * + * + * Note that this method is automatically invoked under some circumstances + * (such as when the map file is re-read following a change to the robot + * configuration). Also note that this method will not invoke any callbacks + * if the map has not been modified via an explicit call to a set method. + * + * @see addMapChangedCB + * @see addPreMapChangedCB + **/ + AREXPORT virtual void mapChanged(void) = 0; + + + /// Adds a callback that is invoked when the map has been changed. + /** + * The given functor should assume that the map has been lock()-ed when + * it is invoked. It should also not attempt to make changes to the + * mapChanged() callback list during the invoke method. + * This method is not thread-safe. + * + * This method is just a wrapper for compatibility, the one that + * takes position as an integer is the main one that should be used + * now. + * + * @param functor a pointer to the ArFunctor to be invoked; must be non-NULL + * @param position the ArListPos::Pos indication at which to add the functor + * (i.e. at the beginning or at the end of the callback list) + **/ + AREXPORT virtual void addMapChangedCB(ArFunctor *functor, + ArListPos::Pos position); + + + /// Adds a callback that is invoked when the map has been changed. + /** + * The given functor should assume that the map has been lock()-ed when + * it is invoked. It should also not attempt to make changes to the + * mapChanged() callback list during the invoke method. + * This method is not thread-safe. + * + * @param functor a pointer to the ArFunctor to be invoked; must be non-NULL + * + * @param position this indicates the order in which the functors + * will be called, the nominal range is 0 to 100, highest is called first + **/ + AREXPORT virtual void addMapChangedCB + (ArFunctor *functor, + int position = 50) = 0; + + /// Removes a callback called when the map has been changed + /** + * This method is not thread-safe. + * + * @param functor a pointer to the ArFunctor to be removed; must be non-NULL + **/ + AREXPORT virtual void remMapChangedCB(ArFunctor *functor) = 0; + + /// Adds a callback called before the map changed callbacks are called + /** + * The "pre-map-changed callbacks" are invoked *after* the map has been + * changed, but before the other "map-changed callbacks" are invoked. + * This method is not thread-safe. + * + * This method is just a wrapper for compatibility, the one that + * takes position as an integer is the main one that should be used + * now. + * + * @param functor a pointer to the ArFunctor to be invoked; must be non-NULL + * @param position the ArListPos::Pos indication at which to add the functor + * (i.e. at the beginning or at the end of the callback list) + * + * @swignote call as addPreMapChangedCBPos() if passing an ArListPos.Pos + * object for @a position rather than an int + **/ + AREXPORT virtual void addPreMapChangedCB(ArFunctor *functor, ArListPos::Pos position); + + /// Adds a callback called before the map changed callbacks are called + /** + * The "pre-map-changed callbacks" are invoked *after* the map has been + * changed, but before the other "map-changed callbacks" are invoked. + * This method is not thread-safe. + * + * @param functor a pointer to the ArFunctor to be invoked; must be non-NULL + * + * @param position this indicates the order in which the functors + * will be called, the nominal range is 0 to 100, highest is called + * first + **/ + AREXPORT virtual void addPreMapChangedCB + (ArFunctor *functor, + int position = 50) = 0; + + + /// Removes the specified "pre-map-changed callback". + /** + * This method is not thread-safe. + * + * @param functor a pointer to the ArFunctor to be removed; must be non-NULL + **/ + AREXPORT virtual void remPreMapChangedCB(ArFunctor *functor) = 0; + + + /// Sets the level at which to log information about the map changed callbacks + AREXPORT virtual void setMapChangedLogLevel(ArLog::LogLevel level) = 0; + + /// Returns the level at which information about the map changed callbacks is logged + AREXPORT virtual ArLog::LogLevel getMapChangedLogLevel(void) = 0; + + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Persistence + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + /// Writes all of the map to the given text-based functor + /** + * This method is not thread-safe + * @param functor a pointer to the ArFunctor1 to which to write the map + * header as text lines + * @param endOfLineChars the const char * string to use as an end-of-line + * indicator + **/ + AREXPORT virtual void writeToFunctor(ArFunctor1 *functor, + const char *endOfLineChars) = 0; + + /// Writes the map header information and objects to a text-based functor. + /** + * This method writes all of the map scan headers, the info arguments, and + * the Cairn map objects to the given functor. It does not write the actual + * scan point or line segment data (nor the header lines that introduce the + * data). + * This method is not thread-safe. + * + * @param functor a pointer to the ArFunctor1 to which to write the map + * header as text lines + * @param endOfLineChars the const char * string to use as an end-of-line + * indicator + * @param isOverrideAsSingleScan a bool set to true if only a single scan + * header should be written; this is generally the "summary scan" and is + * used to maintain backwards compatibility with client applications that + * do not expect multiple scan types in a single map. + * @param maxCategory if given, limit map category + **/ + AREXPORT virtual void writeObjectsToFunctor(ArFunctor1 *functor, + const char *endOfLineChars, + bool isOverrideAsSingleScan = false, + const char *maxCategory = NULL) = 0; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // File I/O Methods + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + /// Adds a callback to be invoked before the map file is written. + /** + * @param functor the ArFunctor * callback to be added + * @param position the ArListPos::Pos that specifies whether the callback + * should be added at the front or the back of the list + **/ + AREXPORT virtual void addPreWriteFileCB(ArFunctor *functor, + ArListPos::Pos position = ArListPos::LAST) = 0; + + /// Removes the given callback from the list of pre-write callbacks. + /** + * @param functor the ArFunctor * callback to be removed + **/ + AREXPORT virtual void remPreWriteFileCB(ArFunctor *functor) = 0; + + /// Adds a callback to be invoked after the map file is written. + /** + * @param functor the ArFunctor * callback to be added + * @param position the ArListPos::Pos that specifies whether the callback + * should be added at the front or the back of the list + **/ + AREXPORT virtual void addPostWriteFileCB(ArFunctor *functor, + ArListPos::Pos position = ArListPos::LAST) = 0; + + /// Removes the given callback from the list of post-write callbacks. + /** + * @param functor the ArFunctor * callback to be removed + **/ + AREXPORT virtual void remPostWriteFileCB(ArFunctor *functor) = 0; + +#ifndef SWIG + /// Reads the map from the specified file + /** + * If the file is successfully read into the map, then this method calls + * mapChanged() afterwards to invoke the installed callbacks. + * + * This method automatically calls lock() and unlock() during operation. Do + * not call this method if the map is already locked. + * + * @param fileName the name of the file to read; Unless an absolute path + * to a file is given (starting with "/" or "\" or, on Windows, a drive letter + * root such as "C:\", "D:\", etc.), it is combined + * with this map's base directory (see getBaseDirectory()) to form the complete file path name; must be + * non-NULL + * @param errorBuffer a pointer to a char buffer in which specific read errors + * can be recorded; if NULL, then the return value is the only success indication + * @param errorBufferLen the size_t of the error buffer + * @param md5DigestBuffer an optional pointer to a buffer in which to store the + * calculated checksum of the map; if NULL, then the checksum is not output + * @param md5DigestBufferLen the size_t of the checksum buffer + * @return bool true if the file was successfully read and the map was populated; + * false if an error occurred + * @see ArMD5Calculator + **/ + AREXPORT virtual bool readFile(const char *fileName, + char *errorBuffer = NULL, + size_t errorBufferLen = 0, + unsigned char *md5DigestBuffer = NULL, + size_t md5DigestBufferLen = 0) = 0; + + /// Writes the map to the specified file + /** + * By default, this method automatically calls lock() and unlock() during its + * operation. If the map is already locked when the file needs to be written, + * then set the internalCall parameter to true to override the default locking + * behavior + * + * @param fileName the const char * name of the file to written; it is combined + * with the getBaseDirectory() to form the complete file path name; must be + * non-NULL + * @param internalCall a bool set to true if writeFile is being called while + * the map is already locked; set to false to indicate that the map should + * lock itself during the method + * @param md5DigestBuffer an optional pointer to a buffer in which to store the + * calculated checksum of the map; if NULL, then the checksum is not output + * @param md5DigestBufferLen the size_t of the checksum buffer + * @param fileTimestamp the time_t to which to set the file write time; in + * general, this should be left as -1 to indicate that the actual write time is + * desired; a real time value can be used to synchronize the map across many + * robots + * @return bool true if the file was successfully written; false if an error + * occurred + * @see ArMD5Calculator + **/ + AREXPORT virtual bool writeFile(const char *fileName, + bool internalCall = false, + unsigned char *md5DigestBuffer = NULL, + size_t md5DigestBufferLen = 0, + time_t fileTimestamp = -1) = 0; +#endif + +#ifndef SWIG + /// Returns information about the map file that was read. + /** @swigomit */ + AREXPORT virtual struct stat getReadFileStat() const = 0; +#endif + + /// Retrieves the map ID. + /** + * The map ID is a unique identifier based on the map file name and the + * checksum data. (Perhaps more accurately, it is highly likely to be + * unique during normal usage.) + * @param mapIdOut a pointer to the ArMapId to be set + * @param isInternalCall a bool set to true only when getMapId is called + * within the context of a method that has already locked the map; if + * false, then the map is locked by this method + * @return bool true if the map ID was successfully set; false, otherwise + **/ + AREXPORT virtual bool getMapId(ArMapId *mapIdOut, + bool isInternalCall = false) = 0; + + /// Calculates the checksum of the map. + /** + * @param md5DigestBuffer the unsigned char buffer in which to store + * the calculated checksum + * @param md5DigestBufferLen the length of the md5DigestBuffer; should + * be ArMD5Calculator::DIGEST_LENGTH + * @return bool true if the checksum was successfully calculated; + * false if an error occurrred + * @see ArMD5Calculator + **/ + AREXPORT virtual bool calculateChecksum(unsigned char *md5DigestBuffer, + size_t md5DigestBufferLen) = 0; + + + /// Gets the base directory + AREXPORT virtual const char *getBaseDirectory(void) const = 0; + /// Sets the base directory + AREXPORT virtual void setBaseDirectory(const char *baseDirectory) = 0; + + /// Gets the temp directory + AREXPORT virtual const char *getTempDirectory(void) const = 0; + /// Sets the temp directory + AREXPORT virtual void setTempDirectory(const char *tempDirectory) = 0; + + + /// Prepends the appropriate directory information on the given filename. + AREXPORT virtual std::string createRealFileName(const char *fileName) = 0; + + /// Gets the fileName that was loaded + AREXPORT virtual const char *getFileName(void) const = 0; + + /// Sets the name of the source and the file from which the map was loaded. + /** + * This method is primarily used to track when a map has been received + * from the central server or another robot. The source and file name + * can be retrieved from the map ID. + * @param sourceName the const char * name of the central server or robot + * from which the map was obtained + * @param fileName the const char * name of the map file on the source + * @param isInternalCall a bool set to true if this method is being called + * while the map is locked; if false, then this method will lock the map + **/ + AREXPORT virtual void setSourceFileName(const char *sourceName, + const char *fileName, + bool isInternalCall = false) = 0; + + + + /// Determines whether the map file needs to be re-read. + /** + * This method is primarily applicable to the active Aria map that is + * associated with the robot configuration. It checks to see if the map + * file has been modified since it was read, and re-reads it if necessary. + * The method may do nothing for "simpler" maps. + **/ + AREXPORT virtual bool refresh() = 0; + + /// Sets whether we ignore empty file names or fail if we encounter one + /** + * This method is primarily applicable to the active Aria map that is + * associated with the robot configuration. + **/ + virtual void setIgnoreEmptyFileName(bool ignore) = 0; + /// Gets whether we ignore empty file names or fail if we encounter one + /** + * This method is primarily applicable to the active Aria map that is + * associated with the robot configuration. + **/ + virtual bool getIgnoreEmptyFileName(void) = 0; + /// Sets whether we ignore case or not + /** + * This method is primarily applicable to the active Aria map that is + * associated with the robot configuration. + **/ + virtual void setIgnoreCase(bool ignoreCase = false) = 0; + /// Gets whether we ignore case or not + /** + * This method is primarily applicable to the active Aria map that is + * associated with the robot configuration. + **/ + virtual bool getIgnoreCase(void) = 0; + + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Inactive Section + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + /// Provides direct access to the inactive map info. + /** + * The "inactive" info is a section of the Aria map that applications may + * use to store "_XInfo:" lines that are not currently active or applicable. + * The inactive info will be written to the map file, but it will not be + * included in any of the inherited ArMapInfoInterface calls (e.g. getInfo(type)). + * This is primarily intended for advanced specialized use where something + * needs to be removed from the map file, but it may be necessary to restore + * it later. + * This method is not thread-safe. + * @return ArMapInfoInterface * a pointer to the inactive map info section + **/ + AREXPORT virtual ArMapInfoInterface *getInactiveInfo() = 0; + + /// Provides direct access to the inactive map objects. + /** + * The "inactive" objects is a section of the Aria map that applications may + * use to store "_Cairn" lines that are not currently active or applicable. + * The inactive objects will be written to the map file, but they will not be + * included in any of the inherited ArMapObjectsInterface calls + * (e.g. getMapObjects()). This is primarily intended for advanced specialized + * use where an object needs to be removed from the map file, but it may be + * necessary to restore it later. + * This method is not thread-safe. + * @return ArMapObjectsInterface * a pointer to the inactive map objects section + **/ + AREXPORT virtual ArMapObjectsInterface *getInactiveObjects() = 0; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Child Objects Section + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + /// Provides direct access to the child map objects which are used to define group templates. + AREXPORT virtual ArMapObjectsInterface *getChildObjects() = 0; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Miscellaneous + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + /// Returns the optional parameters associated with a map object, or NULL if none. + /** + * The Aria map provides an advanced feature that allows a parameter list + * to be defined for custom map object types. (Refer to the ArMap MapFileFormat + * for more information.) + * + * This convenience method provides access to the parameter values for a + * specified map object. It is basically a shortcut for searching and + * parsing the CairnInfo argument list. Unlike the CairnInfo arguments + * (which also include an introduction and map object name), the + * argument builder returned by this method only contains the parameter + * values. Also note that if the argument builder contains string + * parameters, then they may be surrounded by quotes. + * + * The returned pointer should not be stored, modified, or deleted. + * + * See setMapObjectParams for important information about changing the + * parameter values or the associated map object. + * + * This method is not thread-safe. (The call and use of the returned + * ArArgumentBuilder should be surrounded by calls to lock()/unlock().) + * + * @param mapObjectName the unique char * name of the map object whose + * parameters are to be retrieved + * @return ArArgumentBuilder * a pointer to the map object's parameter + * values; + **/ + AREXPORT virtual ArArgumentBuilder *findMapObjectParams + (const char *mapObjectName) = 0; + + + /// Sets the optional parameters associated with a map object. + /** + * This method sets the parameter values for the specified map object. + * It should be used only for custom map object types that have a + * parameter list defined in the MapInfo. (Refer to the ArMap MapFileFormat + * for more information.) + * + * Like findMapObjectParams(), this is basically a convenience method + * that simplifies access to the data stored in the CairnInfo argument + * list. + * + * If the given params is non-NULL, then it is copied and stored in + * the map. (Note that this deletes the pointer previously returned by + * findMapObjectParams(mapObjectName). Do not store that pointer.) + * It is entirely the caller's responsibility to ensure that the + * params arg count and types are correct. + * + * If the given params is NULL, then the parameter information for the + * map object is cleared. If a mapObjectWithParams is to be deleted, + * then setMapObjectParams(mapObjectWithParams->getName(), NULL) must + * be called first. + * + * @param mapObjectName the unique char * name of the map object whose + * parameters are to be updated + * @param params the ArArgumentBuiler * containing the new parameter + * values; if NULL, then the parameter information for the map object + * is deleted + * @param changeDetails an optional pointer to the ArMapChangeDetails in + * which to accumulate a description of the changes to the map; if NULL, + * then changes are not tracked + * @see ArMapChangeDetails + */ + AREXPORT virtual bool setMapObjectParams(const char *mapObjectName, + ArArgumentBuilder *params, + ArMapChangeDetails *changeDetails = NULL) = 0; + + + /// Returns a list of the map file lines that were not recognized. + /** + * Ideally, the returned list should be empty. The remainder list is + * primarily used to determine whether the editor is up-to-date for the + * current map version and to try to minimize lost data. + * + * Note that this method returns a pointer to the actual list that is stored + * in the map object. It is not safe to store this pointer. + * + * This method is not thread-safe. + **/ + AREXPORT virtual std::list *getRemainder() = 0; + + /// Turn on this flag to reduce the number of verbose log messages. + AREXPORT virtual void setQuiet(bool isQuiet) = 0; + + + /** Public for ArQMapProducer **/ + + /// Parses a map line + AREXPORT virtual bool parseLine(char *line) = 0; + /// Says that the parsing by lines is done and to use the parsed data + AREXPORT virtual void parsingComplete(void) = 0; + + // When loading a map, returns whether all header, objects, and lines have completed loading. + /** + * This value returns true once the first DATA tag has been reached. + * The rest of the map contains data points. + **/ + AREXPORT virtual bool isLoadingDataStarted() = 0; + + // When loading a map, returns whether all header and objects have completed loading. + /** + * This value returns true once the first LINES tag has been reached. + * The rest of the map contains data lines and points. + **/ + AREXPORT virtual bool isLoadingLinesAndDataStarted() = 0; + +}; // end class ArMapInterface + +#endif // ARMAPINTERFACE_H + diff --git a/Legacy/Aria/include/ArMapObject.h b/Legacy/Aria/include/ArMapObject.h new file mode 100644 index 0000000..4a72bc0 --- /dev/null +++ b/Legacy/Aria/include/ArMapObject.h @@ -0,0 +1,370 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +/* \file ArMapObject.h + * \brief Contains the definition of the ArMapObject class. + * \date 06/27/08 + * \author K. Cunningham +*/ +#ifndef ARMAPOBJECT_H +#define ARMAPOBJECT_H + +#include "ariaTypedefs.h" +#include "ariaUtil.h" + +/// A point or region of interest in an Aria map. +/** + * ArMapObject contains the data related to an Aria map object, i.e a point or + * region of interest in an Aria map that is not part of the sensed obstacle + * data. Examples of map objects include goals, docks, forbidden lines, and + * forbidden areas. Applications may define their own custom ArMapObject types + * using the ArMap MapInfo mechanism. See @ref ArMap for more information. + * + * The basic attributes of an ArMapObject include the type of the map object, + * an optional name of the object, and its position information. As mentioned + * above, there are two basic categories of ArMapObjects: + * + * - Points: A single ArPose in the map. By convention, if a map object + * can have an optional heading, then "WithHeading" appears at the end of + * the object type when the heading is specified. For example, "Goal" + * designates an (x,y) location in the map (any heading or theta value should + * be ignored) and "GoalWithHeading" designates + * an (x,y,th) location. + * + * - Regions: A set of two ArPoses ("from" and "to") which define a rectangle + * or a line. Rectangles may have an associated rotation value. It is the + * rotation to be applied to the "from" and "to" poses around + * the global origin . To retrieve the list of line segments that + * comprise the rotated rectangle's perimeter, use the getFromToSegments() + * method. + * + * Note that the ArMapObject is generally immutable. If an object needs to be + * changed, then the original version should simply be replaced with a new one. + * See ArMap::getMapObjects(), ArMap::setMapObjects(), and ArMap::mapChanged(). + * +**/ +class ArMapObject +{ +public: + + /// Creates a new ArMapObject whose attributes are as specified in the given arguments + /** + * @param arg the ArArgumentBuilder * from which to create the ArMapObject; this + * should correspond to a parsed line in the ArMap file + * @return ArMapObject * the newly created map object, or NULL if an error + * occurred + **/ + AREXPORT static ArMapObject *createMapObject(ArArgumentBuilder *arg); + + + /// ArArgumentBuilder indices for the various map object attributes + enum ArgIndex { + TYPE_ARG_INDEX = 0, + POSE_X_ARG_INDEX = 1, + POSE_Y_ARG_INDEX = 2, + TH_ARG_INDEX = 3, + DESC_ARG_INDEX = 4, + ICON_ARG_INDEX = 5, + NAME_ARG_INDEX = 6, + LAST_POSE_ARG_INDEX = NAME_ARG_INDEX, + FROM_X_ARG_INDEX = 7, + FROM_Y_ARG_INDEX = 8, + TO_X_ARG_INDEX = 9, + TO_Y_ARG_INDEX = 10, + LAST_ARG_INDEX = TO_Y_ARG_INDEX + }; + + enum { + ARG_INDEX_COUNT = LAST_ARG_INDEX + 1 + }; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Instance Methods + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + /// Constructor + /** + * @param type the char * type of the map object (e.g. "Goal", "ForbiddenLine"); + * must be non-empty + * @param pose the primary ArPose of the map object; for points, this is its + * location; for rectangles, this specifies the rotation of the rectangle (in + * pose.getTh()) + * @param description an optional char * description of the object. + * @param iconName char * currently unused: use "ICON" or NULL as a dummy value. Must + * be a non-empty, non-whitespace string. + * @param name the char * name of the map object; depending on the object type, + * this may be optional or required + * @param hasFromTo a bool set to true if the object is a region (i.e. line or + * rectangle); false if the object is a point + * @param fromPose the ArPose that defines the start point of the region object; + * applicable only when hasFromTo is true + * @param toPose the ArPose that defines the end point of the region object; + * applicable only when hasFromTo is true + **/ + AREXPORT ArMapObject(const char *type, + ArPose pose, + const char *description, + const char *iconName, + const char *name, + bool hasFromTo, + ArPose fromPose, + ArPose toPose); + + /// Copy constructor + AREXPORT ArMapObject(const ArMapObject &mapObject); + + /// Assignment operator + AREXPORT ArMapObject &operator=(const ArMapObject &mapObject); + + /// Destructor + AREXPORT virtual ~ArMapObject(); + + // -------------------------------------------------------------------------- + // Text Attributes: + // -------------------------------------------------------------------------- + + /// Returns the type of the map object + AREXPORT const char *getType(void) const; + + /// Returns the "base" (or root) type of the map object + /** + * If the map object type ends with "WithHeading", then the base is the + * corresponding heading-less type. For example, "GoalWithHeading" has a + * base type of "Goal". + * + * If the map object type does not end with "WithHeading", then the base + * is the same as the type. + **/ + AREXPORT const char *getBaseType(void) const; + + /// Returns the name of the map object (if any) + AREXPORT const char *getName(void) const; + + /// Returns the optional description of the map object + AREXPORT const char *getDescription() const ; + + /// Returns the icon string of the object + /** + * The use of the ICON field is application-dependent. It currently contains + * either the string "ICON" or "ID=". The ID is used only when auto-numbering + * has been turned on in the MapInfo. + **/ + AREXPORT const char *getIconName(void) const; + + /// Returns the numerical identifier of the object, when auto-numbering is on. + /** + * This method returns 0 when auto-numbering is off. + **/ + AREXPORT int getId() const; + + /// Sets the description of the map object + /** + * This method really should only be called immediately after the object + * is created, and before it is added to the map. (Since the map object + * isn't intended to be mutable.) It exists for backwards compatibility. + **/ + AREXPORT void setDescription(const char *description); + + + // -------------------------------------------------------------------------- + // Position Attributes: + // -------------------------------------------------------------------------- + + /// Returns the primary pose of the object + /** + * For points, this is the map object's location; for rectangles, this + * specifies the rotation of the rectangle (in getPose().getTh()) + **/ + AREXPORT ArPose getPose(void) const; + + /// Returns true if the map object has valid "from/to" poses (i.e. is a line or rectangle) + AREXPORT bool hasFromTo(void) const; + + /// Returns the "from" pose for lines and rectangles; valid only if hasFromTo() + AREXPORT ArPose getFromPose(void) const; + /// Returns the "to" pose for lines and rectangles; valid only if hasFromTo() + AREXPORT ArPose getToPose(void) const; + + /// Returns the optional rotation of a rectangle; or 0 if none + /** + * Note that this function doesn't know whether it actually makes sense + * for this map object to have the rotation. (For example, it makes sense + * on a ForbiddenArea but not a ForbiddenLine.) + * + **/ + AREXPORT double getFromToRotation(void) const; + + /// Gets a list of fromTo line segments that have been rotated + /** + * Note that this function doesn't know whether it actually makes sense + * for this map object to have the rotation. (For example, it makes sense + * on a ForbiddenArea but not a ForbiddenLine.) This is just here so + * that everyone doesn't have to do the same calculation. Note that + * this might be a little more CPU/Memory intensive transfering + * these around, so you may want to keep a copy of them if you're + * using them a lot (but make sure you clear the copy if the map + * changes). It may not make much difference on a modern processor + * though (its set up this way for safety). + **/ + AREXPORT std::list getFromToSegments(void); + + /// Gets a line segment that goes from the from to the to + /** + * Note that this function doesn't know whether this is supposed to + * be a rectangle or a line. (For example, it makes sense on a + * ForbiddenLine but not a ForbiddenAra.) This is just here to + * store it. Note that this might be a little more CPU/Memory + * intensive transfering these around, so you may want to keep a + * copy of them if you're using them a lot (but make sure you clear + * the copy if the map changes). It may not make much difference on + * a modern processor though (its set up this way for safety). + **/ + AREXPORT ArLineSegment getFromToSegment(void); + + /// Computes the center pose of the map object. + /** + * This method determines the center of map objects that have a "from" and a + * "to" pose (i.e. lines and rectangles). For map objects that are poses, + * this method simply returns the pose. + **/ + AREXPORT ArPose findCenter(void) const; + + // -------------------------------------------------------------------------- + // I/O Methods + // -------------------------------------------------------------------------- + + /// Returns the text representation of the map object + /** + * The returned string is suitable for writing to the ArMap file. Note that + * the string does NOT include the map object's optional parameters. + **/ + AREXPORT const char *toString() const; + + /// Returns the text representation of the map object + /** + * This method is equivalent to toString(); + **/ + const char *getStringRepresentation() const { + return toString(); + } + + /// Writes the map object to the ArLog. + /** + * @param intro an optional string that should appear before the object + **/ + AREXPORT void log(const char *intro = NULL) const; + + + // -------------------------------------------------------------------------- + // Miscellaneous Methods + // -------------------------------------------------------------------------- + + /// Less than operator (for sets), orders by position + AREXPORT bool operator<(const ArMapObject& other) const; + + + /// Gets the fileName of the object (probably never used for maps) + /** + * This method is maintained solely for backwards compatibility. + * It now returns the same value as getDescription (i.e. any file names + * that may have been associated with an object can now be found in the + * description attribute). + * @deprecated + **/ + AREXPORT const char *getFileName(void) const; + +private: + + /// Parses the given arguments and sets the description of the given ArMapObject + static bool setObjectDescription(ArMapObject *object, + ArArgumentBuilder *arg); + +protected: + + /// The type of the map object + std::string myType; + /// If non-empty, then myType ends with "WithHeading" and this is the "root" + std::string myBaseType; + + /// The name of the map object, if any + std::string myName; + /// The description of the map object + std::string myDescription; + + /// For pose objects, THE pose; For rectangle objects, contains the optional rotation + ArPose myPose; + + /// Reserved for future use + std::string myIconName; + + /// Whether the map object is a region (line or rect) with "from/to" poses + bool myHasFromTo; + /// The "from" pose of a region map object; valid only if myHasFromTo is true + ArPose myFromPose; + /// The "to" pose of a region map object; valid only if myHasFromTo is true + ArPose myToPose; + + /// For rectangle objects, the line segments that comprise the perimeter (even if rotated) + std::list myFromToSegments; + /// For line objects, the line + ArLineSegment myFromToSegment; + + /// Text representation written to the map file + mutable std::string myStringRepresentation; + +}; // end class ArMapObject + + +// ============================================================================= + +#ifndef SWIG +/// Comparator for two pointers to map objects +/** @swigomit */ +struct ArMapObjectCompare : + public std::binary_function + { + /// Returns true if obj1 is less than obj2; NULL pointers are greater than non-NULL + bool operator()(const ArMapObject *obj1, + const ArMapObject *obj2) + { + if ((obj1 != NULL) && (obj2 != NULL)) { + return *obj1 < *obj2; + } + else if ((obj1 == NULL) && (obj2 == NULL)) { + return false; + } + else { + return (obj1 == NULL); + } + } // end operator() + + }; // end struct ArMapObjectCompare + +#endif //ifndef SWIG + +#endif // ARMAPOBJECT_H + diff --git a/Legacy/Aria/include/ArMapUtils.h b/Legacy/Aria/include/ArMapUtils.h new file mode 100644 index 0000000..11c71a0 --- /dev/null +++ b/Legacy/Aria/include/ArMapUtils.h @@ -0,0 +1,960 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +/* + * Contains utility classes for the ArMap class. + * + * \author K. Cunningham + * + * This file contains miscellaneous helper classes for the ArMap class. + * These are primarily related to tracking changes to the map and include + * the following: + * + * - ArMapId : The unique identifier for an Aria map. + * + * - ArMapFileLine : The data regarding a text line in a map file; this + * includes the line number and text. + * + * - ArMapFileLineGroup : A semantic parent / child relationship between + * text lines in a map file. + * + * - ArMapFileLineSet : A list of map file line groups to be compared. + * Contains helper methods to determines lines that have been added or + * deleted. + * + * - ArMapChangeDetails : A collection of ArMapFileLineSets that describes + * all of the changes that were made to an Aria map. + * + * - ArMapFileLineSetWriter : An output functor that is used to populate an + * ArMapFileLineSet. + * + * - ArMapChangedHelper : A collection of callbacks and methods to invoke + * them after the Aria map has been changed. + */ + +#ifndef ARMAPUTILS_H +#define ARMAPUTILS_H + +#include +#include +#include +#include +#include +#include + +#include "ariaTypedefs.h" +#include "ariaUtil.h" + + +class ArArgumentBuilder; +class ArBasePacket; + +// ============================================================================ +// ArMapId +// ============================================================================ + +/// Enapsulates the data used to uniquely identify an Aria map +/** + * ArMapId is a small helper class that contains all of the information + * needed to uniquely identify an Aria map. In addition to the standard + * file attributes (such as filename, size, and timestamps), it + * contains the name of the originating source robot or server. It + * also contains the checksum of the file contents. This checksum is + * currently calculated by the ArMD5Calculator class. All of the + * data should allow one to determine whether two map files are the same + * with a reasonable degree of certainty. + *

+ * The ArMapId class is not thread-safe. + * + * @see ArMD5Calculator +**/ +class ArMapId { + +public: + // -------------------------------------------------------------------------- + // Static Methods + // -------------------------------------------------------------------------- + + /// Given a local file name, creates the map ID + /** + * This method calculates the checksum of the specified file + * @param fileName the const char * name of the file for which to create the + * map ID + * @param mapIdOut a pointer to the map ID to be filled in with the results + * @return bool true if the file was found and the map ID created; false, + * otherwise. + **/ + AREXPORT static bool create(const char *fileName, + ArMapId *mapIdOut); + + /// Inserts the given map ID into a network packet + /** + * The format of the map ID in the network packet is as follows: + *

+   *   string:  source robot or server name
+   *   string:  map file name
+   *   uByte4:  number of bytes in the checksum
+   *   data  :  checksum, included only if the number of bytes in the checksum 
+   *            is greater than 0
+   *   uByte4:  file size
+   *   byte4 :  file last modified time
+   * 
+ * @param mapId the ArMapId to be inserted into the packet + * @param packetOut the ArBasePacket * to be modified + **/ + AREXPORT static bool toPacket(const ArMapId &mapId, + ArBasePacket *packetOut); + + /// Extracts a map ID from the given network packet + /** + * @param packetIn the ArBasePacket from which to read the map ID + * @param mapIdOut a pointer to the ArMapId to be filled in with the results + * @return bool true if the map ID was successfully read from the given + * packet, false otherwise. + * @see toPacket for a description of the packet format + **/ + AREXPORT static bool fromPacket(ArBasePacket *packetIn, + ArMapId *mapIdOut); + + // -------------------------------------------------------------------------- + // Instance Methods + // -------------------------------------------------------------------------- + + /// Default contructor creates a null map ID. + AREXPORT ArMapId(); + + /// Creates a map ID with the given attributes. + /** + * @param sourceName the const char * name of the robot or server + * from which the map originated + * @param fileName the const char * name of the map file + * @param checksum the unsigned char * buffer that contains the + * file checksum + * @param checksumLength the size_t length of the checksum buffer + * @param size the long int number of bytes in the map file + * @param timestamp the time_t last modified time of the map file + * @see ArMD5Calculator + **/ + AREXPORT ArMapId(const char *sourceName, + const char *fileName, + const unsigned char *checksum, + size_t checksumLength, + long int size, + const time_t timestamp); + + /// Copy constructor + AREXPORT ArMapId(const ArMapId &other); + + /// Assignment operator + AREXPORT ArMapId &operator=(const ArMapId &other); + + /// Destructor + AREXPORT ~ArMapId(); + + + // -------------------------------------------------------------------------- + // Getters + // -------------------------------------------------------------------------- + + /// Returns whether this map ID is null + AREXPORT bool isNull() const; + + /// Returns the string name of the originating robot or server + AREXPORT const char *getSourceName() const; + + /// Returns the string name of the file + /** + * TODO: Does this include path name?? + **/ + AREXPORT const char *getFileName() const; + + /// Returns a pointer to the buffer that contains the checksum + AREXPORT const unsigned char *getChecksum() const; + /// Returns the length of the checksum + AREXPORT size_t getChecksumLength() const; + + /// Returns the checksum in a human readable string format + AREXPORT const char *getDisplayChecksum() const; + + /// Returns the number of bytes in the map file + AREXPORT long int getSize() const; + /// Returns the last modified time of the file + AREXPORT time_t getTimestamp() const; + + + // -------------------------------------------------------------------------- + // Setters + // -------------------------------------------------------------------------- + + /// Clears this map ID, i.e. sets it to null + AREXPORT void clear(); + + /// Sets the name of the source robot or server that originated the map file + AREXPORT void setSourceName(const char *sourceName); + /// Sets the map file name + AREXPORT void setFileName(const char *fileName); + /// Sets the checksum of the map file + AREXPORT void setChecksum(const unsigned char *checksum, + size_t checksumLen); + /// Sets the number of bytes in the map file + AREXPORT void setSize(long int size); + /// Sets the last modified time of the map file + AREXPORT void setTimestamp(const time_t ×tamp); + + // -------------------------------------------------------------------------- + // Other Methods + // -------------------------------------------------------------------------- + + /// TODO Think that this is the same as operator== + AREXPORT bool isSameFile(const ArMapId &other) const; + + /// Returns whether the source and file names are identical + AREXPORT bool isVersionOfSameFile(const ArMapId &other) const; + + /// Returns true if the timestamp is valid; false if it's a special 'not-set' indicator + AREXPORT bool isValidTimestamp() const; + + /// Returns whether the two map IDs are equivalent + /** + * Note that if either map ID specifies a NULL timestamp, then the timestamp + * will not be used for comparison purposes. + **/ + AREXPORT friend bool operator==(const ArMapId & id1, const ArMapId & id2); + + /// Returns whether the two map IDs are not equal + /** + * Note that if either map ID specifies a NULL timestamp, then the timestamp + * will not be used for comparison purposes. + **/ + AREXPORT friend bool operator!=(const ArMapId & id1, const ArMapId & id2); + + /// Writes the map ID to the output log file, with the specified prefix /header. + AREXPORT void log(const char *prefix) const; + +protected: + + /// Name of the source robot or server from which the map file originated + std::string mySourceName; + /// Name of the map file + std::string myFileName; + /// Buffer that contains the checksum of the map file + unsigned char *myChecksum; + /// Length of the buffer that contains the checksum of the map file + size_t myChecksumLength; + + /// Buffer that contains the checksum in human readable format + mutable char *myDisplayChecksum; + /// Length of the displayable checksum buffer + mutable size_t myDisplayChecksumLength; + + /// Number of bytes in the map file + long int mySize; + /// Last modified time of the map file + time_t myTimestamp; + +}; // end class ArMapId + + +#ifndef SWIG + + +// ============================================================================ +// ArMapFileLine, etc +// ============================================================================ + +/// Encapsulates the data regarding a text line in a map file. +/** + * ArMapFileLine is the building block for map change comparisons. It is + * simply the line number and associated text. + * @internal + * @swigomit +**/ +class ArMapFileLine { + +public: + + /// Default constructor + ArMapFileLine() : + myLineNum(0), + myLineText() + {} + + /// Constructor which sets the line number and text + ArMapFileLine(int lineNum, + const char *lineText) : + myLineNum(lineNum), + myLineText((lineText != NULL) ? lineText : "") + {} + + /// Copy constructor + ArMapFileLine(const ArMapFileLine &other) : + myLineNum(other.myLineNum), + myLineText(other.myLineText) + {} + + /// Assignment operator + ArMapFileLine &operator=(const ArMapFileLine &other) + { + if (this != &other) { + myLineNum = other.myLineNum; + myLineText = other.myLineText; + } + return *this; + } + + /// Destructor + ~ArMapFileLine() + {} + + /// Returns the line number of the map file line + int getLineNum() const { + return myLineNum; + } + /// Returns the text of the map file line + const char *getLineText() const { + return myLineText.c_str(); + } + + friend inline bool operator< ( const ArMapFileLine & line1, const ArMapFileLine & line2 ); + friend struct ArMapFileLineCompare; + +protected: + + int myLineNum; ///< Line number + std::string myLineText; ///< Line text + +}; // end class ArMapFileLine + + +/// Determines whether the first ArMapFileLine is less than the second +/** + * Line1 is less than Line2 if its line number is less than that of Line2. + * If the two line nubmers are equal, then Line1 is less than Line2 if its + * text is less. + * @internal + * @swigomit +**/ +inline bool operator<(const ArMapFileLine & line1, const ArMapFileLine & line2 ) +{ + bool b = (line1.myLineNum < line2.myLineNum); + if (!b) { + if (line1.myLineNum == line2.myLineNum) { + b = (line1.myLineText < line2.myLineText); + } + } + return b; +} + +/// Comparator used to sort ArMapFileLine objects. +/** + * @internal + * @swigomit + */ +struct ArMapFileLineCompare : public std::binary_function +{ + /// Returns true if line1 is less than line2; false, otherwise. + bool operator()(const ArMapFileLine &line1, + const ArMapFileLine &line2) + { + bool b = (line1.myLineNum < line2.myLineNum); + if (!b) { + if (line1.myLineNum == line2.myLineNum) { + b = (line1.myLineText < line2.myLineText); + } + } + return b; + } +}; // end struct MapFileLineCompare + +// ============================================================================ +// ArMapFileLineGroup +// ============================================================================ + +/// A group of map file lines which have a logical parent / child relationship. +/** + * Some of the text lines in a map file may have a parent / child relationship. + * For example, the text line that starts a route is the parent of the following + * lines that describe the contents of the route. This class is used to + * express this relationship. Note that there is currently no concept of + * a grandparent relationship in the map file lines. + * @internal + * @swigomit +**/ +class ArMapFileLineGroup { + +public: + + /// Contructs a new group with the specified parent. + ArMapFileLineGroup(const ArMapFileLine &parentLine) : + myParentLine(parentLine), + myChildLines() + {} + + /// Destructor + ~ArMapFileLineGroup() {} + + /// Returns a pointer to the parent map file line. + ArMapFileLine *getParentLine() { + return &myParentLine; + } + /// Returns a pointer to the list of child map file lines. + std::vector *getChildLines() { + return &myChildLines; + } + + friend inline bool operator<(const ArMapFileLineGroup & line1, + const ArMapFileLineGroup & line2); + friend struct ArMapFileLineGroupCompare; + + /// Writes the group to the Aria log. + void log(); + +public: // users may access class members directly + + ArMapFileLine myParentLine; ///< The map file line that is the parent of the group + std::vector myChildLines; ///< A list of child map file lines + +}; // end class ArFileLineGroup + +/// Determines whether group1's parent text is less than group2's parent text. +/** @internal + * @swigomit + */ +inline bool operator<(const ArMapFileLineGroup & group1, + const ArMapFileLineGroup & group2) +{ + bool b = (strcmp(group1.myParentLine.getLineText(), + group2.myParentLine.getLineText()) < 0); + return b; +} + + +/// Comparator used to sort groups in order of ascending parent text. +/** @internal + * @swigomit + */ +struct ArMapFileLineGroupCompare : public std::binary_function { + bool operator()(const ArMapFileLineGroup &group1, + const ArMapFileLineGroup &group2) + { + bool b = (strcmp(group1.myParentLine.getLineText(), + group2.myParentLine.getLineText()) < 0); + return b; + } +}; // end struct ArMapFileLineGroupCompare + + +/// Comparator used to sort groups in order of ascending parent line number. +/** @internal + * @swigomit + */ +struct ArMapFileLineGroupLineNumCompare : + public std::binary_function { + bool operator()(const ArMapFileLineGroup &group1, + const ArMapFileLineGroup &group2) + { + bool b = (group1.myParentLine.getLineNum() < + group2.myParentLine.getLineNum()); + return b; + } +}; // end struct ArMapFileLineGroupLineNumCompare + + +// ============================================================================ +// ArMapFileLineSet +// ============================================================================ + +/// A set of map file line groups. +/** + * ArMapFileLineSet is a container of ArMapFileLineGroup objects -- i.e. a + * set of parent/child text lines in an Aria map. The class has been + * defined to enable comparisons of map file versions. Each section of + * an Aria map is written to an ArMapFileLineSet and then the standard + * algorithm set_difference can be used to determine changes within a + * section. The static method ArMapFileLineSet::calculateChanges() + * performs this comparison. + * @swigomit + * @internal +**/ +class ArMapFileLineSet : public std::vector +{ +public: + + // --------------------------------------------------------------------------- + /// Determines the changes that have been made to a set of ArMapFileLines + /** + * @param origLines the ArMapFileLineSet that contains the original map file + * lines + * @param newLines the ArMapFileLineSet that contains the new map file lines + * @param deletedLinesOut a pointer to the ArMapFileLineSet that is populated + * with lines that have been deleted, i.e. that are contained in origLines + * but not in newLines + * @param addedLinesOut a pointer to the ArMapFileLineSet that is populated + * with lines that have been added, i.e. that are contained in newLines but + * not in origLines + * @param isCheckChildren a bool set to true if child lines should also be + * checked; if false, then only the parent lines are checked + * @return bool true if the changes were successfully determined; false if + * an error occurred + **/ + static bool calculateChanges(ArMapFileLineSet &origLines, + ArMapFileLineSet &newLines, + ArMapFileLineSet *deletedLinesOut, + ArMapFileLineSet *addedLinesOut, + bool isCheckChildren = true); + + // --------------------------------------------------------------------------- + + /// Constructor + ArMapFileLineSet() {} + + /// Copy constructor + ArMapFileLineSet(const ArMapFileLineSet &other) : + std::vector(other) + {} + + /// Assignment operator + ArMapFileLineSet &operator=(const ArMapFileLineSet &other) + { + if (this != &other) { + std::vector::operator =(other); + } + return *this; + } + + /// Destructor + ~ArMapFileLineSet() {} + + /// Searches the set for the given parent line. + iterator find(const ArMapFileLine &groupParent); + + /// Writes the set to the Aria output log. + void log(const char *prefix); + +}; // end class ArMapFileLineSet + + +// ============================================================================ +// ArMapChangeDetails +// ============================================================================ + +/// Helper class used to track changes to an Aria map. +/** + * ArMapChangeDetails is a simple helper class that is used to track changes + * to an Aria map. These changes are determined based on set comparisons + * (and thus everything in the map must be ordered in a repeatable manner). + * + * The class itself provides very little functionality. It is basically + * a repository of change information that may be accessed directly by the + * application. The methods return pointers to the internal data members + * which may be directly manipulated. There is no error checking, + * thread-safety, etc. The class's use and scope is expected to be very + * limited (to the Aria map and related classes). + * @swigomit + * @internal +**/ +class ArMapChangeDetails +{ +public: + + enum MapLineChangeType { + DELETIONS, ///< Lines that have been deleted from the Aria map + ADDITIONS, ///< Lines that have been added to the Aria map + LAST_CHANGE_TYPE = ADDITIONS ///< Last value in the enumeration + }; + + enum { + CHANGE_TYPE_COUNT = LAST_CHANGE_TYPE + 1 ///< Number of map change types + }; + + /// Constructor + AREXPORT ArMapChangeDetails(); + + /// Copy constructor + AREXPORT ArMapChangeDetails(const ArMapChangeDetails &other); + + /// Assignment operator + AREXPORT ArMapChangeDetails &operator=(const ArMapChangeDetails &other); + + /// Destructor + AREXPORT ~ArMapChangeDetails(); + + // --------------------------------------------------------------------------- + // Map ID Methods + // --------------------------------------------------------------------------- + + /// Returns the original pre-change map ID + /** + * @param mapIdOut a pointer to the ArMapId to be returned + * @return bool true if the map ID was successfully retrieved; false if an + * error occurred + **/ + AREXPORT bool getOrigMapId(ArMapId *mapIdOut); + + /// Sets the original pre-change map ID + /** + * @param mapId the ArMapId of the map before it was changed + **/ + AREXPORT void setOrigMapId(const ArMapId &mapId); + + /// Returns the new post-change map ID + /** + * @param mapIdOut a pointer to the ArMapId to be returned + * @return bool true if the map ID was successfully retrieved; false if an + * error occurred + **/ + AREXPORT bool getNewMapId(ArMapId *mapIdOut); + + /// Sets the new post-change map ID + /** + * @param mapId the ArMapId of the map after it was changed + **/ + AREXPORT void setNewMapId(const ArMapId &mapId); + + // --------------------------------------------------------------------------- + // Change Info + // --------------------------------------------------------------------------- + + /// Returns a pointer to the list of scan types that have been modified + /** + * This list includes the scan types in the map before and after it was changed. + * Scan types usually won't be added or removed, but it may occur when one + * map is inserted into another. + * A pointer to the actual internal attribute is returned. + * @return a pointer to the list of scan type identifier strings + **/ + AREXPORT std::list *getScanTypes(); + + /// Returns a pointer to the data points that have been changed for the specified scan type + /** + * @param change the MapLineChangeType that indicates whether added or removed + * points are to be returned + * @param scanType the const char * identifier of the scan for which the points + * are to be returned; must be non-NULL + * @return a non-NULL pointer to the vector of ArPose's that have been changed + **/ + AREXPORT std::vector *getChangedPoints(MapLineChangeType change, + const char *scanType); + + /// Returns a pointer to the data line segments that have been changed for the specified scan type + /** + * @param change the MapLineChangeType that indicates whether added or removed + * line segments are to be returned + * @param scanType the const char * identifier of the scan for which the line + * segments are to be returned; must be non-NULL + * @return a non-NULL pointer to the vector of ArLineSegment's that have been changed + **/ + AREXPORT std::vector *getChangedLineSegments + (MapLineChangeType change, + const char *scanType); + + /// Returns a pointer to the header lines that have been changed for the specified scan type + /** + * @param change the MapLineChangeType that indicates whether added or removed + * scan header lines are to be returned + * @param scanType the const char * identifier of the scan for which the changes + * are to be returned; must be non-NULL + * @return a non-NULL pointer to the ArMapFileLineSet that describes the changes + **/ + AREXPORT ArMapFileLineSet *getChangedSummaryLines(MapLineChangeType change, + const char *scanType); + + /// Returns a pointer to the map supplement lines that have been changed + /** + * @param change the MapLineChangeType that indicates whether added or removed + * supplement lines are to be returned + * @return a non-NULL pointer to the ArMapFileLineSet that describes the changes + **/ + AREXPORT ArMapFileLineSet *getChangedSupplementLines(MapLineChangeType change); + + /// Returns a pointer to the map object (i.e. Cairn) lines that have been changed + /** + * @param change the MapLineChangeType that indicates whether added or removed + * map object lines are to be returned + * @return a non-NULL pointer to the ArMapFileLineSet that describes the changes + **/ + AREXPORT ArMapFileLineSet *getChangedObjectLines(MapLineChangeType change); + + /// Returns a pointer to the specified info lines that have been changed + /** + * @param infoName the int identifier of the info type to be returned + * @param change the MapLineChangeType that indicates whether added or removed + * map info lines are to be returned + * @return a non-NULL pointer to the ArMapFileLineSet that describes the changes + **/ + AREXPORT ArMapFileLineSet *getChangedInfoLines(const char *infoName, + MapLineChangeType change); + + + // --------------------------------------------------------------------------- + // Other Methods + // --------------------------------------------------------------------------- + + /// Returns a list of the info types that have been changed + /** + * This method searches the internal changed info lines and returns the info + * types that have non-empty change information. + * @return list of the string info names that have non-empty changes + **/ + AREXPORT std::list findChangedInfoNames() const; + + /// Determines whether the given argument for the specified info type is a "child". + /** + * "Child" arguments have a non-NULL parent. For example, an argument that + * represents a robot task may be a child of one that defines a macro. When + * a child argument is changed, then the parent and all of its children + * must be included in the change details. Note that currently only one + * level of parent-ness is supported (i.e. there are no grandparents). + **/ + AREXPORT bool isChildArg(const char *infoName, + ArArgumentBuilder *arg) const; + + /// Determines whether the given arg 0 for the info type is a "child". + AREXPORT bool isChildArg(const char *infoName, + const char *arg0Text) const; + + /// Creates a map of args that are considered to be a "child" of another arg. + AREXPORT void createChildArgMap(); + + /// Writes the change details to the Aria log. + AREXPORT void log(); + + /// Locks the change details for multithreaded access. + AREXPORT void lock(); + //// Unlocks the change details for multithreaded access. + AREXPORT void unlock(); + +protected: + + /// Summary of changes for a specific map scan type. + struct ArMapScanChangeDetails { + + std::vector myChangedPoints[CHANGE_TYPE_COUNT]; + std::vector myChangedLineSegments[CHANGE_TYPE_COUNT]; + + ArMapFileLineSet myChangedSummaryLines[CHANGE_TYPE_COUNT]; + + ArMapScanChangeDetails(); + ~ArMapScanChangeDetails(); + + }; // end struct ArMapScanChangeDetails + + ArMapScanChangeDetails *getScanChangeDetails(const char *scanType); + +protected: + + /// Mutex to protect multithreaded access. + ArMutex myMutex; + + /// Identifier of the map before the changes were made. + ArMapId myOrigMapId; + /// Identifier of the map after the changes were made. + ArMapId myNewMapId; + + /// Map of info type identifiers to argument types, and whether each argument type is a child. + std::map > myInfoNameToMapOfChildArgsMap; + + /// List of scan types included in the change details. + std::list myScanTypeList; + /// Map of scan types to the changes for the scan. + std::map myScanTypeToChangesMap; + /// Value returned when no scan data was changed. + ArMapScanChangeDetails myNullScanTypeChanges; + + /// Change details for the map's supplemental data. + ArMapFileLineSet myChangedSupplementLines[CHANGE_TYPE_COUNT]; + /// Change details for the map's object list. + ArMapFileLineSet myChangedObjectLines[CHANGE_TYPE_COUNT]; + /// Change details for the map's info data. + std::map myInfoToChangeMaps[CHANGE_TYPE_COUNT]; + +}; // end class ArMapChangeDetails + +// ============================================================================ +// ArMapFileLineSetWriter +// ============================================================================ + +/// Functor that populates a specified ArMapFileLineSet. +/** + * ArMapFileLineSetWriter is used to create an ArMapFileLineSet, using the + * normal Aria map writeToFunctor mechanism. + * @swigomit + * @internal +**/ +class ArMapFileLineSetWriter : public ArFunctor1 +{ +public: + + /// Constructs a new writer for the given map file line set. + ArMapFileLineSetWriter(ArMapFileLineSet *multiSet) : + myLineNum(0), + myChildLineNum(0), + myMultiSet(multiSet), + myIsAddingChildren(false) + {} + + /// Destructor + ~ArMapFileLineSetWriter() + {} + + /// Returns whether children are currently being added to the map file line set. + bool isAddingChildren() const + { + return myIsAddingChildren; + } + + /// Sets whether children are currently being added to the map file line set. + /** + * When a child line is detected by the map file parser, setAddingChildren(true) + * must be called. The new children will be added to the most recently + * created ArMapFileLineSet. Likewise, when the child list is complete, + * setAddingChildren(false) must be called. + **/ + void setAddingChildren(bool isAddingChildren) { + if (myIsAddingChildren == isAddingChildren) { + return; + } + myIsAddingChildren = isAddingChildren; + if (myIsAddingChildren) { + myChildLineNum = 0; + } + } // end method setAddingChildren + + + /// Invokes the functor; this method shouldn't be called. + virtual void invoke(void) {}; + + /// Invokes the functor + /** + @param p1 the char * map file line to be written + */ + virtual void invoke(const char *p1) + { + myLineNum++; + + if ((myMultiSet != NULL) && (p1 != NULL)) { + if (!myIsAddingChildren) { + // Being verbose on the parameters here in order to make it more clear. + // Create a new map file line for the parent, create a new group for + // that parent, and add it to the set. + myMultiSet->push_back(ArMapFileLineGroup(ArMapFileLine(myLineNum, p1))); + } + else if (!myMultiSet->empty()) { + myChildLineNum++; + ArMapFileLineGroup &curParent = myMultiSet->back(); + curParent.getChildLines()->push_back(ArMapFileLine(myChildLineNum, p1)); + } + } + } // end method invoke + +private: + + /// Disabled copy constructor + ArMapFileLineSetWriter(const ArMapFileLineSetWriter &other); + /// Disabled assignment operator + ArMapFileLineSetWriter &operator=(const ArMapFileLineSetWriter &other); + +protected: + + /// Line number currently being written + int myLineNum; + /// "Local" line number of the current child in relation to its parent + int myChildLineNum; + + /// Map file line set that is being populated + ArMapFileLineSet *myMultiSet; + /// Whether a child is currently being added + bool myIsAddingChildren; + +}; // end class ArMapFileLineSetWriter + + +// ============================================================================ +// ArMapChangedHelper +// ============================================================================ + +/// Helper class that stores and invokes the map changed callbacks. +/** @swigomit + * @internal + */ +class ArMapChangedHelper + { + public: + + /// Constructor + AREXPORT ArMapChangedHelper(); + /// Destructor + AREXPORT virtual ~ArMapChangedHelper(); + + /// Function that invokes the map changed callbacks + AREXPORT virtual void invokeMapChangedCallbacks(void); + + + /// Adds a callback to be invoked when the map is changed + AREXPORT virtual void addMapChangedCB(ArFunctor *functor, + int position = 50); + /// Removes a callback invoked when the map is changed + AREXPORT virtual void remMapChangedCB(ArFunctor *functor); + + + /// Adds a callback called before the map changed callbacks are called + /** + * Note that these callbacks are simply invoked before the "normal" map changed + * callbacks. They are not + **/ + AREXPORT virtual void addPreMapChangedCB(ArFunctor *functor, + int position = 50); + /// Removes a callback called before the map changed callbacks are called + AREXPORT virtual void remPreMapChangedCB(ArFunctor *functor); + + /// Sets the level we log our map changed callback at + AREXPORT virtual void setMapChangedLogLevel(ArLog::LogLevel level); + /// Gets the level we log our map changed callback at + AREXPORT virtual ArLog::LogLevel getMapChangedLogLevel(void); + + private: + + /// Disabled copy constructor + AREXPORT ArMapChangedHelper(const ArMapChangedHelper &other); + /// Disabled assignment operaotr + AREXPORT ArMapChangedHelper &operator=(const ArMapChangedHelper &other); + + protected: + + ArLog::LogLevel myMapChangedLogLevel; + + ArCallbackList myMapChangedCBList; + ArCallbackList myPreMapChangedCBList; + + }; // end class ArMapChangedHelper + +#endif // ifndef SWIG + +#endif // ARMAPUTILS_H + diff --git a/Legacy/Aria/include/ArMode.h b/Legacy/Aria/include/ArMode.h new file mode 100644 index 0000000..38031d1 --- /dev/null +++ b/Legacy/Aria/include/ArMode.h @@ -0,0 +1,102 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARMODE_H +#define ARMODE_H + +#include "ariaTypedefs.h" +#include "ArFunctor.h" +#include +#include + +class ArRobot; + + +/// A class for different modes, mostly as related to keyboard input +/** + Each mode is going to need to add its keys to the keyHandler... + each mode should only use the keys 1-0, the arrow keys (movement), + the space bar (stop), z (zoom in), x (zoom out), and e (exercise)... + then when its activate is called by that key handler it needs to + first deactivate the ourActiveMode (if its not itself, in which case + its done) then add its key handling stuff... activate and deactivate + will need to add and remove their user tasks (or call the base class + activate/deactivate to do it) as well as the key handling things for + their other part of modes. This mode will ALWAYS bind help to /, ?, h, + and H when the first instance of an ArMode is made. + + @ingroup OptionalClasses +**/ +class ArMode +{ +public: + /// Constructor + AREXPORT ArMode(ArRobot *robot, const char *name, char key, char key2); + /// Destructor + AREXPORT virtual ~ArMode(); + /// Gets the name of the mode + AREXPORT const char *getName(void); + /// The function called when the mode is activated, subclass must provide + AREXPORT virtual void activate(void) = 0; + /// The function called when the mode is deactivated, subclass must provide + AREXPORT virtual void deactivate(void) = 0; + /// The ArMode's user task, don't need one, subclass must provide if needed + AREXPORT virtual void userTask(void) {} + /// The mode's help print out... subclass must provide if needed + /** + This is called as soon as a mode is activated, and should give + directions on to what keys do what and what this mode will do + **/ + AREXPORT virtual void help(void) {} + /// The base activation, it MUST be called by inheriting classes, + /// and inheriting classes MUST return if this returns false + AREXPORT bool baseActivate(void); + /// The base deactivation, it MUST be called by inheriting classes, + /// and inheriting classes MUST return if this returns false + AREXPORT bool baseDeactivate(void); + /// This is the base help function, its internal, bound to ? and h and H + AREXPORT static void baseHelp(void); + /// An internal function to get the first key this is bound to + AREXPORT char getKey(void); + /// An internal function to get the second key this is bound to + AREXPORT char getKey2(void); +protected: + AREXPORT void addKeyHandler(int keyToHandle, ArFunctor *functor); + AREXPORT void remKeyHandler(ArFunctor *functor); + // Our activeArMode + AREXPORT static ArMode *ourActiveMode; + std::string myName; + ArRobot *myRobot; + ArFunctorC myActivateCB; + ArFunctorC myDeactivateCB; + ArFunctorC myUserTaskCB; + char myKey; + char myKey2; + // our help callback, its NULL until its initialized + static ArGlobalFunctor *ourHelpCB; + static std::list ourModes; +}; + +#endif // ARMODE_H diff --git a/Legacy/Aria/include/ArModes.h b/Legacy/Aria/include/ArModes.h new file mode 100644 index 0000000..798f26c --- /dev/null +++ b/Legacy/Aria/include/ArModes.h @@ -0,0 +1,510 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARMODES_H +#define ARMODES_H + +#include "ariaTypedefs.h" +#include "ArMode.h" +#include "ArActionGroups.h" +#include "ArGripper.h" +#include "ArTcpConnection.h" +#include "ArSerialConnection.h" +#include "ArPTZ.h" +#include "ArTCMCompassRobot.h" +#include "ArRobotConfigPacketReader.h" + +class ArTCMCompassRobot; +class ArACTS_1_2; +class ArRobotPacket; +class ArSick; +class ArAnalogGyro; + +/// Mode for teleoping the robot with joystick + keyboard +class ArModeTeleop : public ArMode +{ +public: + /// Constructor + AREXPORT ArModeTeleop(ArRobot *robot, const char *name, char key, char key2); + /// Destructor + AREXPORT virtual ~ArModeTeleop(); + AREXPORT virtual void activate(void); + AREXPORT virtual void deactivate(void); + AREXPORT virtual void help(void); + AREXPORT virtual void userTask(void); +protected: + //ArActionGroupTeleop myGroup; + // use our new ratio drive instead + ArActionGroupRatioDrive myGroup; + ArFunctorC myEnableMotorsCB; +}; + +/// Mode for teleoping the robot with joystick + keyboard +class ArModeUnguardedTeleop : public ArMode +{ +public: + /// Constructor + AREXPORT ArModeUnguardedTeleop(ArRobot *robot, const char *name, char key, char key2); + /// Destructor + AREXPORT virtual ~ArModeUnguardedTeleop(); + AREXPORT virtual void activate(void); + AREXPORT virtual void deactivate(void); + AREXPORT virtual void help(void); + AREXPORT virtual void userTask(void); +protected: + //ArActionGroupUnguardedTeleop myGroup; + // use our new ratio drive instead + ArActionGroupRatioDriveUnsafe myGroup; + ArFunctorC myEnableMotorsCB; +}; + +/// Mode for wandering around +class ArModeWander : public ArMode +{ +public: + /// Constructor + AREXPORT ArModeWander(ArRobot *robot, const char *name, char key, char key2); + /// Destructor + AREXPORT virtual ~ArModeWander(); + AREXPORT virtual void activate(void); + AREXPORT virtual void deactivate(void); + AREXPORT virtual void help(void); + AREXPORT virtual void userTask(void); +protected: + ArActionGroupWander myGroup; +}; + +/// Mode for controlling the gripper +class ArModeGripper : public ArMode +{ +public: + /// Constructor + AREXPORT ArModeGripper(ArRobot *robot, const char *name, char key, + char key2); + /// Destructor + AREXPORT virtual ~ArModeGripper(); + AREXPORT virtual void activate(void); + AREXPORT virtual void deactivate(void); + AREXPORT virtual void userTask(void); + AREXPORT virtual void help(void); + AREXPORT void open(void); + AREXPORT void close(void); + AREXPORT void up(void); + AREXPORT void down(void); + AREXPORT void stop(void); + AREXPORT void exercise(void); +protected: + enum ExerState { + UP_OPEN, + UP_CLOSE, + DOWN_CLOSE, + DOWN_OPEN + }; + ArGripper myGripper; + bool myExercising; + ExerState myExerState; + ArTime myLastExer; + ArFunctorC myOpenCB; + ArFunctorC myCloseCB; + ArFunctorC myUpCB; + ArFunctorC myDownCB; + ArFunctorC myStopCB; + ArFunctorC myExerciseCB; + +}; + +/// Mode for controlling the camera +class ArModeCamera : public ArMode +{ +public: + /// Constructor + AREXPORT ArModeCamera(ArRobot *robot, const char *name, char key, + char key2); + /// Destructor + AREXPORT virtual ~ArModeCamera(); + AREXPORT virtual void activate(void); + AREXPORT virtual void deactivate(void); + AREXPORT virtual void userTask(void); + AREXPORT virtual void help(void); + AREXPORT void up(void); + AREXPORT void down(void); + AREXPORT void left(void); + AREXPORT void right(void); + AREXPORT void center(void); + AREXPORT void zoomIn(void); + AREXPORT void zoomOut(void); + AREXPORT void exercise(void); + AREXPORT void sony(void); + AREXPORT void canon(void); + AREXPORT void dpptu(void); + AREXPORT void amptu(void); + AREXPORT void canonInverted(void); + AREXPORT void sonySerial(void); + AREXPORT void canonSerial(void); + AREXPORT void dpptuSerial(void); + AREXPORT void amptuSerial(void); + AREXPORT void canonInvertedSerial(void); + AREXPORT void rvisionSerial(void); + AREXPORT void com1(void); + AREXPORT void com2(void); + AREXPORT void com3(void); + AREXPORT void com4(void); + AREXPORT void aux1(void); + AREXPORT void aux2(void); +protected: + void takeCameraKeys(void); + void giveUpCameraKeys(void); + void helpCameraKeys(void); + void takePortKeys(void); + void giveUpPortKeys(void); + void helpPortKeys(void); + void takeAuxKeys(void); + void giveUpAuxKeys(void); + void helpAuxKeys(void); + void takeMovementKeys(void); + void giveUpMovementKeys(void); + void helpMovementKeys(void); + enum State { + STATE_CAMERA, + STATE_PORT, + STATE_MOVEMENT + }; + void cameraToMovement(void); + void cameraToPort(void); + void cameraToAux(void); + void portToMovement(void); + void auxToMovement(void); + enum ExerState { + CENTER, + UP_LEFT, + UP_RIGHT, + DOWN_RIGHT, + DOWN_LEFT + }; + + bool myExercising; + State myState; + ExerState myExerState; + ArTime myLastExer; + bool myExerZoomedIn; + ArTime myLastExerZoomed; + ArSerialConnection myConn; + ArPTZ *myCam; + ArFunctorC myUpCB; + ArFunctorC myDownCB; + ArFunctorC myLeftCB; + ArFunctorC myRightCB; + ArFunctorC myCenterCB; + ArFunctorC myZoomInCB; + ArFunctorC myZoomOutCB; + ArFunctorC myExerciseCB; + ArFunctorC mySonyCB; + ArFunctorC myCanonCB; + ArFunctorC myDpptuCB; + ArFunctorC myAmptuCB; + ArFunctorC myCanonInvertedCB; + ArFunctorC mySonySerialCB; + ArFunctorC myCanonSerialCB; + ArFunctorC myDpptuSerialCB; + ArFunctorC myAmptuSerialCB; + ArFunctorC myCanonInvertedSerialCB; + ArFunctorC myRVisionSerialCB; + ArFunctorC myCom1CB; + ArFunctorC myCom2CB; + ArFunctorC myCom3CB; + ArFunctorC myCom4CB; + ArFunctorC myAux1CB; + ArFunctorC myAux2CB; + const int myPanAmount; + const int myTiltAmount; +}; + +/// Mode for displaying the sonar +class ArModeSonar : public ArMode +{ +public: + /// Constructor + AREXPORT ArModeSonar(ArRobot *robot, const char *name, char key, char key2); + /// Destructor + AREXPORT virtual ~ArModeSonar(); + AREXPORT virtual void activate(void); + AREXPORT virtual void deactivate(void); + AREXPORT virtual void userTask(void); + AREXPORT virtual void help(void); + AREXPORT void allSonar(void); + AREXPORT void firstSonar(void); + AREXPORT void secondSonar(void); + AREXPORT void thirdSonar(void); + AREXPORT void fourthSonar(void); +protected: + enum State + { + STATE_ALL, + STATE_FIRST, + STATE_SECOND, + STATE_THIRD, + STATE_FOURTH + }; + State myState; + ArFunctorC myAllSonarCB; + ArFunctorC myFirstSonarCB; + ArFunctorC mySecondSonarCB; + ArFunctorC myThirdSonarCB; + ArFunctorC myFourthSonarCB; +}; + +class ArModeBumps : public ArMode +{ +public: + AREXPORT ArModeBumps(ArRobot *robot, const char *name, char key, char key2); + AREXPORT ~ArModeBumps(); + AREXPORT virtual void activate(void); + AREXPORT virtual void deactivate(void); + AREXPORT virtual void userTask(void); + AREXPORT virtual void help(void); +}; + +class ArModePosition : public ArMode +{ +public: + AREXPORT ArModePosition(ArRobot *robot, const char *name, char key, + char key2, ArAnalogGyro *gyro = NULL); + AREXPORT ~ArModePosition(); + AREXPORT virtual void activate(void); + AREXPORT virtual void deactivate(void); + AREXPORT virtual void userTask(void); + AREXPORT virtual void help(void); + AREXPORT void up(void); + AREXPORT void down(void); + AREXPORT void left(void); + AREXPORT void right(void); + AREXPORT void stop(void); + AREXPORT void reset(void); + AREXPORT void mode(void); + AREXPORT void gyro(void); + AREXPORT void incDistance(void); + AREXPORT void decDistance(void); +protected: + enum Mode { MODE_BOTH, MODE_EITHER }; + ArAnalogGyro *myGyro; + double myGyroZero; + double myRobotZero; + Mode myMode; + std::string myModeString; + bool myInHeadingMode; + double myHeading; + double myDistance; + ArFunctorC myUpCB; + ArFunctorC myDownCB; + ArFunctorC myLeftCB; + ArFunctorC myRightCB; + ArFunctorC myStopCB; + ArFunctorC myResetCB; + ArFunctorC myModeCB; + ArFunctorC myGyroCB; + ArFunctorC myIncDistCB; + ArFunctorC myDecDistCB; +}; + +class ArModeIO : public ArMode +{ +public: + AREXPORT ArModeIO(ArRobot *robot, const char *name, char key, + char key2); + AREXPORT ~ArModeIO(); + AREXPORT virtual void activate(void); + AREXPORT virtual void deactivate(void); + AREXPORT virtual void userTask(void); + AREXPORT virtual void help(void); +protected: + bool myExplanationReady; + bool myExplained; + ArTime myLastPacketTime; + char myExplanation[1024]; + char myOutput[1024]; + ArFunctorC myProcessIOCB; +}; + +class ArModeLaser : public ArMode +{ +public: + AREXPORT ArModeLaser(ArRobot *robot, const char *name, char key, + char key2, ArSick *obsolete = NULL); + AREXPORT ~ArModeLaser(); + AREXPORT virtual void activate(void); + AREXPORT virtual void deactivate(void); + AREXPORT virtual void userTask(void); + AREXPORT virtual void help(void); + AREXPORT virtual void switchToLaser(int laserNumber); + +protected: + void togMiddle(void); + void togConnect(void); + + enum State { + STATE_UNINITED, + STATE_CONNECTING, + STATE_CONNECTED + }; + + State myState; + ArLaser *myLaser; + int myLaserNumber; + + bool myPrintMiddle; + + ArFunctorC myTogMiddleCB; + + std::map myLasers; + std::map *> myLaserCallbacks; +}; + +/// Mode for following a color blob using ACTS +class ArModeActs : public ArMode +{ +public: + /// Constructor + AREXPORT ArModeActs(ArRobot *robot, const char *name, char key, char key2, + ArACTS_1_2 *acts = NULL); + /// Destructor + AREXPORT virtual ~ArModeActs(); + AREXPORT virtual void activate(void); + AREXPORT virtual void deactivate(void); + AREXPORT virtual void help(void); + AREXPORT virtual void userTask(void); + AREXPORT virtual void channel1(void); + AREXPORT virtual void channel2(void); + AREXPORT virtual void channel3(void); + AREXPORT virtual void channel4(void); + AREXPORT virtual void channel5(void); + AREXPORT virtual void channel6(void); + AREXPORT virtual void channel7(void); + AREXPORT virtual void channel8(void); + AREXPORT virtual void stop(void); + AREXPORT virtual void start(void); + AREXPORT virtual void toggleAcquire(void); + +protected: + ArActionGroupColorFollow *myGroup; + ArPTZ *camera; + ArACTS_1_2 *myActs; + ArRobot *myRobot; + + ArFunctorC myChannel1CB; + ArFunctorC myChannel2CB; + ArFunctorC myChannel3CB; + ArFunctorC myChannel4CB; + ArFunctorC myChannel5CB; + ArFunctorC myChannel6CB; + ArFunctorC myChannel7CB; + ArFunctorC myChannel8CB; + ArFunctorC myStopCB; + ArFunctorC myStartCB; + ArFunctorC myToggleAcquireCB; +}; + +class ArModeCommand : public ArMode +{ +public: + AREXPORT ArModeCommand(ArRobot *robot, const char *name, char key, + char key2); + AREXPORT ~ArModeCommand(); + AREXPORT virtual void activate(void); + AREXPORT virtual void deactivate(void); + AREXPORT virtual void help(void); +protected: + void takeKeys(void); + void giveUpKeys(void); + void addChar(int ch); + void finishParsing(void); + void reset(bool print = true); + char myCommandString[70]; + ArFunctor1C my0CB; + ArFunctor1C my1CB; + ArFunctor1C my2CB; + ArFunctor1C my3CB; + ArFunctor1C my4CB; + ArFunctor1C my5CB; + ArFunctor1C my6CB; + ArFunctor1C my7CB; + ArFunctor1C my8CB; + ArFunctor1C my9CB; + ArFunctor1C myMinusCB; + ArFunctor1C myBackspaceCB; + ArFunctor1C mySpaceCB; + ArFunctorC myEnterCB; + +}; + +/// Mode for following a color blob using ACTS +class ArModeTCM2 : public ArMode +{ +public: + /// Constructor + AREXPORT ArModeTCM2(ArRobot *robot, const char *name, char key, char key2, ArTCM2 *tcm2 = NULL); + /// Destructor + AREXPORT virtual ~ArModeTCM2(); + AREXPORT virtual void activate(void); + AREXPORT virtual void deactivate(void); + AREXPORT virtual void help(void); + AREXPORT virtual void userTask(void); + +protected: + void init(); + ArTCM2 *myTCM2; + ArCompassConnector *connector; + ArRobot *myRobot; + ArFunctorC *myOffCB; + ArFunctorC *myCompassCB; + ArFunctorC *myOnePacketCB; + ArFunctorC *myContinuousPacketsCB; + ArFunctorC *myUserCalibrationCB; + ArFunctorC *myAutoCalibrationCB; + ArFunctorC *myStopCalibrationCB; + ArFunctorC *myResetCB; + +}; + + +/// Mode for requesting config packet +class ArModeConfig : public ArMode +{ +public: + /// Constructor + AREXPORT ArModeConfig(ArRobot *robot, const char *name, char key, char key2); + AREXPORT virtual void activate(void); + AREXPORT virtual void deactivate(void); + AREXPORT virtual void help(void); + +protected: + ArRobot *myRobot; + ArRobotConfigPacketReader myConfigPacketReader; + ArFunctorC myGotConfigPacketCB; + + void gotConfigPacket(); +}; + + +#endif // ARMODES_H diff --git a/Legacy/Aria/include/ArModule.h b/Legacy/Aria/include/ArModule.h new file mode 100644 index 0000000..aed6dd7 --- /dev/null +++ b/Legacy/Aria/include/ArModule.h @@ -0,0 +1,171 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARMODULE_H +#define ARMODULE_H + + +#include "ariaTypedefs.h" +#include "ArRobot.h" + + +/// Dynamicly loaded module base class, read warning in more +/** + Right now only one module's init will be called, that is the first + one, its a bug that I just don't have time to fix at the moment. + I'll get to it when I have time or if someone needs it... someone + else wrote this code so it'll take me a little longer to fix it. + + This class defines a dyanicmly loaded module of code. This is usefull + for an application to load piece of code that it does not know about. + The ArModule defines and interface in which to invoke that piece of code + that the program does not know about. For instance, a module could + contain an ArAction and the modules init() could instantiate the ArAction + and add it to the supplied ArRobot. The init() takes a reference to an + ArRobot. The module should use that robot for its purposes. If the module + wants to use more robots, assuming there are multiple robots, it can use + Aria::getRobotList() to find all the ArRobot instantiated. The module + should do all its clean up in exit(). + + The user should derive their own class from ArModule and implement the + init() and exit() functions. The users code should always clean up + when exit() is called. exit() is called right before the module (dynamic + library .dll/.so) is closed and removed from the program. + + The macro ARDEF_MODULE() must be called within the .cpp file of the users + module. A global instance of the users module must be defined and a + reference to that instance must be passed to ARDEF_MODULE(). This allows + the ArModuleLoader to find the users module class and invoke it. + + One thing to note about the use of code wrapped in ArModules and staticly + linking in that code. To be able to staticly link .cpp files which contain + an ArModule, the ARIA_STATIC preprocessor symbol should be defined. This will cause + the ARDEF_MODULE() to do nothing. If it defined its normal functions and + variables, the linker would fail to staticly link in multiple modules + since they all have symbols with the same name. + + Refer to ArModuleLoader to see how to load an ArModule into a program. + + For examples, see the programs advanced/simpleMod.cpp and advanced/simpleModule.cpp. +*/ +class ArModule +{ +public: + + /// Constructor + AREXPORT ArModule(); + /// Destructor + AREXPORT virtual ~ArModule(); + + /// Initialize the module. The module should use the supplied ArRobot pointer + /** + @param robot Robot this module should attach to or operate on. Note, may be NULL. + + @param argument an optional argument passed to the module. Default + is NULL. The module can interpret this in any way, it is recommended + that you make sure this is documented if used. + */ + AREXPORT virtual bool init(ArRobot *robot, + void *argument = NULL) = 0; + + /// Close down the module and have it exit + AREXPORT virtual bool exit() = 0; + + /// Get the ArRobot pointer the module should be using + AREXPORT ArRobot * getRobot() {return(myRobot);} + + /// Set the ArRobot pointer + AREXPORT void setRobot(ArRobot *robot) {myRobot=robot;} + +protected: + + /// Stored ArRobot pointer that the module should use + ArRobot *myRobot; +}; + + +/* + Beware ye all who pass beyond this point. Ugly macros abound and you might + get eaten by a gru if your light fails. */ + + +#ifdef ARIA_STATIC + +#define ARDEF_MODULE(mod) + +#else + +#ifdef WIN32 + +#define ARDEF_MODULE(mod) \ +extern "C" {\ +static ArModule *__AriaModule_##mod = &mod; \ +_declspec(dllexport) bool \ +ariaInitModule(ArRobot *robot, void *argument = NULL) \ +{ \ + if (__AriaModule_##mod) \ + { \ + __AriaModule__->setRobot(robot); \ + return(__AriaModule_##mod->init(robot, argument)); \ + } \ + else \ + return(false); \ +} \ +_declspec(dllexport) bool ariaExitModule() \ +{ \ + if (__AriaModule_##mod) \ + return(__AriaModule_##mod->exit()); \ + return(false); \ +} \ +} +#else // WIN32 + +#define ARDEF_MODULE(mod) \ +static ArModule *__AriaModule_##mod = &mod; \ +extern "C" {\ +bool ariaInitModule(ArRobot *robot, void *argument = NULL) \ +{ \ + if (__AriaModule_##mod) \ + { \ + __AriaModule_##mod->setRobot(robot); \ + return(__AriaModule_##mod->init(robot, argument)); \ + } \ + else \ + return(false); \ +} \ +bool ariaExitModule() \ +{ \ + if (__AriaModule_##mod) \ + return(__AriaModule_##mod->exit()); \ + return(false); \ +} \ +} + +#endif // WIN32 + +#endif // ARIA_STATIC + + +#endif // ARMODULE_H diff --git a/Legacy/Aria/include/ArModuleLoader.h b/Legacy/Aria/include/ArModuleLoader.h new file mode 100644 index 0000000..044ce7b --- /dev/null +++ b/Legacy/Aria/include/ArModuleLoader.h @@ -0,0 +1,82 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARMODULELOADER_H +#define ARMODULELOADER_H + + +#include +#include +#include "ariaTypedefs.h" +#include "ArRobot.h" + + +/// Dynamic ArModule loader +/** + The ArModuleLoader is used to load ArModules into a program and invoke + them. + + See also ArModule to see how to define an ArModule. + + See also the example programs advanced/simpleMod.cpp and advanced/simpleModule.cpp. +*/ +class ArModuleLoader +{ +public: + +#ifdef WIN32 + typedef HINSTANCE DllRef; +#else + typedef void * DllRef; +#endif + + typedef enum { + STATUS_SUCCESS=0, ///< Load succeded + STATUS_ALREADY_LOADED, ///< Module already loaded + STATUS_FAILED_OPEN, ///< Could not find or open the module + STATUS_INVALID, ///< Invalid module file format + STATUS_INIT_FAILED, ///< The module failed its init stage + STATUS_EXIT_FAILED, ///< The module failed its exit stage + STATUS_NOT_FOUND ///< The module was not found + } Status; + + /// Load an ArModule + AREXPORT static Status load(const char *modName, ArRobot *robot, + void *modArgument = NULL, bool quiet = false); + /// Close and then reload an ArModule + AREXPORT static Status reload(const char *modName, ArRobot *robot, + void * modArgument = NULL, bool quiet = false); + /// Close an ArModule + AREXPORT static Status close(const char *modName, bool quiet = false); + /// Close all open ArModule + AREXPORT static void closeAll(); + +protected: + + static std::map ourModMap; +}; + + +#endif // ARMODULELOADER_H diff --git a/Legacy/Aria/include/ArMutex.h b/Legacy/Aria/include/ArMutex.h new file mode 100644 index 0000000..e6247f9 --- /dev/null +++ b/Legacy/Aria/include/ArMutex.h @@ -0,0 +1,210 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARMUTEX_H +#define ARMUTEX_H + +#if !defined(WIN32) || defined(MINGW) +#include +#endif +#include +#include "ariaTypedefs.h" + +class ArTime; +class ArFunctor; + +/// Cross-platform mutex wrapper class +/** + This class wraps the operating system's mutex functions. It allows mutualy + exclusive access to a critical section. This is extremely useful for + multiple threads which want to use the same variable. On Linux, ArMutex simply + uses the POSIX pthread interface in an object oriented manner. It also + applies the same concept to Windows using Windows' own abilities to restrict + access to critical sections. ArMutex also adds additional + diagnostic/debugging tools such as logging and timing. + + + @note ArMutex is by default a recursive mutex. This means that a + thread is allowed to acquire an additional lock (whether via lock() or tryLock()) + on a locked mutex if that same thread already has the lock. This allows a thread + to lock a mutex, but not become deadlocked if any functions called while it + is locked also attempt to lock the mutex, while still preventing other threads + from interrupting it. + If you want a non-recursive mutex, so that multiple attempts by the same thread + to lock a mutex to block, supply an argument of 'false' to the constructor. + + @ingroup UtilityClasses +*/ +class ArMutex +{ +public: + +#if defined(WIN32) && !defined(MINGW) + typedef HANDLE MutexType; +#else + typedef pthread_mutex_t MutexType; +#endif + + typedef enum { + STATUS_FAILED_INIT=1, ///< Failed to initialize + STATUS_FAILED, ///< General failure + STATUS_ALREADY_LOCKED ///< Mutex already locked + } Status; + + /// Constructor + AREXPORT ArMutex(bool recursive = true); + /// Destructor + AREXPORT virtual ~ArMutex(); + /// Copy constructor + AREXPORT ArMutex(const ArMutex &mutex); + + /** Lock the mutex + * + * If this is a recursive mutex (the default type), and a different + * thread has locked this mutex, then block until it is unlocked; if + * this thread has locked this mutex, then continue immediately and do + * not block. + * + * If this is not a recursive mutex, then block if any thread + * (including this thread) has locked this mutex. + * + * Call setLog(true) to enable extra logging. + * + * @return 0 if the mutex was successfully locked (after blocking if it was + * already locked by another thread, or by any thread if this is not a + * recursive mutex). + * @return ArMutex::STATUS_ALREADY_LOCKED immediately if this is a recursive mutex + * (default) and the current thread has already locked this mutex. + * @return ArMutex::STATUS_FAILED on an error from the platform mutex + * implementation. + * @return ArMutex::STATUS_FAILED_INIT if the platform threading is not + * enabled, initialized, etc. + */ + AREXPORT virtual int lock(); + + /** Try to lock the mutex, but do not block + * + * If this is a recursive mutex (the default type), and a different + * thread has locked this mutex, then return ArMutex::STATUS_ALREADY_LOCKED; if + * this thread has locked this mutex, then return 0. + * + * If this is not a recursive mutex, then return 0 if any thread + * (including this thread) has locked this mutex. + * + * Returns ArMutex::STATUS_FAILED or ArMutex::STATUS_FAILED_INIT on an error (such as threading + * not initialized or supported). + * + * Call setLog(true) to enable extra logging. + * + * @return 0 If tryLock() acquires the lock, or mutex is a recursive mutex + * (default) and is already locked by this thread + * @return ArMutex::STATUS_ALREADY_LOCKED if this mutex is currently locked + * by another thread, or if mutex is not recursive, by any thread + * including the current thread. + * @return ArMutex::STATUS_FAILED on an error from the platform mutex + * implementation. + * @return ArMutex::STATUS_FAILED_INIT if the platform threading is not + * enabled, initialized, etc. + */ + AREXPORT virtual int tryLock(); + + /// Unlock the mutex, allowing another thread to obtain the lock + AREXPORT virtual int unlock(); + + /// Get a human readable error message from an error code + AREXPORT virtual const char * getError(int messageNumber) const; + /** Sets a flag that will log out when we lock and unlock. Use setLogName() to + set a descriptive name for this mutex, and ArThread::setThreadName() to set a + descriptive name for a thread. + */ + void setLog(bool log) { myLog = log; } + /// Sets a name we'll use to log with + void setLogName(const char *logName) { myLogName = logName; } +#ifndef SWIG + /// Sets a name we'll use to log with formatting + /** @swigomit use setLogName() */ + AREXPORT void setLogNameVar(const char *logName, ...); +#endif + /// Get a reference to the underlying OS-specific mutex variable + AREXPORT virtual MutexType & getMutex() {return(myMutex);} + /** Sets the lock warning time (sec). If it takes more than @a lockWarningSeconds to perform the mutex lock in lock(), log a warning. + @linuxonly + */ + static void setLockWarningTime(double lockWarningSeconds) + { ourLockWarningMS = (unsigned int)(lockWarningSeconds*1000.0); } + /** Gets the lock warning time (sec) + @linuxonly + */ + static double getLockWarningTime(void) + { return ourLockWarningMS/1000.0; } + /** Sets the unlock warning time (sec). If it takes more than @a unlockWarningSeconds between the mutex being locked with lock() then unlocked with unlock(), log a warning. + @linuxonly + */ + static void setUnlockWarningTime(double unlockWarningSeconds) + { ourUnlockWarningMS = (unsigned int)(unlockWarningSeconds*1000.0); } + /** Gets the lock warning time (sec) + @linuxonly + */ + static double getUnlockWarningTime(void) + { return ourUnlockWarningMS/1000.0; } +protected: + + bool myFailedInit; + MutexType myMutex; +// Eliminating this from Windows in an attempt to debug a memory issue +#if !defined(WIN32) || defined(MINGW) + ArStrMap myStrMap; +#endif + + bool myLog; + std::string myLogName; + + bool myNonRecursive; + bool myWasAlreadyLocked; + + bool myFirstLock; + ArTime *myLockTime; + AREXPORT static unsigned int ourLockWarningMS; + AREXPORT static unsigned int ourUnlockWarningMS; + ArTime *myLockStarted; + // Intialize lock timing state. Call in ArMutex constructor. + void initLockTiming(); + // Destroy lock timing state. Call in destructor. + void uninitLockTiming(); + // Start timing how long it takes to perform the mutex lock. + void startLockTimer(); + // Check time it took to lock the mutex against ourLockWarningMS and log about it + void checkLockTime(); + // Start timing how long it takes between this mutex lock and its next unlock. + void startUnlockTimer(); + // Check time it took between lock and unlock against ourUnlockWarningMS and log about it + void checkUnlockTime(); + + + static ArFunctor *ourNonRecursiveDeadlockFunctor; +}; + + +#endif // ARMUTEX_H diff --git a/Legacy/Aria/include/ArNMEAParser.h b/Legacy/Aria/include/ArNMEAParser.h new file mode 100644 index 0000000..7f4d0e8 --- /dev/null +++ b/Legacy/Aria/include/ArNMEAParser.h @@ -0,0 +1,169 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ + +#ifndef ARNMEAPARSER_H +#define ARNMEAPARSER_H + +#include "ariaTypedefs.h" +#include "ArFunctor.h" +#include "ariaUtil.h" +#include "ArDeviceConnection.h" +#include +#include + + +/** @brief NMEA Parser + * + * Parses NMEA input data and calls callbacks for certain messages with message + * parts. NMEA is a standard output data protocol used by GPS devices and + * others (e.g. compass, altimiter, etc.) This class is used internally by ArNMEAParser and + * subclasses, and by ArTCMCompassDirect. + */ +class ArNMEAParser { + +public: + /** @param name Used in log messages */ + AREXPORT ArNMEAParser(const char *name = "NMEA Parser"); + + /** @brief Flags to indicates what the parse() method did. + * i.e. If nothing was done, then the + * result will be 0. To check a parse() return result @a result to see if data was updated, use + * (result & ParseUpdated). To check if there was an error, use (result & + * ParseError). + */ + enum { + ParseFinished = 1, ///< There was no data to parse + ParseError = 2, ///< There was an error + ParseData = 4, ///< Input was recieved and stored, but no complete messages were parsed + ParseUpdated = 8 ///< At least one complete message was parsed + } ParseFlags; + + /** @brief Set whether checksum is ignored (default behavior is not to ignore it, and + * skip messages with incorrect checksums, and log a warning mesage) */ + AREXPORT void setIgnoreChecksum(bool ignore) { ignoreChecksum = ignore; } + + /** NMEA message, divided into parts. */ + typedef std::vector MessageVector; + + /** Message data passed to handlers */ + typedef struct { + /** The parts of the message, including initial message ID (but excluding + * checksum) */ + ArNMEAParser::MessageVector* message; + /** Timestamp when the beginning of this message was recieved and parsing + * began. */ + ArTime timeParseStarted; + } Message; + + + /** NMEA message handler type. */ + typedef ArFunctor1 Handler; + + + /** Set a handler for an NMEA message. Mostly for internal use or to be used + * by related classes, but you could use for ususual or custom messages + * emitted by a device that you wish to be handled outside of the ArNMEAParser + * class. + */ + AREXPORT void addHandler(const char *message, ArNMEAParser::Handler *handler); + AREXPORT void removeHandler(const char *message); + + /* Read a chunk of input text from the given device connection and + * parse with parse(char*, int). The maximum amount of text read from the device + * connection is determined by the internal buffer size in this class + * (probably a few hundred bytes limit). + * @return a result code from ParseFlags + * @note You should only use one stream of data with ArNMEAParser, and in a + * continuous fashion, since it will store partially recieved messages for + * the next call to one of the parse() methods. + */ + AREXPORT int parse(ArDeviceConnection *dev); + + /* Parse a chunk of input text. Call message handlers as complete NMEA + * messages are parsed. Parsing state is stored in this ArNMEAParser object. + * @return a result code from ParseFlags + */ + AREXPORT int parse(const char *buf, int n); + + + + + +public: + /* Map of message identifiers to handler functors */ + typedef std::map HandlerMap; + +private: + /* NMEA message handlers used by ArNMEAParser */ + HandlerMap myHandlers; + +public: + const ArNMEAParser::HandlerMap& getHandlersRef() const { return myHandlers; } + +private: + + const char *myName; + + /* NMEA scanner state. + * There are possabilities for opmitization here, such + * as just storing the read data in a buffer and handling + * each field as it is found in the buffer, or building + * a list of char* for each field pointing into the buffer + * instead of copying each field into a std::string in the + * currentMessage vector, etc. etc. + */ + const unsigned short MaxNumFields; + const unsigned short MaxFieldSize; // bytes + bool ignoreChecksum; + + MessageVector currentMessage; + ArTime currentMessageStarted; + std::string currentField; + char checksumBuf[3]; + short checksumBufOffset; + bool inChecksum; + bool inMessage; + char currentChecksum; + bool gotCR; + + // Tools to update state + void beginMessage(); + void endMessage(); + void nextField(); + void beginChecksum(); + + /* Data buffer used by handleInput(ArDeviceConnection*). + * This should be enough to hold several NMEA messages. + * Most NMEA messages should be less than 50 bytes or so; + * 256 then allows a minumum of 5 messages parsed per + * call to parse(arDeviceConnection*).) + */ + char myReadBuffer[256]; //[512]; + +}; + +#endif // ifdef ARNMEAPARSER_H + diff --git a/Legacy/Aria/include/ArNetServer.h b/Legacy/Aria/include/ArNetServer.h new file mode 100644 index 0000000..662ad6b --- /dev/null +++ b/Legacy/Aria/include/ArNetServer.h @@ -0,0 +1,223 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARNETSERVER_H +#define ARNETSERVER_H + +#include "ariaTypedefs.h" +#include "ArSocket.h" +#include "ArFunctor.h" +#include "ariaUtil.h" + +#include + + +class ArRobot; + +class ArArgumentBuilder; + +/// Class for running a simple net server to send/recv commands via text +/** + This class is for running a simple server which will have a + list of commands to use and a fairly simple set of interactions... + Start the server with the open() function, add commands with the + addCommand() function and remove commands with remCommand(), and close + the server with the close() function. + + A client can connect via TCP on the port provided to open() and send + a line of text where the first word is the command and the following + words are extra arguments or data (space separated). The line should + end with a newline ("\n") or carriage return character. The first + line sent should be a password and must match the password given to + open() in order to continue. + + You can use the "telnet" program as a general client to any ArNetServer server. + + It has a built in mutex, if you only use sendToAllClients() through + the normal commands or during the robot loop you don't need to + worry about locking anything and the server is locked before any of + the callbacks for the commands are called so you really only need + to lock the server if you're dealing with from another thread.... + From another thread you can use sendToAllClientsNextCycle which + takes care of all the locking itself in a threadsafe way (it puts + the message in a list, then sends it in the next cycle of the + loop). The only real reason to use the + lock/sendToAllClients/unlock method is if you're highly concerned + about synchronizing the different types of output. + + @ingroup OptionalClasses +**/ +class ArNetServer +{ +public: + /// Constructor + AREXPORT ArNetServer(bool addAriaExitCB = true, + bool doNotAddShutdownServer = false); + /// Destructor + AREXPORT ~ArNetServer(); + + /// Initializes the server + AREXPORT bool open(ArRobot *robot, unsigned int port, + const char *password, bool multipleClients = true, + const char *openOnIP = NULL); + + /// Closes the server + AREXPORT void close(void); + + /// Adds a new command + AREXPORT bool addCommand(const char *command, + ArFunctor3 *functor, + const char *help); + + /// Removes a command + AREXPORT bool remCommand(const char *command); + +#ifndef SWIG + /** @brief Sends the given string to all the clients. See also the + * notes on locking in the class description. + * @swigomit @sa + * sendToAllClientsPlain() + */ + AREXPORT void sendToAllClients(const char *str, ...); +#endif + + /// Sends the given string to all the clients, no varargs, wrapper for java + AREXPORT void sendToAllClientsPlain(const char *str); + +#ifndef SWIG + /** @brief Sends the given string to all the clients next cycle + * @swigomit + * @sa sendToAllClientsNextCyclePlain() + */ + AREXPORT void sendToAllClientsNextCycle(const char *str, ...); +#endif + + /// Sends the given string to all the clients next cycle, no varargs, wrapper for java + AREXPORT void sendToAllClientsNextCyclePlain(const char *str); + +#ifndef SWIG + /** @brief Sends the given string to the (hopefully) the client given (this method may go away) + * @swigomit + * @sa sendToClientPlain() + */ + AREXPORT void sendToClient(ArSocket *socket, const char *ipString, + const char *str, ...); +#endif + + /// Sends the given plain string to the (hopefully) the client given (this method may go away) + AREXPORT void sendToClientPlain(ArSocket *socket, const char *ipString, + const char *str); + + /// Sees if the server is running and open + AREXPORT bool isOpen(void); + + /// Sets whether we are logging all data sent or not + AREXPORT void setLoggingDataSent(bool loggingData); + + /// Gets whether we are logging all data sent or not + AREXPORT bool getLoggingDataSent(void); + + /// Sets whether we are logging all data received or not + AREXPORT void setLoggingDataReceived(bool loggingData); + + /// Gets whether we are logging all data received or not + AREXPORT bool getLoggingDataReceived(void); + + /// Sets whether we're using the wrong (legacy) end chars or not + AREXPORT void setUseWrongEndChars(bool useWrongEndChars); + + /// Gets whether we're using the wrong (legacy) end chars or not + AREXPORT bool getUseWrongEndChars(void); + + /// the internal sync task we use for our loop + AREXPORT void runOnce(void); + + /// the internal function that gives the greeting message + AREXPORT void internalGreeting(ArSocket *socket); + + /// The internal function that does the help + AREXPORT void internalHelp(ArSocket *socket); + /// The internal function for the help cb + AREXPORT void internalHelp(char **argv, int argc, ArSocket *socket); + /// The internal function for echo + AREXPORT void internalEcho(char **argv, int argc, ArSocket *socket); + /// The internal function for closing this connection + AREXPORT void internalQuit(char **argv, int argc, ArSocket *socket); + /// The internal function for shutting down + AREXPORT void internalShutdownServer(char **argv, int argc, + ArSocket *socket); + /// The internal function for parsing a command on a socket + AREXPORT void parseCommandOnSocket(ArArgumentBuilder *args, + ArSocket *socket, bool allowLog = true); + /// The internal function that adds a client to our list + AREXPORT void internalAddSocketToList(ArSocket *socket); + /// The internal function that adds a client to our delete list + AREXPORT void internalAddSocketToDeleteList(ArSocket *socket); + /// This squelchs all the normal commands and help + AREXPORT void squelchNormal(void); + /// Sets an extra string that the server holds for passing around + AREXPORT void setExtraString(const char *str) { myExtraString = str; } + /// Gets an extra string that the server holds for passing around + AREXPORT const char *getExtraString(void) { return myExtraString.c_str(); } + /// Lock the server + AREXPORT int lock() {return(myMutex.lock());} + /// Try to lock the server without blocking + AREXPORT int tryLock() {return(myMutex.tryLock());} + /// Unlock the server + AREXPORT int unlock() {return(myMutex.unlock());} + +protected: + ArMutex myMutex; + ArSocket myAcceptingSocket; + std::map *, ArStrCaseCmpOp> myFunctorMap; + std::map myHelpMap; + bool myLoggingDataSent; + bool myLoggingDataReceived; + bool myUseWrongEndChars; + bool myOpened; + bool myWantToClose; + bool mySquelchNormal; + ArSocket myServerSocket; + ArRobot *myRobot; + std::string myPassword; + bool myMultipleClients; + unsigned int myPort; + std::string myExtraString; + std::list myConns; + std::list myConnectingConns; + std::list myDeleteList; + + ArMutex myNextCycleSendsMutex; + std::list myNextCycleSends; + + ArFunctorC myTaskCB; + ArFunctor3C myHelpCB; + ArFunctor3C myEchoCB; + ArFunctor3C myQuitCB; + ArFunctor3C myShutdownServerCB; + ArFunctorC myAriaExitCB; +}; + +#endif // ARNETSERVER_H diff --git a/Legacy/Aria/include/ArNovatelGPS.h b/Legacy/Aria/include/ArNovatelGPS.h new file mode 100644 index 0000000..760481b --- /dev/null +++ b/Legacy/Aria/include/ArNovatelGPS.h @@ -0,0 +1,98 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ + +#ifndef ARNOVATELGPS_H +#define ARNOVATELGPS_H + + +#include "ariaTypedefs.h" +#include "ArFunctor.h" +#include "ariaUtil.h" +#include "ArGPS.h" + +/** @brief GPS subclass to support the NovAtel ProPak G2 and other NovAtel + * "OEM4" devices. + * + * This subclass overrides initDevice() to send initialization commands specific + * to NovAtel GPS devices. + * On connect, it initiazes SBAS (satellite-based augmentation) to + * "auto", which uses WAAS, EGNOS, or MSAS if available, + * and then requests NMEA messages to be interpreted by ArGPS. + * + * It does not initialize corrections sent by your own DGPS fixed + * base station over radio, or the wide-area L-Band services such as OmniStar or + * the Canada-wide DGPS (supported by the NovaTel ProPak LBplus). + * To configure DGPS, you must connect to the GPS with a terminal + * program (e.g. "minicom" in Linux), configure the device for + * your specific service, region and radio settings, and save + * with the "saveconfig" command. See the GPS setup notes + * at http://robots.mobilerobots.com/tech_notes/GPS_Setup_Notes.txt + * and the NovAtel GPS Reference Manual Volume 1, Sections 4.3 and 4.5 for + * ("Transmitting and Receiving Corrections" and "Enabling L-Band Positioning") + * for more information on doing this. + * + */ +class ArNovatelGPS : public virtual ArGPS { +protected: + void handleNovatelGPGGA(ArNMEAParser::Message msg); + ArFunctor1C myNovatelGPGGAHandler; +public: + AREXPORT ArNovatelGPS(); + AREXPORT virtual ~ArNovatelGPS(); +protected: + AREXPORT virtual bool initDevice(); +}; + +/** @brief GPS subclass to support the NovAtel SPAN GPS with integrated IMU. + + This subclass requests the INGLL NMEA message for combined IMU and GPS + position, and updates the GPS position in ArGPS using this data. + It replaces the normal GPRMC handler from ArGPS, and instead saves the uncorrected + GPS data separately. (use dynamic_cast to cast an ArGPS object to an + ArNovatelSPAN object to access this data). + + @since ARIA 2.7.2 +*/ +class ArNovatelSPAN : public virtual ArNovatelGPS { +protected: + /** overrides ArNovatelGPS::handleGPRMC(), and keeps results of parsing the + * message in this class rather than ArGPS. */ + void handleGPRMC(ArNMEAParser::Message msg); + void handleINGLL(ArNMEAParser::Message msg); + AREXPORT virtual bool initDevice(); + ArFunctor1C myGPRMCHandler; + ArFunctor1C myINGLLHandler; +public: + double GPSLatitude, GPSLongitude; + bool haveGPSPosition, GPSValidFlag; + ArTime timeGotGPSPosition, GPSTimestamp; + AREXPORT ArNovatelSPAN(); + AREXPORT virtual ~ArNovatelSPAN(); +}; + +#endif + + diff --git a/Legacy/Aria/include/ArP2Arm.h b/Legacy/Aria/include/ArP2Arm.h new file mode 100644 index 0000000..d058d48 --- /dev/null +++ b/Legacy/Aria/include/ArP2Arm.h @@ -0,0 +1,299 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARP2ARM_H +#define ARP2ARM_H + +#include "ArRobot.h" +#include "ariaTypedefs.h" +#include "ArSerialConnection.h" +#include "ariaOSDef.h" + +// P2 Arm classes: ArP2Arm for control and ArP2ArmJoints for P2 Arm joint data + +/// P2 Arm joint info +class P2ArmJoint +{ +public: + + AREXPORT P2ArmJoint(); + AREXPORT virtual ~P2ArmJoint(); + + ArTypes::UByte myPos; + ArTypes::UByte myVel; + ArTypes::UByte myHome; + ArTypes::UByte myMin; + ArTypes::UByte myCenter; + ArTypes::UByte myMax; + ArTypes::UByte myTicksPer90; +}; + +/** + ArP2Arm is the interface to the AROS/P2OS-based Pioneer 2 Arm servers, + by means of which the robot microcontroller firmware can control the + original 5-DOF Pioneer 2 Arm manipulator. + The P2 Arm is attached to the robot's microcontroller via an auxiliary + serial port. + + To use ArmP2, you must first set up an ArRobot and have it connect + with the robot. The ArRobot needs to be run so that it reads and writes + packets to and from server. The easiest way is ArRobot::runAsync() + which runs the ArRobot in its own thread. + + Then call ArP2Arm::setRobot() with ArRobot, and finally initialized + with ArmP2::init(). Once initialized, use the various ArP2Arm + methods to power the P2 Arm servos, move joints, and so on. + + For simple examples on how to use ArP2Arm, look in the Aria/examples + directory for P2ArmSimple.cpp and P2ArmJoydrive.cpp. + + For additional information about the original 5-DOF Pioneer 2 Arm, + see the robot operations manual and the arm manual, available at + http://robots.mobilerobots.com. + + @ingroup DeviceClasses + @ingroup OptionalClasses +**/ +/// Arm Control class +class ArP2Arm +{ +public: + + /// General error conditions possible from most of the arm related functions + typedef enum { + SUCCESS, ///< Succeded + ALREADY_INITED, ///< The class is already initialized + NOT_INITED, ///< The class is not initialized + ROBOT_NOT_SETUP, ///< The ArRobot class is not setup properly + NO_ARM_FOUND, ///< The arm can not be found + COMM_FAILED, ///< Communications has failed + COULD_NOT_OPEN_PORT, ///< Could not open the communications port + COULD_NOT_SET_UP_PORT, ///< Could not setup the communications port + ALREADY_CONNECTED, ///< Already connected to the arm + NOT_CONNECTED, ///< Not connected with the arm, connect first + INVALID_JOINT, ///< Invalid joint specified + INVALID_POSITION ///< Invalid position specified + } State; + + /// Type of arm packet identifiers. Used in ArP2Arm::setPacketCB(). + typedef enum { + StatusPacket, ///< The status packet type + InfoPacket ///< The info packet type + } PacketType; + + /// Type of status packets to request for. Used in ArP2Arm::requestStatus() + typedef enum + { + StatusOff=0, ///< Stop sending status packets + StatusSingle=1, ///< Send a single status packets + StatusContinuous=2 ///< Send continous packets. Once every 100ms. + } StatusType; + + /// Bit for joint 1 in arm status byte + AREXPORT static const int ArmJoint1; + /// Bit for joint 2 in arm status byte + AREXPORT static const int ArmJoint2; + /// Bit for joint 3 in arm status byte + AREXPORT static const int ArmJoint3; + /// Bit for joint 4 in arm status byte + AREXPORT static const int ArmJoint4; + /// Bit for joint 5 in arm status byte + AREXPORT static const int ArmJoint5; + /// Bit for joint 6 in arm status byte + AREXPORT static const int ArmJoint6; + /// Bit for arm good state in arm status byte + AREXPORT static const int ArmGood; + /// Bit for arm initialized in arm status byte + AREXPORT static const int ArmInited; + /// Bit for arm powered on in arm status byte + AREXPORT static const int ArmPower; + /// Bit for arm homing in arm status byte + AREXPORT static const int ArmHoming; + /// Number of joints that the arm has + AREXPORT static int NumJoints; + + /// Constructor + AREXPORT ArP2Arm(); + + /// Destructor + AREXPORT virtual ~ArP2Arm(); + + /// Set the robot to use to talk to the arm + AREXPORT void setRobot(ArRobot *robot) {myRobot=robot;} + + /// Init the arm class + AREXPORT virtual State init(); + + /// Uninit the arm class + AREXPORT virtual State uninit(); + + /// Power on the arm + AREXPORT virtual State powerOn(bool doWait=true); + + /// Power off the arm + AREXPORT virtual State powerOff(); + + /// Request the arm info packet + AREXPORT virtual State requestInfo(); + + /// Request the arm status packet + AREXPORT virtual State requestStatus(StatusType status); + + /// Request arm initialization + AREXPORT virtual State requestInit(); + + /// Check to see if the arm is still connected + AREXPORT virtual State checkArm(bool waitForResponse=true); + + /// Home the arm + AREXPORT virtual State home(int joint=-1); + + /// Home the arm and power if off + AREXPORT virtual State park(); + + /// Move a joint to a position in degrees + AREXPORT virtual State moveTo(int joint, float pos, unsigned char vel=0); + + /// Move a joint to a position in low level arm controller ticks + AREXPORT virtual State moveToTicks(int joint, unsigned char pos); + + /// Move a joint step degrees + AREXPORT virtual State moveStep(int joint, float pos, unsigned char vel=0); + + /// Move a joint step ticks + AREXPORT virtual State moveStepTicks(int joint, signed char pos); + + /// Set the joint to move at the given velocity + AREXPORT virtual State moveVel(int joint, int vel); + + /// Stop the arm + AREXPORT virtual State stop(); + + /// Set the auto park timer value + AREXPORT virtual State setAutoParkTimer(int waitSecs); + + /// Set the gripper park timer value + AREXPORT virtual State setGripperParkTimer(int waitSecs); + + /// Set the arm stopped callback + AREXPORT virtual void setStoppedCB(ArFunctor *func) {myStoppedCB=func;} + + /// set the arm packet callback + AREXPORT virtual void setPacketCB(ArFunctor1 *func) + {myPacketCB=func;} + + /// Get the arm version + AREXPORT virtual std::string getArmVersion() {return(myVersion);} + + /// Get the joints position in degrees + AREXPORT virtual float getJointPos(int joint); + + /// Get the joints position in ticks + AREXPORT virtual unsigned char getJointPosTicks(int joint); + + /// Check to see if the arm is moving + AREXPORT virtual bool getMoving(int joint=-1); + + /// Check to see if the arm is powered + AREXPORT virtual bool isPowered(); + + /// Check to see if the arm is communicating + AREXPORT virtual bool isGood(); + + /// Get the two byts of status info from P2OS + AREXPORT virtual int getStatus() {return(myStatus);} + + /// Get when the last arm status packet came in + AREXPORT virtual ArTime getLastStatusTime() {return(myLastStatusTime);} + + /// Get the robot that the arm is on + AREXPORT virtual ArRobot * getRobot() {return(myRobot);} + + /// Get the joints data structure + AREXPORT virtual P2ArmJoint * getJoint(int joint); + + /// Converts degrees to low level arm controller ticks + AREXPORT virtual bool convertDegToTicks(int joint, float pos, + unsigned char *ticks); + + /// Converts low level arm controller ticks to degrees + AREXPORT virtual bool convertTicksToDeg(int joint, unsigned char pos, + float *degrees); + + +protected: + + // AROS/P2OS parameters + static const unsigned int ARMpac; + static const unsigned int ARMINFOpac; + static const unsigned char ComArmInfo; + static const unsigned char ComArmStats; + static const unsigned char ComArmInit; + static const unsigned char ComArmCheckArm; + static const unsigned char ComArmPower; + static const unsigned char ComArmHome; + static const unsigned char ComArmPark; + static const unsigned char ComArmPos; + static const unsigned char ComArmSpeed; + static const unsigned char ComArmStop; + static const unsigned char ComArmAutoPark; + static const unsigned char ComArmGripperPark; + + bool comArmInfo(); + bool comArmStats(StatusType stats=StatusSingle); + bool comArmInit(); + bool comArmCheckArm(); + bool comArmPower(bool on); + bool comArmHome(unsigned char joint=0xff); + bool comArmPark(); + bool comArmPos(unsigned char joint, unsigned char pos); + bool comArmSpeed(unsigned char joint, unsigned char speed); + bool comArmStop(unsigned char joint=0xff); + bool comArmAutoPark(int waitSecs); + bool comArmGripperPark(int waitSecs); + + bool armPacketHandler(ArRobotPacket *packet); + + bool myInited; + ArRobot *myRobot; + // ArmP2Model myModel; + ArTime myLastStatusTime; + ArTime myLastInfoTime; + std::string myVersion; + StatusType myStatusRequest; + ArTypes::UByte2 myLastStatus; + ArTypes::UByte2 myStatus; + ArSerialConnection myCon; + ArRetFunctorC myAriaUninitCB; + ArRetFunctor1C myArmPacketHandler; + ArFunctor1 *myPacketCB; + ArFunctor *myStoppedCB; + + // We have 6 joints. Including the gripper. It's here so that we can + // store its position even though its not really a joint. + P2ArmJoint myJoints[6]; +}; + +#endif // _ARP2ARM_H diff --git a/Legacy/Aria/include/ArPTZ.h b/Legacy/Aria/include/ArPTZ.h new file mode 100644 index 0000000..e6ebbf1 --- /dev/null +++ b/Legacy/Aria/include/ArPTZ.h @@ -0,0 +1,357 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARPTZ_H +#define ARPTZ_H + +#include "ariaTypedefs.h" +#include "ArFunctor.h" +#include "ArCommands.h" +#include "ArPTZConnector.h" + +class ArRobot; +class ArBasePacket; +class ArRobotPacket; +class ArDeviceConnection; + + +/// Base class which handles the PTZ cameras +/** + This class is mainly concerned with making all the cameras look + the same for outgoing data, it is also set up to facilitate the + acquisition of incoming data but that is described in the + following paragraphs. There are two ways this can be used. The + first is the simplest and default behavior and should be used by + those whose cameras are attached to their robot's microcontroller, + a ArRobot pointer is passed in to the contructor, this is where + the commands will be sent to the robot via the robot's connection + which will then send it along over the second serial port. The + second way is to pass an ArDeviceConnection to + setDeviceConnection, if this is done commands will be sent along + the given serial port, this should ONLY be done if the camera is + attached straight to a serial port on the computer this program is + running on. + + The next two paragraphs describe how to get data back from the + cameras, but this base class is set up so that by default it won't + try to get data back and assumes you're not trying to do that. If + you are trying to get data back the important functions are + packetHandler, robotPacketHandler and readPacket and you should + read the docs on those. + + If the camera is attached to the robot (and you are thus using the + first method described in the first paragraph) then the only way + to get data back is to send an ArCommands::GETAUX, then set up a + robotPacketHandler for the AUX id and have it call the + packetHandler you set up in in the class. + + If the camera is attached to the serial port on the computer (and + thus the second method described in the first paragraph was used) + then its more complicated... the default way is to just pass in an + ArDeviceConnection to setDeviceConnection and implement the + readPacket method (which MUST not block), and every time through + the robot loop readPacket (with the sensorInterpHandler) will be + called and any packets will be given to the packetHandler (which + you need to implement in your class) to be processed. The other + way to do this method is to pass both an ArDefaultConnection and + false to setDeviceConnection, this means the camera will not be + read at all by default, and you're on your own for reading the + data in (ie like your own thread). + + @ingroup OptionalClasses + @ingroup DeviceClasses + + @todo add functions (optional to implement): power on/off, isReady/isInitialized, slew +**/ +class ArPTZ +{ +public: + AREXPORT ArPTZ(ArRobot *robot); + /// Destructor + AREXPORT virtual ~ArPTZ(); + + /// Initializes the camera + AREXPORT virtual bool init(void) = 0; + + /// Return name of this PTZ type + AREXPORT virtual const char *getTypeName() = 0; + + /// Resets the camera + /** + This function will reset the camera to 0 0 pan tilt, and 0 zoom, + on some cameras that can get out of sync it may need to do more, + such as call init on it again. + **/ + AREXPORT virtual void reset(void) + { panTilt(0, 0); if (canZoom()) zoom(getMinZoom()); } + + /// Pans to the given degrees. 0 is straight ahead, - is to the left, + to the right + virtual bool pan(double degrees) + { + if(myInverted) { + return pan_i(-degrees); + } else { + return pan_i(degrees); + } + } + /// Pans relative to current position by given degrees + virtual bool panRel(double degrees) { if(myInverted) return panRel_i(-degrees); else return panRel_i(degrees); } + + /// Tilts to the given degrees. 0 is middle, - is downward, + is upwards. + virtual bool tilt(double degrees) { if(myInverted) return tilt_i(-degrees); else return tilt_i(degrees); } + /// Tilts relative to the current position by given degrees + virtual bool tiltRel(double degrees) { if(myInverted) return tiltRel_i(-degrees); else return tiltRel_i(degrees); } + + /// Pans and tilts to the given degrees + virtual bool panTilt(double degreesPan, double degreesTilt) { if(myInverted) return panTilt_i(-degreesPan, -degreesTilt); else return panTilt_i(degreesPan, degreesTilt); } + /// Pans and tilts relatives to the current position by the given degrees + virtual bool panTiltRel(double degreesPan, double degreesTilt) { if(myInverted) return panTiltRel_i(-degreesPan, -degreesTilt); else return panTiltRel_i(degreesPan, degreesTilt); } + + /// Returns true if camera can zoom and this class can control the zoom amount + AREXPORT virtual bool canZoom(void) const = 0; + + /// Zooms to the given value + AREXPORT virtual bool zoom(int zoomValue) { return false; } + /// Zooms relative to the current value, by the given value + AREXPORT virtual bool zoomRel(int zoomValue) { return false; } + + /** The angle the camera is panned to (or last commanded value sent, if unable to obtain real pan position) + @sa canGetRealPanTilt() + */ + virtual double getPan(void) const { if(myInverted) return -getPan_i(); else return getPan_i(); } + + /** The angle the camera is tilted to (or last commanded value sent, if unable to obtain real pan position) + @sa canGetRealPanTilt() + */ + virtual double getTilt(void) const { if(myInverted) return -getTilt_i(); else return getTilt_i(); } + + /** The amount the camera is zoomed to (or last commanded value sent, + if unable to obtain real pan position) + @sa canZoom(); + @sa canGetZoom() + */ + AREXPORT virtual int getZoom(void) const { return 0; } + + /// Whether getPan() hand getTilt() return the device's real position, or last commanded position. + AREXPORT virtual bool canGetRealPanTilt(void) const { return false; } + + /// Whether getZoom() returns the device's real zoom amount, or last commanded zoom position. + AREXPORT virtual bool canGetRealZoom(void) const { return false; } + + + /// Gets the highest positive degree the camera can pan to (inverted if camera is inverted) + virtual double getMaxPosPan(void) const { if (myInverted) return -myMaxPosPan; else return myMaxPosPan; } + + + /// @copydoc getMaxPosPan() + double getMaxPan() const { return getMaxPosPan(); } + + /// Gets the lowest negative degree the camera can pan to (inverted if camera is inverted) + virtual double getMaxNegPan(void) const { if (myInverted) return -myMaxNegPan; else return myMaxNegPan; } + + /// @copydoc getMaxNegPan() + double getMinPan() const { return getMaxNegPan(); } + + + /// Gets the highest positive degree the camera can tilt to (inverted if camera is inverted) + virtual double getMaxPosTilt(void) const { if (myInverted) return -myMaxPosTilt; else return myMaxPosTilt; } + + /// @copydoc getMaxPosTilt() + double getMaxTilt() const { return getMaxPosTilt(); } + + /// Gets the lowest negative degree the camera can tilt to (inverted if camera is inverted) + virtual double getMaxNegTilt(void) const { if (myInverted) return -myMaxNegTilt; else return myMaxNegTilt; } + + ///@copydoc getMaxNegTilt() + double getMinTilt() const { return getMaxNegTilt(); } + + /// Halt any pan/tilt movement, if device supports it + virtual bool haltPanTilt() { return false; }; + + /// Halt any zoom movement, if device supports that + virtual bool haltZoom() { return false; } + + /// Can pan and tilt speed (slew rates) be set to move device? + virtual bool canPanTiltSlew() { return false; } + + /// Set pan slew rate (speed) (degrees/sec) if device supports it (see canPanTiltSlew()) + virtual bool panSlew(double s) { return false; } + + /// Set tilt slew rate (speed) (degrees/sec) if device supports it (see canPanTiltSlew()) + virtual bool tiltSlew(double s) { return false; } + +protected: + /// Versions of the pan and tilt limit accessors where inversion is not applied, for use by subclasses to check when given pan/tilt commands. + /// @todo limits checking should be done in ArPTZ pan(), tilt() and panTilt() public interface methods instead of in each implementation + //@{ + virtual double getMaxPosPan_i(void) const { return myMaxPosPan; } + double getMaxPan_i() const { return getMaxPosPan_i(); } + virtual double getMaxPosTilt_i(void) const { return myMaxPosTilt; } + double getMinPan_i() const { return getMaxNegPan_i(); } + virtual double getMaxNegPan_i(void) const { return myMaxNegPan; } + double getMaxTilt_i() const { return getMaxPosTilt_i(); } + virtual double getMaxNegTilt_i(void) const { return myMaxNegTilt; } + double getMinTilt_i() const { return getMaxNegTilt_i(); } + //@} + +public: + + /// Gets the maximum value for the zoom on this camera + virtual int getMaxZoom(void) const { if (myInverted) return -myMaxZoom; else return myMaxZoom; } + /// Gets the lowest value for the zoom on this camera + virtual int getMinZoom(void) const { if (myInverted) return -myMinZoom; else return myMinZoom; } + /// Whether we can get the FOV (field of view) or not + virtual bool canGetFOV(void) { return false; } + /// Gets the field of view at maximum zoom + AREXPORT virtual double getFOVAtMaxZoom(void) { return 0; } + /// Gets the field of view at minimum zoom + AREXPORT virtual double getFOVAtMinZoom(void) { return 0; } + + /// Set gain on camera, range of 1-100. Returns false if out of range + /// or if you can't set the gain on the camera + AREXPORT virtual bool setGain(double gain) const { return false; } + /// Get the gain the camera is set to. 0 if not supported + AREXPORT virtual double getGain(double gain) const { return 0; } + /// If the driver can set gain on the camera, or not + AREXPORT virtual bool canSetGain(void) const { return false; } + + /// Set focus on camera, range of 1-100. Returns false if out of range + /// or if you can't set the focus on the camera + AREXPORT virtual bool setFocus(double focus) const { return false; } + /// Get the focus the camera is set to. 0 if not supported + AREXPORT virtual double getFocus(double focus) const { return 0; } + /// If the driver can set the focus on the camera, or not + AREXPORT virtual bool canSetFocus(void) const { return false; } + + /// Set whether the camera is inverted (upside down). If true, pan and tilt axes will be reversed. + void setInverted(bool inv) { myInverted = inv; } + + /// Get whether the camera is inverted (upside down). If true, pan and tilt axes will be reversed. + bool getInverted() { return myInverted; } + + /// Sets the device connection to be used by this PTZ camera, if set + /// this camera will send commands via this connection, otherwise + /// its via robot aux. serial port (see setAuxPortt()) + AREXPORT virtual bool setDeviceConnection(ArDeviceConnection *connection, + bool driveFromRobotLoop = true); + /// Gets the device connection used by this PTZ camera + AREXPORT virtual ArDeviceConnection *getDeviceConnection(void); + /// Sets the aux port on the robot to be used to communicate with this device + AREXPORT virtual bool setAuxPort(int auxPort); + /// Gets the port the device is set to communicate on + AREXPORT virtual int getAuxPort(void) { return myAuxPort; } + /// Reads a packet from the device connection, MUST NOT BLOCK + /** + This should read in a packet from the myConn connection and + return a pointer to a packet if there was on to read in, or NULL + if there wasn't one... this MUST not block if it is used with + the default mode of being driven from the sensorInterpHandler, + since that is on the robot loop. + @return packet read in, or NULL if there was no packet read + **/ + AREXPORT virtual ArBasePacket *readPacket(void) { return NULL; } + + /// Sends a given packet to the camera (via robot or serial port, depending) + AREXPORT virtual bool sendPacket(ArBasePacket *packet); + /// Handles a packet that was read from the device + /** + This should work for the robot packet handler or for packets read + in from readPacket (the joys of OO), but it can't deal with the + need to check the id on robot packets, so you should check the id + from robotPacketHandler and then call this one so that your stuff + can be used by both robot and serial port connections. + @param packet the packet to handle + @return true if this packet was handled (ie this knows what it + is), false otherwise + **/ + AREXPORT virtual bool packetHandler(ArBasePacket *packet) { return false; } + + /// Handles a packet that was read by the robot + /** + This handles packets read in from the robot, this function should + just check the ID of the robot packet and then return what + packetHandler thinks of the packet. + @param packet the packet to handle + @return true if the packet was handled (ie this konws what it is), + false otherwise + **/ + AREXPORT virtual bool robotPacketHandler(ArRobotPacket *packet); + + /// Internal, attached to robot, inits the camera when robot connects + AREXPORT virtual void connectHandler(void); + /// Internal, for attaching to the robots sensor interp to read serial port + AREXPORT virtual void sensorInterpHandler(void); + + /// Return ArRobot object this PTZ is associated with. May be NULL + ArRobot *getRobot() { return myRobot; } +protected: + ArRobot *myRobot; + ArDeviceConnection *myConn; + ArFunctorC myConnectCB; + ArFunctorC mySensorInterpCB; + int myAuxPort; + ArCommands::Commands myAuxTxCmd; + ArCommands::Commands myAuxRxCmd; + ArRetFunctor1C myRobotPacketHandlerCB; + bool myInverted; + double myMaxPosPan; + double myMaxNegPan; + double myMaxPosTilt; + double myMaxNegTilt; + int myMaxZoom; + int myMinZoom; + + /// Subclasses call this to set extents (limits) returned by getMaxPosPan(), getMaxNegPan(), getMaxPosTilt(), getMaxNegTilt(), getMaxZoom(), and getMinZoom(). + /// @since 2.7.6 + void setLimits(double maxPosPan, double maxNegPan, double maxPosTilt, double maxNegTilt, int maxZoom = 0, int minZoom = 0) + { + myMaxPosPan = maxPosPan; + myMaxNegPan = maxNegPan; + myMaxPosTilt = maxPosTilt; + myMaxNegTilt = maxNegTilt; + myMaxZoom = maxZoom; + myMinZoom = minZoom; + } + + /// Internal implementations by subclasses. Inverted is not applied in these functions, it is done in the public interface above. + /// Note, once execution enters one of these _i methods, then inversion has been + /// applied and no call should be made to any pan/tilt or max/min limit accessor + /// method that does not end in _i, or inversion will be applied again, + /// reversing it. + /// @since 2.7.6 + //@{ + AREXPORT virtual bool pan_i (double degrees) = 0; + AREXPORT virtual bool panRel_i(double degrees) = 0; + AREXPORT virtual bool tilt_i(double degrees) = 0; + AREXPORT virtual bool tiltRel_i (double degrees) = 0; + AREXPORT virtual bool panTilt_i(double degreesPan, double degreesTilt) = 0; + AREXPORT virtual bool panTiltRel_i(double degreesPan, double degreesTilt) = 0; + AREXPORT virtual double getPan_i(void) const = 0; + AREXPORT virtual double getTilt_i(void) const = 0; + //@} + +}; + +#endif // ARPTZ_H diff --git a/Legacy/Aria/include/ArPTZConnector.h b/Legacy/Aria/include/ArPTZConnector.h new file mode 100644 index 0000000..18832cd --- /dev/null +++ b/Legacy/Aria/include/ArPTZConnector.h @@ -0,0 +1,170 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ + +#ifndef ARPTZCONNECTOR_H +#define ARPTZCONNECTOR_H + +#include +#include + +#include "ariaTypedefs.h" +#include "ariaUtil.h" +#include "ArFunctor.h" +#include "ArRobotParams.h" +#include "ariaInternal.h" + +class ArArgumentParser; +class ArPTZ; +class ArRobot; + +/** + * @brief Factory for creating and configuring interfaces for pan/tilt units or camera + * pan/tilt/zoom control based on robot parameter file and command-line arguments. + * + * First, create an ArPTZConnector object before + * calling Aria::parseArgs(). After connecting to the robot, call + * Aria::parseArgs() to check arguments and parameters from the parameter + * file(s). Then, call connect() to connect to all configured and enabled PTZs. To get + * access to a PTZ objects, use getPTZ(int i) and getNumPTZs(), or getPTZs(). + * ArPTZ provides an interface to functions that most PTZ implementations + * (ArPTZ subclasses) implement. Some PTZ implementations have additional + * features. Use those subclasse directly to use these additional features + * (use dynamic_cast to cast an ArPTZ pointer to a subclass pointer, if + * possible.) + * + * ArPTZConnector has built in support for all the PTZ types with support + * included in the ARIA library, and other libraries or programs may register + * new types as well. (For example, the ArVideo library contains support for + * additional camera PTZ types.) + * + * The following command-line arguments are checked: + * @verbinclude ArPTZConnector_options + * + * PTZs are 0-indexed internally in this class, however, argument names, + * parameter names and log messages displayed to users are 1-indexed. + + @ingroup OptionalClasses + @ingroup DeviceClasses + @since 2.7.6 +*/ + +class ArPTZConnector { +public: + /* @arg robot In some cases the robot connection is used to communicate with + * devices via auxilliary serial connections, so this robot interface is used. + * May be NULL. */ + AREXPORT ArPTZConnector(ArArgumentParser* argParser, ArRobot *robot = NULL); + AREXPORT ~ArPTZConnector(); + + /** For each PTZ specified in program arguments, and in robot parameters with + * PTZAutoConnect set to true, create the + * appropriate PTZ object (based on type name) and connect to it. + @return false on first error, true if all PTZ connections were successful. + */ + AREXPORT bool connect(); + + /** @copydoc connect() */ + bool connectPTZs() { return connect(); } + + /** @return number of PTZ objects that were created and connected to. */ + size_t getNumPTZs() const { return myConnectedPTZs.size(); } + + /** @return a specific PTZ object that was connected by connect() or + * connectPTZs(), or NULL if none exists. These are 0-indexed. */ + ArPTZ* getPTZ(size_t i = 0) const + { + if(i >= myConnectedPTZs.size()) return NULL; + return myConnectedPTZs[i]; + } + + /** @copydoc getPTZ(size_t) */ + ArPTZ* findPTZ(size_t i) const { return getPTZ(i); } + + /** @return list of connected PTZs. + 0-indexed. Pointers in the vector may be NULL if no parameters or command + line arguments were given for them or that PTZ was disabled. These should be + skipped when iterating on this list and not accessed. + */ + std::vector getPTZs() const { + return myConnectedPTZs; + } + + + + /** Arguments passed to function are PTZ index, parameters, parser (may be + * null) and robot object (may be null) */ + typedef ArRetFunctor4 PTZCreateFunc; + typedef ArGlobalRetFunctor4 GlobalPTZCreateFunc; + + /** Register a new PTZ type. Aria::init() registers PTZ types built in to + * ARIA. ArVideo::init() registers new PTZ types implemented in the ArVideo + * library. You may also add any new PTZ types you create. + */ + AREXPORT static void registerPTZType(const std::string& typeName, ArPTZConnector::PTZCreateFunc* func); + + /** Change limit on number of PTZ devices. + * You must call this + * before creating an ArPTZConnector, parsing command line arguments, connecting + * to a robot or loading a parameter file, or using ArPTZconnecor to connect to + * PTZ devices. + */ + void setMaxNumPTZs(size_t n) + { + Aria::setMaxNumPTZs(n); + } + + size_t getMaxNumPTZs() + { + return Aria::getMaxNumPTZs(); + } + + /** Return robot that PTZs are or will be attached to (may be NULL) */ + ArRobot *getRobot() { return myRobot; } + +protected: + bool parseArgs(); + bool parseArgs(ArArgumentParser *parser); + bool parseArgsFor(ArArgumentParser *parser, int which); + AREXPORT void logOptions() const; + void populateRobotParams(ArRobotParams *params); + + ArArgumentParser *myArgParser; + ArRobot *myRobot; + ArRetFunctorC myParseArgsCallback; + ArConstFunctorC myLogOptionsCallback; + static std::map< std::string, PTZCreateFunc* > ourPTZCreateFuncs; + ArFunctor1C myPopulateRobotParamsCB; + std::vector myParams; ///< copied from ArRobotParams (via myRobot), then in connect() parameters given from command line arguments (myArguments) are merged in. + std::vector myArguments; ///< from program command-line options (via the parseArgs() callback called by Aria::parseArgs()) + //std::vector myConfiguredPTZs; ///< if connecting to a PTZ, its parameters are copied here from myParams and myArguments + //static size_t ourMaxNumPTZs; + std::vector myConnectedPTZs; ///< ArPTZ objects created and initialized in connect(). +}; + + +#endif // ifdef ARPTZCONNECTOR_H + + diff --git a/Legacy/Aria/include/ArPixelDevice.h b/Legacy/Aria/include/ArPixelDevice.h new file mode 100644 index 0000000..d65792a --- /dev/null +++ b/Legacy/Aria/include/ArPixelDevice.h @@ -0,0 +1,235 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARPIXELDEVICE_H +#define ARPIXELDEVICE_H + +#include +#include "Aria.h" +/*! + @class ArPixelDevice. + @brief Holds data from a sensor that provides data arranged in a 2d array. + + Subclasses are used for specific sensor implementations, such + as the ArFocusPixelDevice for the Focus Robotics nDepth + stereocamera. + + The data are arranged in an x,y grid, with the origin being + in the upper left corner, from the perspective of the robot. + It's in a row-major format. + + The Field of View (FOV) is assumed to be centered with zero + being the center of the area, such that the permitted x angles + are between ((-x_fov/2) to (+x_fov/2)) and + ((-y_fov/2) to (+y_fov/2)). Negative angles are to the lower + left of the grid from the perspective of the robot. + + @param x_size dimension of data grid in x direction + + @param y_size dimension of data grid in y direction + + @param x_fov Field of View of sensor in X direction (angle in degrees) + + @param y_fov Field of View of sensor in Y direction (angle in degrees) + + @param name the name of this device +*/ +template +class ArPixelDevice +{ + public: + /// Base Constructor + AREXPORT ArPixelDevice(int x_size, int y_size, double x_fov, double y_fov, + const char *name) + { + myDeviceMutex.setLogName("ArPixelDevice::myDeviceMutex"); + myXSize = x_size; + myYSize = y_size; + myXFOV = x_fov; + myYFOV = y_fov; + myName = name; + + mySensorData = NULL; + + if (!allocateSensorDataMemory()) + { + ArLog::log(ArLog::Terse, "Failed to allocate memory for ArPixelDevice %s", getName()); + } + else + { + ArLog::log(ArLog::Verbose, "Allocated memory for ArPixelDevice %s", getName()); + } + + if (!allocateSensorXYZMemory()) + { + ArLog::log(ArLog::Terse, "Failed to allocate XYZ memory for ArPixelDevice %s", getName()); + } + else + { + ArLog::log(ArLog::Verbose, "Allocated XYZ memory for ArPixelDevice %s", getName()); + } + } + /// Base destructor + AREXPORT virtual ~ArPixelDevice() + { + if (mySensorData != NULL) + { + for (int i=0; i < myXSize; i++) + { + for (int j=0; j < myYSize; j++) + { + delete mySensorData[i][j]; + } + delete [] (mySensorData[i]); + } + delete [] (mySensorData); + } + if (mySensorXYZ != NULL) + { + for (int i=0; i < myXSize; i++) + { + for (int j=0; j < myYSize; j++) + { + delete [] mySensorXYZ[i][j]; + } + delete [] (mySensorXYZ[i]); + } + delete [] (mySensorXYZ); + } + + } + /// Get the value of the sensor at the (x,y) coords + DataObject *getSensorData(int x, int y) + { + if ((x >= 0) && (x < myXSize) && (y >= 0) && (y < myYSize)) + { + return mySensorData[x][y]; + } + else + { + return NULL; + } + } + /// Get the xyz array of the sensor at the (x,y) pizels. + DataObject* getSensorXYZ(int x, int y) + { + if ((x >= 0) && (x < myXSize) && (y >= 0) && (y < myYSize)) + { + return mySensorXYZ[x][y]; + } + else + { + return NULL; + } + } + /// Get the dimension of the grid in the x direction + int getXDimension(void) { return myXSize; } + /// Get the dimension of the grid in the y direction + int getYDimension(void) { return myYSize; } + /// Get the X direction Field of View, in degrees + double getXFOV(void) { return myXFOV; } + /// Get the Y direction Field of View, in degrees + double getYFOV(void) { return myYFOV; } + /// Get the name of the device + const char *getName(void) { return myName.c_str(); } + /// Gets the raw sensor data + DataObject ***getRawSensorData(void) { return mySensorData; } + /// Gets the raw XYZ data + DataObject ***getRawSensorXYZ(void) { return mySensorXYZ; } + /// Lock this device + AREXPORT virtual int lockDevice() { return(myDeviceMutex.lock()); } + /// Try to lock this device + AREXPORT virtual int tryLockDevice() { return(myDeviceMutex.tryLock()); } + /// Unlock this device + AREXPORT virtual int unlockDevice() { return(myDeviceMutex.unlock()); } +protected: + std::string myName; + int myXSize; + int myYSize; + double myXFOV; + double myYFOV; + DataObject ***mySensorData; + DataObject ***mySensorXYZ; + ArMutex myDeviceMutex; + + bool allocateSensorDataMemory() + { + if ((myXSize < 1) || (myYSize < 1)) + { + ArLog::log(ArLog::Normal, "Bad array size for ArPixelDevice %s", getName()); + return false; + } + mySensorData = new DataObject**[myXSize]; + if (mySensorData == NULL) + { + ArLog::log(ArLog::Normal, "Cannot allocate memory for ArPixelDevice %s", getName()); + return false; + } + for (int i = 0; i < myXSize; i++) + { + if ((mySensorData[i] = new DataObject*[myYSize]) == NULL) + { + ArLog::log(ArLog::Normal, "Cannot allocate memory for ArPixelDevice %s", getName()); + return false; + } + for (int j = 0; j < myYSize; j++) + { + mySensorData[i][j] = new DataObject; + } + } + return true; + } + + bool allocateSensorXYZMemory() + { + if ((myXSize < 1) || (myYSize < 1)) + { + ArLog::log(ArLog::Normal, "Bad array size for ArPixelDevice %s", getName()); + return false; + } + mySensorXYZ = new DataObject**[myXSize]; + if (mySensorXYZ == NULL) + { + ArLog::log(ArLog::Normal, "Cannot allocate memory for ArPixelDevice %s", getName()); + return false; + } + for (int i = 0; i < myXSize; i++) + { + if ((mySensorXYZ[i] = new DataObject*[myYSize]) == NULL) + { + ArLog::log(ArLog::Normal, "Cannot allocate memory for ArPixelDevice %s", getName()); + return false; + } + for (int j = 0; j < myYSize; j++) + { + mySensorXYZ[i][j] = new DataObject[3]; + } + } + return true; + } + +}; + +#endif // ARPIXELDEVICE_H diff --git a/Legacy/Aria/include/ArPriorityResolver.h b/Legacy/Aria/include/ArPriorityResolver.h new file mode 100644 index 0000000..29f8990 --- /dev/null +++ b/Legacy/Aria/include/ArPriorityResolver.h @@ -0,0 +1,50 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARPRIORITYRESOLVER_H +#define ARPRIORITYRESOLVER_H + +#include "ArResolver.h" + +/// (Default resolver), takes the action list and uses the priority to resolve +/** + This is the default resolver for ArRobot, meaning if you don't do a + non-normal init on the robot, or a setResolver, you'll have one these. +*/ +class ArPriorityResolver : public ArResolver +{ +public: + /// Constructor + AREXPORT ArPriorityResolver(); + /// Destructor + AREXPORT virtual ~ArPriorityResolver(); + AREXPORT virtual ArActionDesired *resolve(ArResolver::ActionMap *actions, + ArRobot *robot, + bool logActions = false); +protected: + ArActionDesired myActionDesired; +}; + +#endif // ARPRIORITYRESOLVER_H diff --git a/Legacy/Aria/include/ArRVisionPTZ.h b/Legacy/Aria/include/ArRVisionPTZ.h new file mode 100644 index 0000000..51c4e65 --- /dev/null +++ b/Legacy/Aria/include/ArRVisionPTZ.h @@ -0,0 +1,152 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARRVISIONPTZ_H +#define ARRVISIONPTZ_H + +#include "ariaTypedefs.h" +#include "ArBasePacket.h" +#include "ArPTZ.h" +#include "ArSerialConnection.h" +/// A class for for making commands to send to the RVision camera +/** There are only two functioning ways to put things into this packet, + * uByteToBuf() and byte2ToBuf; You + * MUST use thse, if you use anything else your commands won't work. + * @since 2.7.0 +*/ +class ArRVisionPacket: public ArBasePacket +{ +public: + /// Constructor + AREXPORT ArRVisionPacket(ArTypes::UByte2 bufferSize = 15); + AREXPORT virtual ~ArRVisionPacket(); + + AREXPORT virtual void uByteToBuf(ArTypes::UByte val); + AREXPORT virtual void byte2ToBuf(ArTypes::Byte2 val); + /// This is a new function, read the details before you try to use it + AREXPORT void byte2ToBufAtPos(ArTypes::Byte2 val, ArTypes::UByte2 pose); +}; + +//class ArRobot; + +/** Control the RVision camera pan tilt zoom unit. + In addition to creating an ArRvisionPTZ instance, you will also need + to create an ArSerialConnection object and open the serial port connection + (the RVision is normally on COM3 on Seekur and Seekur Jr. robots) and + use the setDeviceConnection() method to associate the serial connection + with the ArRVisionPTZ object. + @since 2.7.0 +*/ + +class ArRVisionPTZ : public ArPTZ +{ +public: + AREXPORT ArRVisionPTZ(ArRobot *robot); + AREXPORT virtual ~ArRVisionPTZ(); + + AREXPORT virtual bool init(void); + AREXPORT virtual const char *getTypeName() { return "rvision"; } + /// Set serial port + /// @since 2.7.6 + void setPort(const char *port) + { + mySerialPort = port; + } +protected: + AREXPORT virtual bool pan_i(double degrees); + AREXPORT virtual bool panRel_i(double degrees); + AREXPORT virtual bool tilt_i(double degrees); + AREXPORT virtual bool tiltRel_i(double degrees); + AREXPORT virtual bool panTilt_i(double degreesPan, double degreesTilt); + AREXPORT virtual bool panTiltRel_i(double degreesPan, double degreesTilt); +public: + AREXPORT virtual bool canZoom(void) const { return true; } + AREXPORT virtual bool zoom(int zoomValue); + AREXPORT virtual bool zoomRel(int zoomValue); +protected: + AREXPORT virtual double getPan_i(void) const { return myPan; } + AREXPORT virtual double getTilt_i(void) const { return myTilt; } +public: + AREXPORT virtual int getZoom(void) const { return myZoom; } + //AREXPORT void getRealPanTilt(void); + //AREXPORT void getRealZoomPos(void); + /* + AREXPORT virtual double getMaxPosPan(void) const { return MAX_PAN; } + AREXPORT virtual double getMaxNegPan(void) const { return MIN_PAN; } + AREXPORT virtual double getMaxPosTilt(void) const { return MAX_TILT; } + AREXPORT virtual double getMaxNegTilt(void) const { return MIN_TILT; } + AREXPORT virtual int getMaxZoom(void) const { return MAX_ZOOM; } + AREXPORT virtual int getMinZoom(void) const { return MIN_ZOOM; } + */ + + AREXPORT virtual bool canGetRealPanTilt(void) const { return false; } + AREXPORT virtual bool canGetRealZoom(void) const { return false; } + AREXPORT virtual bool canGetFOV(void) { return true; } + /// Gets the field of view at maximum zoom + AREXPORT virtual double getFOVAtMaxZoom(void) { return 4.4; } + /// Gets the field of view at minimum zoom + AREXPORT virtual double getFOVAtMinZoom(void) { return 48.8; } + + virtual ArBasePacket* readPacket(void); + enum { + MAX_PAN = 180, ///< maximum degrees the unit can pan (clockwise from top) + MIN_PAN = -180, ///< minimum degrees the unit can pan (counterclockwise from top) + MIN_TILT = -30, ///< minimum degrees the unit can tilt + MAX_TILT = 60, ///< maximum degrees the unit can tilt + MIN_ZOOM = 0, ///< minimum value for zoom + MAX_ZOOM = 32767, ///< maximum value for zoom + TILT_OFFSET_IN_DEGREES = 38, ///< offset value to convert internal camera coords to world + PAN_OFFSET_IN_DEGREES = 190 ///< offset value to convert internal camera coords to world + }; + + /// called automatically by Aria::init() + ///@since 2.7.6 + ///@internal +#ifndef SWIG + static void registerPTZType(); +#endif +protected: + void initializePackets(void); + double myPan; + double myTilt; + int myZoom; + double myDegToTilt; + double myDegToPan; + double myPanOffsetInDegrees; + double myTiltOffsetInDegrees; + ArRVisionPacket myPacket; + ArRVisionPacket myZoomPacket; + ArRVisionPacket myPanTiltPacket; + ArRVisionPacket myInquiryPacket; + const char *mySerialPort; + + ///@since 2.7.6 + static ArPTZ* create(size_t index, ArPTZParams params, ArArgumentParser *parser, ArRobot *robot); + ///@since 2.7.6 + static ArPTZConnector::GlobalPTZCreateFunc ourCreateFunc; + +}; + +#endif // ARRVISIONPTZ_H diff --git a/Legacy/Aria/include/ArRangeBuffer.h b/Legacy/Aria/include/ArRangeBuffer.h new file mode 100644 index 0000000..2d241d4 --- /dev/null +++ b/Legacy/Aria/include/ArRangeBuffer.h @@ -0,0 +1,133 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARRANGEBUFFER_H +#define ARRANGEBUFFER_H + +#include "ariaUtil.h" +#include "ariaTypedefs.h" +#include "ArTransform.h" +#include +#include + +/// This class is a buffer that holds ranging information +class ArRangeBuffer +{ +public: + /// Constructor + AREXPORT ArRangeBuffer(int size); + /// Destructor + AREXPORT virtual ~ArRangeBuffer(); + /// Gets the size of the buffer + AREXPORT size_t getSize(void) const; + /// Sets the size of the buffer + AREXPORT void setSize(size_t size); + /// Gets the pose of the robot when readings were taken + AREXPORT ArPose getPoseTaken() const; + /// Sets the pose of the robot when readings were taken + AREXPORT void setPoseTaken(ArPose p); + /// Gets the encoder pose of the robot when readings were taken + AREXPORT ArPose getEncoderPoseTaken() const; + /// Sets the pose of the robot when readings were taken + AREXPORT void setEncoderPoseTaken(ArPose p); + /// Adds a new reading to the buffer + AREXPORT void addReading(double x, double y); + /// Adds a new reading to the buffer if some conditions are met + AREXPORT void addReadingConditional(double x, double y, + double closeDistSquared, + bool *wasAdded = NULL); + /// Begins a walk through the getBuffer list of readings + AREXPORT void beginInvalidationSweep(void); + /// While doing an invalidation sweep a reading to the list to be invalidated + AREXPORT void invalidateReading(std::list::iterator readingIt); + /// Ends the invalidation sweep + AREXPORT void endInvalidationSweep(void); +#ifndef SWIG + /** @brief Gets a pointer to a list of readings + * @swigomit + */ + AREXPORT const std::list *getBuffer(void) const; +#endif + /// Gets a pointer to a list of readings + AREXPORT std::list *getBuffer(void); + + /// Gets the closest reading, on a polar system + AREXPORT double getClosestPolar(double startAngle, double endAngle, + ArPose position, unsigned int maxRange, + double *angle = NULL) const; + /// Gets the closest reading, from a rectangular box, in robot LOCAL coords + AREXPORT double getClosestBox(double x1, double y1, double x2, double y2, + ArPose position, unsigned int maxRange, + ArPose *readingPos = NULL, + ArPose targetPose = ArPose(0, 0, 0)) const; + /// Applies a transform to the buffer + AREXPORT void applyTransform(ArTransform trans); + /// Clears all the readings in the range buffer + AREXPORT void clear(void); + /// Resets the readings older than this many seconds + AREXPORT void clearOlderThan(int milliSeconds); + /// Resets the readings older than this many seconds + AREXPORT void clearOlderThanSeconds(int seconds); + /// same as clear, but old name + AREXPORT void reset(void); + /// This begins a redoing of the buffer + AREXPORT void beginRedoBuffer(void); + /// Add a reading to the redoing of the buffer + AREXPORT void redoReading(double x, double y); + /// End redoing the buffer + AREXPORT void endRedoBuffer(void); + /// Gets the buffer as an array instead of as a std::list + AREXPORT std::vector *getBufferAsVector(void); + /// Gets the closest reading, from an arbitrary buffer + AREXPORT static double getClosestPolarInList( + double startAngle, double endAngle, ArPose position, + unsigned int maxRange, double *angle, + const std::list *buffer); + /// Gets the closest reading, from an arbitrary buffer + AREXPORT static double getClosestBoxInList( + double x1, double y1, double x2, double y2, ArPose position, + unsigned int maxRange, ArPose *readingPos, + ArPose targetPose, const std::list *buffer); +protected: + std::vector myVector; + ArPose myBufferPose; // where the robot was when readings were acquired + ArPose myEncoderBufferPose; // where the robot was when readings were acquired + + std::list myBuffer; + std::list myInvalidBuffer; + std::list::iterator > myInvalidSweepList; + std::list::iterator >::iterator myInvalidIt; + std::list::iterator myRedoIt; + int myNumRedone; + bool myHitEnd; + + size_t mySize; + std::list::reverse_iterator myRevIterator; + std::list::iterator myIterator; + + ArPoseWithTime * myReading; +}; + +#endif // ARRANGEBUFFER_H diff --git a/Legacy/Aria/include/ArRangeDevice.h b/Legacy/Aria/include/ArRangeDevice.h new file mode 100644 index 0000000..d1e09ae --- /dev/null +++ b/Legacy/Aria/include/ArRangeDevice.h @@ -0,0 +1,442 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARRANGEDEVICE_H +#define ARRANGEDEVICE_H + +#include "ariaTypedefs.h" +#include "ArRangeBuffer.h" +#include "ArSensorReading.h" +#include "ArDrawingData.h" +#include "ArMutex.h" +#include + +class ArRobot; + +/** + @brief The base class for all sensing devices which return range + information from the device (mounted on a robot) to an object in + the environment. + + This class maintains two ArRangeBuffer objects: a current buffer + (getCurrentBuffer()) + for storing very recent readings, and a cumulative buffer + (getCumulativeBuffer()) for a + longer history of readings. The maximum sizes of each buffer can + be set in the constructor or resized later. Range device readings + are most often represented as a point in space (X,Y) where the + sensor detected an object. (Therefore an ArPose object may only + have X and Y components set). + + Some devices provide an original set of "raw" ArSensorReading + objects (getRawReadings()) (that it used to add data to the current buffer) + which may also include extra device specific information as well. + Not all devices provide raw readings. + + Subclasses are used for specific sensor implementations like + ArSick for SICK lasers and ArSonarDevice for the Pioneer sonar + array. It can also be useful to treat "virtual" objects like + forbidden areas specified by the user in a map like range devices. + Some of these subsclasses may use a separate thread to update the + range reading buffers, and so this base class provides "lock" and + "unlock" methods which you should use when accessing device data. + + A range device may have an ArRobot object associated with it. A + range device may also be associated with an ArRobot by calling + ArRobot::addRangeDevice(). ArRobot provides functions which + operate on all such associated ArRangeDevice objects. This is a + convenient (and thread-safe) way to access all range device data + without depending on a specific set of individual range + devices. For example, you can find the closest reading in a box or + a polar section, no matter if that reading originated from the + sonar, a laser, or other device. + + @ingroup ImportantClasses +**/ + +class ArRangeDevice +{ +public: + /// Constructor + AREXPORT ArRangeDevice(size_t currentBufferSize, + size_t cumulativeBufferSize, + const char *name, unsigned int maxRange, + int maxSecondsToKeepCurrent = 0, + int maxSecondsToKeepCumulative = 0, + double maxDistToKeepCumulative = 0, + bool locationDependent = false); + /// Destructor + AREXPORT virtual ~ArRangeDevice(); + /// Gets the name of the device + AREXPORT virtual const char *getName(void) const; + /// Sets the robot this device is attached to + AREXPORT virtual void setRobot(ArRobot *robot); + /// Gets the robot this device is attached to + AREXPORT virtual ArRobot *getRobot(void); + /// Sets the maximum size of the buffer for current readings + AREXPORT virtual void setCurrentBufferSize(size_t size); + /// Gets the maximum size of the buffer for current readings + AREXPORT virtual size_t getCurrentBufferSize(void) const; + /// Sets the maximum size of the buffer for cumulative readings + AREXPORT virtual void setCumulativeBufferSize(size_t size); + /// Sets the maximum size of the buffer for cumulative readings + AREXPORT virtual size_t getCumulativeBufferSize(void) const; + /// Adds a reading to the buffer + AREXPORT virtual void addReading(double x, double y, bool *wasAdded = NULL); + /// Gets if this device is location dependent or not + bool isLocationDependent(void) { return myIsLocationDependent; } + /// Gets the closest current reading in the given polar region + AREXPORT virtual double currentReadingPolar(double startAngle, + double endAngle, + double *angle = NULL) const; + /// Gets the closest cumulative reading in the given polar region + AREXPORT virtual double cumulativeReadingPolar(double startAngle, + double endAngle, + double *angle = NULL) const; + /// Gets the closest current reading from the given box region + AREXPORT virtual double currentReadingBox(double x1, double y1, double x2, + double y2, + ArPose *readingPos = NULL) const; + /// Gets the closest current reading from the given box region + AREXPORT virtual double cumulativeReadingBox(double x1, double y1, double x2, + double y2, + ArPose *readingPos = NULL) const; +#ifndef SWIG + /** @brief Gets the current range buffer + * @swigomit See getCurrentBufferAsVector() + */ + virtual const ArRangeBuffer *getCurrentRangeBuffer(void) const + { return &myCurrentBuffer; } + /** @brief Gets the cumulative range buffer + * @swigomit See getCumulativeBufferAsVector() + */ + virtual const ArRangeBuffer *getCumulativeRangeBuffer(void) const + { return &myCumulativeBuffer; } + /** @brief Gets the current buffer of readings + * @swigomit See getCurrentBufferAsVector() + */ + virtual const std::list *getCurrentBuffer(void) const + { return myCurrentBuffer.getBuffer(); } + /** @brief Gets the current buffer of readings + * @swigomit See getCumulativeBufferAsVector() + */ + virtual const std::list *getCumulativeBuffer(void) const + { return myCumulativeBuffer.getBuffer(); } +#endif // SWIG + + /// Gets the current range buffer + virtual ArRangeBuffer *getCurrentRangeBuffer(void) + { return &myCurrentBuffer; } + /// Gets the cumulative range buffer + virtual ArRangeBuffer *getCumulativeRangeBuffer(void) + { return &myCumulativeBuffer; } + /// Gets the current buffer of readings + virtual std::list *getCurrentBuffer(void) + { return myCurrentBuffer.getBuffer(); } + /** @brief Gets the current buffer of readings as a vector + * @swignote The return type will be named + * ArPoseWithTimeVector instead of the std::vector template. + */ + virtual std::vector *getCurrentBufferAsVector(void) + { return myCurrentBuffer.getBufferAsVector(); } + /// Gets the current buffer of readings + virtual std::list *getCumulativeBuffer(void) + { return myCumulativeBuffer.getBuffer(); } + /** @brief Gets the cumulative buffer of readings as a vector + * @swignote The return type will be named ArPoseWithTimeVector + * instead of the std::vector template. + */ + virtual std::vector *getCumulativeBufferAsVector(void) + { return myCumulativeBuffer.getBufferAsVector(); } + + /// Gets the raw unfiltered readings from the device + /** The raw readings are the full set of unfiltered readings from the device. + They are the latest readings. You should not manipulate the list you get from + this function, the only manipulation of this list should be done by + the range device itself. (Its only pointers for speed.) + + @note Only ArSick provides this data currently. Sonar, bumpers, + etc. do not provide raw readings. + This method was added to this base class for future lasers or other + similar devices. + Other kinds of range devices are sufficiently different from lasers that + any "raw" information provided would usually require very different interpretation. + **/ + virtual const std::list *getRawReadings(void) const + { return myRawReadings; } + + /// Gets the raw unfiltered readings from the device into a vector + AREXPORT virtual std::vector *getRawReadingsAsVector(void); + + /// Gets the raw unfiltered readings from the device (but pose takens are corrected) + /** The raw readings are the full set of unfiltered readings from + the device. They are the latest readings. You should not + manipulate the list you get from this function, the only + manipulation of this list should be done by the range device + itself. (Its only pointers for speed.) + + This is like the raw readings but they were corrected for the + robot odometry offset (just the pose taken, and encoder psoe + taken). + + @note Only ArSick provides this data currently. Sonar, bumpers, + etc. do not provide raw readings. + This method was added to this base class for future lasers or other + similar devices. + Other kinds of range devices are sufficiently different from lasers that + any "raw" information provided would usually require very different interpretation. + **/ + virtual const std::list *getAdjustedRawReadings(void) const + { return myAdjustedRawReadings; } + + /// Gets the raw adjusted readings from the device into a vector + AREXPORT virtual std::vector *getAdjustedRawReadingsAsVector(void); + + + /// Sets the maximum seconds to keep current readings around + /** + @param maxSecondsToKeepCurrent this is the number of seconds to + keep current readings around, if less than 0 then they are not + automatically removed because of this + **/ + void setMaxSecondsToKeepCurrent(int maxSecondsToKeepCurrent) + { myMaxSecondsToKeepCurrent = maxSecondsToKeepCurrent; } + + /// gets the maximum seconds to keep current readings around + /** + @return this is the number of seconds current readings are kept + around for, if less than 0 then they are not automatically removed + because of this + **/ + int getMaxSecondsToKeepCurrent(void) { return myMaxSecondsToKeepCurrent; } + + /// Sets the minimum distance between current readings + /** + @param minDistBetweenCurrent The minimum distance between current + readings, this is applied in the addReading call so range devices + need to call that for this to take effect. + **/ + void setMinDistBetweenCurrent(double minDistBetweenCurrent) + { + myMinDistBetweenCurrent = minDistBetweenCurrent; + myMinDistBetweenCurrentSquared = (minDistBetweenCurrent * + minDistBetweenCurrent); + } + + /// Gets the minimum distance between current readings + /** + @return The minimum distance between current readings, this is + applied in the addReading call so range devices need to call that + for this to take effect. + **/ + double getMinDistBetweenCurrent(void) + { + return myMinDistBetweenCurrent; + } + + + /// gets the maximum seconds to keep cumulative readings around + /** + @param maxSecondsToKeepCumulative this is the number of seconds to keep + cumulative readings around, if less than 0 then they are not automatically + removed because of this + **/ + void setMaxSecondsToKeepCumulative(int maxSecondsToKeepCumulative) + { myMaxSecondsToKeepCumulative = maxSecondsToKeepCumulative; } + /// gets the maximum seconds to keep current readings around + /** + @return this is the number of seconds cumulative readings are kept + around for, if less than 0 then they are not automatically removed + because of this + **/ + int getMaxSecondsToKeepCumulative(void) + { return myMaxSecondsToKeepCumulative; } + + /// sets the maximum distance cumulative readings can be from current pose + /** + @param maxDistToKeepCumulative if cumulative readings are further than + this from where the current pose they are removed, if this is less + than 0 they are not removed because of this + **/ + void setMaxDistToKeepCumulative(double maxDistToKeepCumulative) + { + myMaxDistToKeepCumulative = maxDistToKeepCumulative; + myMaxDistToKeepCumulativeSquared = (maxDistToKeepCumulative * + maxDistToKeepCumulative); + } + + /// sets the maximum distance cumulative readings can be from current pose + /** + @return if cumulative readings are further than this from where the + current pose they are removed, if this is less than 0 they are not + removed because of this + **/ + double getMaxDistToKeepCumulative(void) { return myMaxDistToKeepCumulative; } + + /// Sets the minimum distance between cumulative readings + /** + @param minDistBetweenCumulative The minimum distance between cumulative + readings, this is applied in the addReading call so range devices + need to call that for this to take effect. + **/ + void setMinDistBetweenCumulative(double minDistBetweenCumulative) + { + myMinDistBetweenCumulative = minDistBetweenCumulative; + myMinDistBetweenCumulativeSquared = (minDistBetweenCumulative * + minDistBetweenCumulative); + } + + /// Gets the minimum distance between cumulative readings + /** + @return The minimum distance between cumulative readings, this is + applied in the addReading call so range devices need to call that + for this to take effect. + **/ + double getMinDistBetweenCumulative(void) + { + return myMinDistBetweenCumulative; + } + + /// Sets the maximum distance a cumulative reading can be from the robot and still be inserted + /** + @param maxInsertDistCumulative The maximum distance a cumulative + reading can have from the robot's current position and still be + inserted into the cumulative readings, this is applied in the + addReading call so range devices need to call that for this to + take effect. + **/ + void setMaxInsertDistCumulative(double maxInsertDistCumulative) + { + myMaxInsertDistCumulative = maxInsertDistCumulative; + myMaxInsertDistCumulativeSquared = (maxInsertDistCumulative * + maxInsertDistCumulative); + } + + /// Gets the maximum distance a cumulative reading can be from the robot and still be inserted + /** + @return The maximum distance a cumulative reading can have from + the robot's current position and still be inserted into the + cumulative readings, this is applied in the addReading call so + range devices need to call that for this to take effect. + **/ + double getMaxInsertDistCumulative(void) + { + return myMaxInsertDistCumulative; + } + + /// Clears all the current readings + virtual void clearCurrentReadings(void) { myCurrentBuffer.clear(); } + /// Clears all the cumulative readings + virtual void clearCumulativeReadings(void) { myCumulativeBuffer.clear(); } + /// Clears all the cumulative readings older than this number of milliseconds + virtual void clearCumulativeOlderThan(int milliSeconds) + { myCumulativeBuffer.clearOlderThan(milliSeconds); } + + /// Clears all the cumulative readings older than this number of seconds + virtual void clearCumulativeOlderThanSeconds(int seconds) + { myCumulativeBuffer.clearOlderThanSeconds(seconds); } + + /// Gets the maximum range for this device + virtual unsigned int getMaxRange(void) const { return myMaxRange; } + /// Sets the maximum range for this device + virtual void setMaxRange(unsigned int maxRange) + { myMaxRange = maxRange; } + + + /// Applies a transform to the buffers + AREXPORT virtual void applyTransform(ArTransform trans, + bool doCumulative = true); + + /// Gets data used for visualizing the current buffer (see ArNetworking) + virtual ArDrawingData *getCurrentDrawingData(void) + { return myCurrentDrawingData; } + /// Gets data used for visualizing the cumulative buffer (see ArNetworking) + virtual ArDrawingData *getCumulativeDrawingData(void) + { return myCumulativeDrawingData; } + /// Sets data for visualizing the current buffer (and if we own it) + AREXPORT virtual void setCurrentDrawingData(ArDrawingData *data, + bool takeOwnershipOfData); + /// Sets data for visualizing the cumulative buffer (and if we own it) + AREXPORT virtual void setCumulativeDrawingData(ArDrawingData *data, + bool takeOwnershipOfData); + + + + /// Lock this device + AREXPORT virtual int lockDevice() { return(myDeviceMutex.lock());} + /// Try to lock this device + AREXPORT virtual int tryLockDevice() {return(myDeviceMutex.tryLock());} + /// Unlock this device + AREXPORT virtual int unlockDevice() {return(myDeviceMutex.unlock());} + + /// Internal function to filter the readings based on age and distance + /// @internal + AREXPORT void filterCallback(void); + +protected: + /** + This call should be called by the range device every robot cycle + before the range device makes new readings (and even if it isn't + adding any that cycle)... it will adjust the raw readings by the + robot odometry offset. The robot should be locked when this + happens (which should be the case if you're doing it in the robot + callback). The code currently assumes that all readings were taken + at the same point, so if that isn't true with your device then you + can't use this mechanism. + **/ + AREXPORT void adjustRawReadings(bool interlaced); + std::vector myRawReadingsVector; + std::vector myAdjustedRawReadingsVector; + std::string myName; + ArRobot *myRobot; + unsigned int myMaxRange; + ArRangeBuffer myCurrentBuffer; + ArRangeBuffer myCumulativeBuffer; + + int myMaxSecondsToKeepCurrent; + double myMinDistBetweenCurrent; + double myMinDistBetweenCurrentSquared; + + int myMaxSecondsToKeepCumulative; + double myMaxDistToKeepCumulative; + double myMaxDistToKeepCumulativeSquared; + double myMinDistBetweenCumulative; + double myMinDistBetweenCumulativeSquared; + double myMaxInsertDistCumulative; + double myMaxInsertDistCumulativeSquared; + ArPose myMaxInsertDistCumulativePose; + + ArFunctorC myFilterCB; + std::list *myRawReadings; + std::list *myAdjustedRawReadings; + ArDrawingData *myCurrentDrawingData; + bool myOwnCurrentDrawingData; + ArDrawingData *myCumulativeDrawingData; + bool myOwnCumulativeDrawingData; + ArMutex myDeviceMutex; + bool myIsLocationDependent; +}; + +#endif // ARRANGEDEVICE_H diff --git a/Legacy/Aria/include/ArRangeDeviceThreaded.h b/Legacy/Aria/include/ArRangeDeviceThreaded.h new file mode 100644 index 0000000..481f725 --- /dev/null +++ b/Legacy/Aria/include/ArRangeDeviceThreaded.h @@ -0,0 +1,76 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARRANGEDEVICETHREADED_H +#define ARRANGEDEVICETHREADED_H + +#include "ariaTypedefs.h" +#include "ArRangeDevice.h" +#include "ArFunctorASyncTask.h" + +/// A range device which can run in its own thread +/** + This is a range device thats threaded, it doesn't do + multipleInheritance from both ArASyncTask and ArRangeDevice any + more since JAVA doesn't support this and the wrapper software + can't deal with it. Its still functionally the same however. + **/ +class ArRangeDeviceThreaded : public ArRangeDevice +{ +public: + /// Constructor + AREXPORT ArRangeDeviceThreaded(size_t currentBufferSize, + size_t cumulativeBufferSize, + const char *name, unsigned int maxRange, + int maxSecondsTokeepCurrent = 0, + int maxSecondsToKeepCumulative = 0, + double maxDistToKeepCumulative = 0, + bool locationDependent = false); + /// Destructor + AREXPORT virtual ~ArRangeDeviceThreaded(); + /// The functor you need to implement that will be the one executed by the thread + AREXPORT virtual void * runThread(void *arg) = 0; + /// Run in this thread + AREXPORT virtual void run(void) { myTask.run(); } + /// Run in its own thread + AREXPORT virtual void runAsync(void) { myTask.runAsync(); } + /// Stop the thread + AREXPORT virtual void stopRunning(void) { myTask.stopRunning(); } + /// Get the running status of the thread + AREXPORT virtual bool getRunning(void) { return myTask.getRunning();} + /// Get the running status of the thread, locking around the variable + AREXPORT virtual bool getRunningWithLock(void) + { return myTask.getRunningWithLock(); } + + AREXPORT virtual int lockDevice(void) { return myTask.lock(); } + AREXPORT virtual int tryLockDevice(void) { return myTask.tryLock(); } + AREXPORT virtual int unlockDevice(void) { return myTask.unlock(); } +protected: + ArRetFunctor1C myRunThreadCB; + ArFunctorASyncTask myTask; + +}; + +#endif // ARRANGEDEVICETHREADED_H diff --git a/Legacy/Aria/include/ArRatioInputJoydrive.h b/Legacy/Aria/include/ArRatioInputJoydrive.h new file mode 100644 index 0000000..2c59661 --- /dev/null +++ b/Legacy/Aria/include/ArRatioInputJoydrive.h @@ -0,0 +1,114 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARRATIOINPUTJOYDRIVE_H +#define ARRATIOINPUTJOYDRIVE_H + +#include "ariaTypedefs.h" +#include "ArAction.h" +#include "ArActionRatioInput.h" +#include "ArJoyHandler.h" + +class ArRobot; + +/// Use computer joystick to control an ArActionRatioInput and drive the robot. + +/** + This class obtains data from + a joystick attached to the computer + and provides it to an ArActionRatioInput which drives the robot. + (See ArRatioInputRobotJoydrive for a similar class that uses the robot's built in + joystick interface.) + A callback is attached to the ArActionRatioInput object which reads joystick + information and sets requested drive rations on the ArActionRatioInput + + If the joystick button is pressed, then input values are set in the + ArActionRatioDrive action object to request motion. + If the button is not pressed, then either the robot will be stopped via the + action (if @a stopIfNoButtonPressed is true), or no action will be requested + and lower priority actions can take over (if @a stopIfNoButtonPressed is + false) + + You may need to calibrate the joystick for + it to work right, for details about this see ArJoyHandler. + + This class creates its own ArJoyHandler object to get input from the + joystick, or uses the global ArJoyHandler object in the global Aria class if present. Then it will scale the speed between 0 and the given max + for velocity and turning, up and down on the joystick go + forwards/backwards while right and left go right and left. + + NOTE: The joystick does not save calibration information, so you + may need to calibrate the joystick before each time you use it. To do + this, press the button for at least a half a second while the + joystick is in the middle. Then let go of the button and hold the + joystick in the upper left for at least a half second and then in + the lower right corner for at least a half second. See also ArJoyHandler. + + @sa ArRatioInputRobotJoydrive + @sa ArActionRatioInput + @sa ArJoyHandler + + @ingroup OptionalClasses +**/ +class ArRatioInputJoydrive +{ +public: + /// Constructor + AREXPORT ArRatioInputJoydrive(ArRobot *robot, ArActionRatioInput *input, + int priority = 50, + bool stopIfNoButtonPressed = false, + bool useOSCalForJoystick = true); + /// Destructor + AREXPORT virtual ~ArRatioInputJoydrive(); + /// Whether the joystick is initalized or not + AREXPORT bool joystickInited(void); + /// Set if we'll stop if no button is pressed, otherwise just do nothing + AREXPORT void setStopIfNoButtonPressed(bool stopIfNoButtonPressed); + /// Get if we'll stop if no button is pressed, otherwise just do nothing + AREXPORT bool getStopIfNoButtonPressed(void); + /// Sets whether to use OSCalibration the joystick or not + AREXPORT void setUseOSCal(bool useOSCal); + /// Gets whether OSCalibration is being used for the joystick or not + AREXPORT bool getUseOSCal(void); + /// Gets the joyHandler + AREXPORT ArJoyHandler *getJoyHandler(void) { return myJoyHandler; } +protected: + void fireCallback(void); + ArRobot *myRobot; + ArActionRatioInput *myInput; + // if we're printing extra information for tracing and such + bool myPrinting; + // joystick handler + ArJoyHandler *myJoyHandler; + bool myFiredLast; + // if we want to stop when no button is presesd + bool myStopIfNoButtonPressed; + // if we're using os cal for the joystick + bool myUseOSCal; + bool myPreviousUseOSCal; + ArFunctorC myFireCB; +}; + +#endif //ARRATIOINPUTJOYDRIVE_H diff --git a/Legacy/Aria/include/ArRatioInputKeydrive.h b/Legacy/Aria/include/ArRatioInputKeydrive.h new file mode 100644 index 0000000..558424a --- /dev/null +++ b/Legacy/Aria/include/ArRatioInputKeydrive.h @@ -0,0 +1,99 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARRATIOINPUTKEYDRIVE_H +#define ARRATIOINPUTKEYDRIVE_H + +#include "ariaTypedefs.h" +#include "ArAction.h" +#include "ArFunctor.h" +#include "ArActionRatioInput.h" + + +/// This will use the keyboard arrow keys and the ArActionRatioInput to drive the robot +/** + You have to make an ArActionRatioInput and add it to the robot like + a normal action for this to work. + + @ingroup OptionalClasses +**/ +class ArRatioInputKeydrive +{ +public: + /// Constructor + AREXPORT ArRatioInputKeydrive(ArRobot *robot, ArActionRatioInput *input, + int priority = 25, double velIncrement = 5); + /// Destructor + AREXPORT virtual ~ArRatioInputKeydrive(); + /// Takes the keys this action wants to use to drive + AREXPORT void takeKeys(void); + /// Gives up the keys this action wants to use to drive + AREXPORT void giveUpKeys(void); + /// Internal, callback for up arrow + AREXPORT void up(void); + /// Internal, callback for down arrow + AREXPORT void down(void); + /// Internal, callback for z + AREXPORT void z(void); + /// Internal, callback for x + AREXPORT void x(void); + /// Internal, callback for left arrow + AREXPORT void left(void); + /// Internal, callback for right arrow + AREXPORT void right(void); + /// Internal, callback for space key + AREXPORT void space(void); + /// Internal, gets our firecb + AREXPORT ArFunctor *getFireCB(void) { return &myFireCB; } +protected: + AREXPORT void activate(void); + AREXPORT void deactivate(void); + AREXPORT void fireCallback(void); + ArFunctorC myUpCB; + ArFunctorC myDownCB; + ArFunctorC myLeftCB; + ArFunctorC myRightCB; + ArFunctorC myZCB; + ArFunctorC myXCB; + ArFunctorC mySpaceCB; + + double myPrinting; + double myTransRatio; + double myRotRatio; + double myThrottle; + double myLatRatio; + + ArRobot *myRobot; + bool myHaveKeys; + double myVelIncrement; + double myLatVelIncrement; + ArActionRatioInput *myInput; + ArFunctorC myFireCB; + ArFunctorC myActivateCB; + ArFunctorC myDeactivateCB; +}; + + +#endif // ARRATIOINPUTKEYDRIVE_H diff --git a/Legacy/Aria/include/ArRatioInputRobotJoydrive.h b/Legacy/Aria/include/ArRatioInputRobotJoydrive.h new file mode 100644 index 0000000..d2cdbbd --- /dev/null +++ b/Legacy/Aria/include/ArRatioInputRobotJoydrive.h @@ -0,0 +1,76 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARRATIOINPUTROBOTJOYDRIVE_H +#define ARRATIOINPUTROBOTJOYDRIVE_H + +#include "ariaTypedefs.h" +#include "ArActionRatioInput.h" + +class ArRobotPacket; +class ArRobot; +class ArRobotJoyHandler; + +/// Use robot's joystick to control an ArActionRatioInput action and drive the robot. +/** + This class connects the joystick data obtained from the robot's built + in joystick port (if it has one, not all robots have a joystick port) + to an ArActionRatioInput which drives the robot. (See ArRatioInputJoydrive + for a similar class that uses a joystick plugged in to the computer.) + + A callback is attached to the ArActionRatioInput object which reads joystick + information using an ArRobotJoyHandler object, and sets requested drive rations on the ArActionRatioInput + object. + + + @sa ArRatioInputJoydrive + @sa ArActionRatioInput + + + @ingroup OptionalClasses +**/ +class ArRatioInputRobotJoydrive +{ +public: + /// Constructor + AREXPORT ArRatioInputRobotJoydrive(ArRobot *robot, + ArActionRatioInput *input, + int priority = 75, + bool requireDeadmanPushed = true); + /// Destructor + AREXPORT virtual ~ArRatioInputRobotJoydrive(); +protected: + AREXPORT void fireCallback(void); + + ArRobot *myRobot; + ArActionRatioInput *myInput; + bool myRequireDeadmanPushed; + bool myDeadZoneLast; + + ArRobotJoyHandler *myRobotJoyHandler; + ArFunctorC myFireCB; +}; + +#endif //ARRATIOINPUTROBOTJOYDRIVE_H diff --git a/Legacy/Aria/include/ArRecurrentTask.h b/Legacy/Aria/include/ArRecurrentTask.h new file mode 100644 index 0000000..43760ea --- /dev/null +++ b/Legacy/Aria/include/ArRecurrentTask.h @@ -0,0 +1,87 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +// ArRecurrentTask.h -- Recurrent async task interface class +#ifndef ARRECURASYNCTASK_H +#define ARRECURASYNCTASK_H + + +#include "ariaTypedefs.h" +#include "ArFunctor.h" +#include "ArThread.h" +#include "ArASyncTask.h" + +/// Recurrent task (runs in its own thread) +/** + The ArRecurrentTask is a task that runs in its own thread. Recurrent + tasks are asynchronous tasks that complete in a finite amount of time, + and need to be reinvoked recurrently. A typical example is Saphira's + localization task: it runs for a few hundred milliseconds, localizes the + robot, and returns. Then the cycle starts over. + The user simply needs to derive their own class + from ArRecurrentTask and define the task() function. This is the user + code that will be called to execute the task body. + Then, create an object of the class, and call the go() function to + start the task. The status of the task can be checked with the + done() function, which returns 0 if running, 1 if completed, and 2 if + killed. + go() can be called whenever the task is done to restart it. To stop the + task in midstream, call reset(). + kill() kills off the thread, shouldn't be used unless exiting the + async task permanently +*/ +class ArRecurrentTask : public ArASyncTask +{ +public: + /// Constructor + AREXPORT ArRecurrentTask(); + /// Descructor + AREXPORT ~ArRecurrentTask(); + /// The main run loop + /** + Override this function and put your task here. + */ + virtual void task() = 0; + /// Starts up on cycle of the recurrent task + AREXPORT void go(); + /// Check if the task is running or not + /** + 0 = running, 1 = finished normally, 2 = canceled + */ + AREXPORT int done(); + /// Cancel the task and reset for the next cycle + AREXPORT void reset(); // stops the current thread and restarts it + AREXPORT void kill(); // kills the current thread + + AREXPORT void *runThread(void *ptr); // main task loop + +private: + bool running; // true if currently running + bool go_req; // run request + bool killed; // did we get killed by request? +}; + + +#endif // ARRECURASYNCTASK_H diff --git a/Legacy/Aria/include/ArResolver.h b/Legacy/Aria/include/ArResolver.h new file mode 100644 index 0000000..fd8c6c0 --- /dev/null +++ b/Legacy/Aria/include/ArResolver.h @@ -0,0 +1,65 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARRESOLVER_H +#define ARRESOLVER_H + +#include "ariaTypedefs.h" +#include "ArActionDesired.h" +#include + +class ArAction; +class ArRobot; + +/// Resolves a list of actions and returns what to do +/** + ArResolver::resolve() is the function that ArRobot + calls with the action list in order + to produce a combined ArActionDesired object from them, according to + the subclass's particular algorithm or policy. +*/ +class ArResolver +{ +public: + /// Constructor + typedef std::multimap ActionMap; + ArResolver(const char *name, const char * description = "") + { myName = name; myDescription = description; } + /// Desturctor + virtual ~ArResolver() {}; + /// Figure out a single ArActionDesired from a list of ArAction s + virtual ArActionDesired *resolve(ActionMap *actions, ArRobot *robot, + bool logActions = false) = 0; + /// Gets the name of the resolver + virtual const char *getName(void) const { return myName.c_str(); } + /// Gets the long description fo the resolver + virtual const char *getDescription(void) const { return myDescription.c_str(); } + +protected: + std::string myName; + std::string myDescription; +}; + +#endif diff --git a/Legacy/Aria/include/ArRingQueue.h b/Legacy/Aria/include/ArRingQueue.h new file mode 100644 index 0000000..144bf56 --- /dev/null +++ b/Legacy/Aria/include/ArRingQueue.h @@ -0,0 +1,229 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ + + +#ifndef _AR_RING_QUEUE_H_ +#define _AR_RING_QUEUE_H_ + +#include +#include +#include + +/** @brief An expanding ring queue. + * + * It is used to keep a queue with a minimum of allocation and freeing of + * heap memory. + * The ring queue is implemented using std::list. The queue starts with an + * initial capacity, but those initial items are considered 'unused'. Items + * are "pushed" into the queue at the "back", and "popped" from the queue at + * the "front". pop() and advance_front() will move the front of the queue to + * the next item, creating a new 'unused slot' for future use; advance_back() + * changes the next item in the back to a 'used' slot. push() either uses the + * next 'unused' slot, or inserts a new item into the std::list. + * When the capacity of the queue is filled, all operations will fail + * except push(). Use push() to insert new items in the queue and increase + * its capacity. + * + * @todo Ideally, this class would be fully threadsafe (with occasional or no mutex + * locking), but it is not currently. + * @todo Optionally allocate several future 'slots' instead of just one. + * + * @ingroup UtilityClasses + */ +template +class ArRingQueue { +public: + /** @param capacity Initial capacity of the ring queue. + * @param init_value Initial value for new, unused items in the queue. + * */ + ArRingQueue(int capacity, T init_value) + : ring(capacity, init_value), curSize(0), initval(init_value) + { + back_it = ring.begin(); + front_it = ring.end();// signals empty state + } + + + /** Get an iterator for the front item of the ring queue (the item that would + * be returned by pop()). If the queue is currently empty, nil() will be + * returned. + * + * To remove an item from the queue without + * making a copy with pop(), first check if the queue is empty(). Then use this + * function to get the data. Then call advance_front(). + */ + typename std::list::iterator front() { + if(empty()) + return nil(); + return front_it; + } + + /** Get an iterator for the back of the queue (the item that would be + * replaced by push()). This is not the last item in the queue, rather it is the + * next, unused, "slot". If the queue is full, an iterator equivalent to that + * returned by nil() is returned. + * + * To add an item to the queue without pushing + * a copy with push(), first check if the queue is full (in which case you + * must push() your item). Then use this function to write the data into the + * next unused 'slot'. Then call advance_back() to advance the back of the queue + * to your new item. + */ + typename std::list::iterator back() { + if(front_it == back_it) + { + //std::cerr << "ArRingQueue: back(): 0-capacity or full, returning nil.\n"; + return nil(); + } + return back_it; + } + + /** Advance (pop) the front of the queue. 'Used' size will be decremented. */ + void advance_front() { + if(front_it == ring.end()) // initial or empty state. + front_it = ring.begin(); + else if(++front_it == ring.end()) + front_it = ring.begin(); + if(front_it == back_it) { // it's now empty (not full) + front_it = ring.end(); + back_it = ring.begin(); + } + curSize--; + } + + /** Same as advance_front() */ + void pop_front() { advance_front(); }; + + /** Advance the back (an 'empty' push), if the queue is not full. 'Used' size will be incremented. */ + void advance_back() { + if(front_it == back_it) // full or 0-capacity + { + // debugging: + /* + if(empty()) { + std::cerr << "ArRingQueue: advance_back(): queue is *empty*, can't advance back.\n"; + return; + } + std::cerr << "ArRingQueue: advance_back(): queue is full, can't advance back.\n"; + */ + return; + } + if(++back_it == ring.end()) + back_it = ring.begin(); + if(front_it == ring.end()) + front_it = ring.begin(); // no longer empty. + curSize++; + } + + /** Add an item to the back of the ring queue. If the queue is full, the + * capacity of the queue will be expanded and the item + * will be inserted. */ + void push(const T& item) { + if(full()) { + // expand + back_it = ring.insert(back_it, item); + } else { + // back is unused, use it + *back_it = item; + } + advance_back(); + } + + /** Same as push() */ + void push_back(const T& item) { push(item); } + + /** Push a new item, but preserve capacity: instead of expanding the queue if + * full, then the oldest item is replaced and the front is advanced. + */ + void push_without_expanding(const T& item) { + if(full()) + advance_front(); + push(item); + } + + /** Print the current contents of the queue. + * @pynote use printQueue() instead of print() (which is a reserved word in Python) + */ + void print() { + for(typename std::list::const_iterator i = ring.begin(); i != ring.end(); i++) { + if(i == back_it) + std::cerr << "]"; + if(i == front_it || (i == ring.begin() && front_it == ring.end()) ) + std::cerr << "["; + std::cerr << (*i) << "," ; + } + std::cerr << std::endl; + } + + /** Get the number of items currently 'used' in the queue. */ + size_t size() { + return curSize; + } + + /** Get the current capacity of the queue. */ + size_t capacity() { + return ring.size(); + } + + /** Return true if the queue is empty (has no 'used' items), false otherwise. */ + bool empty() { + return (front_it == ring.end()); + } + + /** Logically clear the queue, resetting to initial empty state, but preserving current + * capacity, and leaving all contents as they are; the contents are not + * destroyed, but will be when replaced by new data later. */ + void reset() { + front_it = ring.end(); + back_it = ring.begin(); + curSize = 0; + } + + /** Return true if the queue is full, false otherwise. */ + bool full() { + return (back_it == front_it); + } + + /** Return an iterator representing an invalid item. Compare to the return + * values of front(), back(), pop(), etc. */ + typename std::list::iterator nil() { + return ring.end(); + } + +protected: + std::list ring; + typename std::list::iterator front_it, back_it; + // push to back, pop from front; front will point to first item, + // back to one past last. + + size_t curSize; + T initval; + +}; + + + +#endif diff --git a/Legacy/Aria/include/ArRobot.h b/Legacy/Aria/include/ArRobot.h new file mode 100644 index 0000000..d6fff19 --- /dev/null +++ b/Legacy/Aria/include/ArRobot.h @@ -0,0 +1,1848 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARROBOT_H +#define ARROBOT_H + +#include "ariaTypedefs.h" +#include "ArRobotPacketSender.h" +#include "ArRobotPacketReceiver.h" +#include "ArFunctor.h" +#include "ArFunctor.h" +#include "ArSyncTask.h" +#include "ArSensorReading.h" +#include "ArMutex.h" +#include "ArCondition.h" +#include "ArSyncLoop.h" +#include "ArRobotPacketReaderThread.h" +#include "ArRobotParams.h" +#include "ArActionDesired.h" +#include "ArResolver.h" +#include "ArTransform.h" +#include "ArInterpolation.h" +#include "ArKeyHandler.h" +#include + +class ArAction; +class ArRobotConfigPacketReader; +class ArRobotBatteryPacketReader; +class ArDeviceConnection; +class ArRangeDevice; +class ArRobotPacket; +class ArPTZ; +class ArLaser; +class ArBatteryMTX; +class ArSonarMTX; +class ArLCDMTX; + +/// Central class for communicating with and operating the robot +/** + This is the most important class. It is used to communicate with + the robot by sending commands and retrieving data (including + wheel odometry, digital and analog inputs, sonar data, and more). + It is also used + to provide access to objects for controlling attached accessories, + ArRangeDevice objects, ArAction objects, and others. For details + on usage, and how the task cycle and obot state synchronization works, + see the @ref robot "ArRobot section" and the + @ref ClientCommands "Commands and Actions section" of the ARIA overview. + + @note In Windows you cannot make an ArRobot object a global variable, + it will crash because the compiler initializes the constructors in + the wrong order. You can, however, make a pointer to an ArRobot and then + allocate it with 'new' at program start. + + @see ArRobotConnector + + @ingroup ImportantClasses + @ingroup DeviceClasses +**/ +class ArRobot +{ +public: + + typedef enum { + WAIT_CONNECTED, ///< The robot has connected + WAIT_FAILED_CONN, ///< The robot failed to connect + WAIT_RUN_EXIT, ///< The run loop has exited + WAIT_TIMEDOUT, ///< The wait reached the timeout specified + WAIT_INTR, ///< The wait was interupted by a signal + WAIT_FAIL ///< The wait failed due to an error + } WaitState; + + enum ChargeState { + CHARGING_UNKNOWN = -1, + CHARGING_NOT = 0, + CHARGING_BULK = 1, + CHARGING_OVERCHARGE = 2, + CHARGING_FLOAT = 3, + CHARGING_BALANCE = 4 + }; + /// Constructor + AREXPORT ArRobot(const char * name = NULL, bool ignored = true, + bool doSigHandle=true, + bool normalInit = true, bool addAriaExitCallback = true); + + /// Destructor + AREXPORT ~ArRobot(); + + /// Starts the instance to do processing in this thread + AREXPORT void run(bool stopRunIfNotConnected, + bool runNonThreaded = false); + /// Starts the instance to do processing in its own new thread + AREXPORT void runAsync(bool stopRunIfNotConnected, + bool runNonThreadedPacketReader = false); + + /// Returns whether the robot is currently running or not + AREXPORT bool isRunning(void) const; + + /// Stops the robot from doing any more processing + AREXPORT void stopRunning(bool doDisconnect=true); + + /// Sets the connection this instance uses + AREXPORT void setDeviceConnection(ArDeviceConnection *connection); + /// Gets the connection this instance uses + AREXPORT ArDeviceConnection *getDeviceConnection(void) const; + + /// Questions whether the robot is connected or not + /** + @return true if connected to a robot, false if not + */ + AREXPORT bool isConnected(void) const { return myIsConnected; } + /// Connects to a robot, not returning until connection made or failed + AREXPORT bool blockingConnect(void); + /// Connects to a robot, from the robots own thread + AREXPORT bool asyncConnect(void); + /// Disconnects from a robot + AREXPORT bool disconnect(void); + + /// Clears what direct motion commands have been given, so actions work + AREXPORT void clearDirectMotion(void); + /// Returns true if direct motion commands are blocking actions + AREXPORT bool isDirectMotion(void) const; + + /// Sets the state reflection to be inactive (until motion or clearDirectMotion) + /// @see clearDirectMotion + AREXPORT void stopStateReflection(void); + + + /// Enables the motors on the robot + AREXPORT void enableMotors(); + /// Disables the motors on the robot + AREXPORT void disableMotors(); + + /// Enables the sonar on the robot + AREXPORT void enableSonar(); + /// Enables some of the sonar on the robot (the ones for autonomous driving) + AREXPORT void enableAutonomousDrivingSonar(); + /// Disables the sonar on the robot + AREXPORT void disableSonar(); + + /// Stops the robot + /// @see clearDirectMotion + AREXPORT void stop(void); + /// Sets the velocity + /// @see clearDirectMotion + AREXPORT void setVel(double velocity); + /// Sets the velocity of the wheels independently + AREXPORT void setVel2(double leftVelocity, double rightVelocity); + /// Move the given distance forward/backwards + AREXPORT void move(double distance); + /// Sees if the robot is done moving the previously given move + AREXPORT bool isMoveDone(double delta = 0.0); + /// Sets the difference required for being done with a move + AREXPORT void setMoveDoneDist(double dist) { myMoveDoneDist = dist; } + /// Gets the difference required for being done with a move + AREXPORT double getMoveDoneDist(void) { return myMoveDoneDist; } + /// Sets the heading + AREXPORT void setHeading(double heading); + /// Sets the rotational velocity + AREXPORT void setRotVel(double velocity); + /// Sets the delta heading + AREXPORT void setDeltaHeading(double deltaHeading); + /// Sees if the robot is done changing to the previously given setHeading + AREXPORT bool isHeadingDone(double delta = 0.0) const; + /// sets the difference required for being done with a heading change (e.g. used in isHeadingDone()) + AREXPORT void setHeadingDoneDiff(double degrees) + { myHeadingDoneDiff = degrees; } + /// Gets the difference required for being done with a heading change (e.g. used in isHeadingDone()) + AREXPORT double getHeadingDoneDiff(void) const { return myHeadingDoneDiff; } + /// Sets the lateral velocity + /// @see clearDirectMotion + AREXPORT void setLatVel(double latVelocity); + + /// Sets the length of time a direct motion command will take precedence + /// over actions, in milliseconds + AREXPORT void setDirectMotionPrecedenceTime(int mSec); + + /// Gets the length of time a direct motion command will take precedence + /// over actions, in milliseconds + AREXPORT unsigned int getDirectMotionPrecedenceTime(void) const; + + /// Sends a command to the robot with no arguments + AREXPORT bool com(unsigned char command); + /// Sends a command to the robot with an int for argument + AREXPORT bool comInt(unsigned char command, short int argument); + /// Sends a command to the robot with two bytes for argument + AREXPORT bool com2Bytes(unsigned char command, char high, char low); + /// Sends a command to the robot with a length-prefixed string for argument + AREXPORT bool comStr(unsigned char command, const char *argument); + /// Sends a command to the robot with a length-prefixed string for argument + AREXPORT bool comStrN(unsigned char command, const char *str, int size); + /// Sends a command containing exactly the data in the given buffer as argument + AREXPORT bool comDataN(unsigned char command, const char *data, int size); + + /// Returns the robot's name that is set in its onboard firmware configuration + const char * getRobotName(void) const { return myRobotName.c_str();} + /// Returns the type of the robot we are currently connected to + const char * getRobotType(void) const { return myRobotType.c_str();} + /// Returns the subtype of the robot we are currently connected to + const char * getRobotSubType(void) const + { return myRobotSubType.c_str(); } + + /// Gets the robot's absolute maximum translational velocity + double getAbsoluteMaxTransVel(void) const + { return myAbsoluteMaxTransVel; } + /// Sets the robot's absolute maximum translational velocity + AREXPORT bool setAbsoluteMaxTransVel(double maxVel); + + /// Gets the robot's absolute maximum translational velocity + double getAbsoluteMaxTransNegVel(void) const + { return myAbsoluteMaxTransNegVel; } + /// Sets the robot's absolute maximum translational velocity + AREXPORT bool setAbsoluteMaxTransNegVel(double maxVel); + + /// Gets the robot's absolute maximum translational acceleration + AREXPORT double getAbsoluteMaxTransAccel(void) const + { return myAbsoluteMaxTransAccel; } + /// Sets the robot's absolute maximum translational acceleration + AREXPORT bool setAbsoluteMaxTransAccel(double maxAccel); + + /// Gets the robot's absolute maximum translational deceleration + double getAbsoluteMaxTransDecel(void) const + { return myAbsoluteMaxTransDecel; } + /// Sets the robot's absolute maximum translational deceleration + AREXPORT bool setAbsoluteMaxTransDecel(double maxDecel); + + /// Gets the robot's absolute maximum rotational velocity + double getAbsoluteMaxRotVel(void) const + { return myAbsoluteMaxRotVel; } + /// Sets the robot's absolute maximum rotational velocity + AREXPORT bool setAbsoluteMaxRotVel(double maxVel); + + /// Gets the robot's absolute maximum rotational acceleration + double getAbsoluteMaxRotAccel(void) const + { return myAbsoluteMaxRotAccel; } + /// Sets the robot's absolute maximum rotational acceleration + AREXPORT bool setAbsoluteMaxRotAccel(double maxAccel); + + /// Gets the robot's absolute maximum rotational deceleration + double getAbsoluteMaxRotDecel(void) const + { return myAbsoluteMaxRotDecel; } + /// Sets the robot's absolute maximum rotational deceleration + AREXPORT bool setAbsoluteMaxRotDecel(double maxDecel); + + /// Gets the robot's absolute maximum lateral velocity + double getAbsoluteMaxLatVel(void) const + { return myAbsoluteMaxLatVel; } + /// Sets the robot's absolute maximum lateral velocity + AREXPORT bool setAbsoluteMaxLatVel(double maxVel); + + /// Gets the robot's absolute maximum lateral acceleration + double getAbsoluteMaxLatAccel(void) const + { return myAbsoluteMaxLatAccel; } + /// Sets the robot's absolute maximum lateral acceleration + AREXPORT bool setAbsoluteMaxLatAccel(double maxAccel); + + /// Gets the robot's absolute maximum lateral deceleration + double getAbsoluteMaxLatDecel(void) const + { return myAbsoluteMaxLatDecel; } + /// Sets the robot's absolute maximum lateral deceleration + AREXPORT bool setAbsoluteMaxLatDecel(double maxDecel); + + + // Accessors + + /** @brief Get the current stored global position of the robot. + * + * This position is updated by data reported by the robot as it + * moves, and may also be changed by other program components, + * such as a localization process (see moveTo()). + * + * This position is also referred to as the robot's + * "odometry" or "odometric" pose, since the robot + * uses its odometry data to determine this pose; but it + * may also incorporate additional data sources such as + * an onboard gyro. The term "odometric pose" also + * distinguishes this position by the fact that its + * coordinate system may be arbitrary, and seperate + * from any external coordinate system. + * + * @sa getEncoderPose() + * @sa moveTo() + * + */ + ArPose getPose(void) const { return myGlobalPose; } + /// Gets the global X position of the robot + /** @sa getPose() */ + double getX(void) const { return myGlobalPose.getX(); } + /// Gets the global Y position of the robot + /** @sa getPose() */ + double getY(void) const { return myGlobalPose.getY(); } + /// Gets the global angular position ("theta") of the robot + /** @sa getPose() */ + double getTh(void) const { return myGlobalPose.getTh(); } + /// Gets the distance to a point from the robot's current position + double findDistanceTo(const ArPose pose) + { return myGlobalPose.findDistanceTo(pose); } + /// Gets the angle to a point from the robot's current position and orientation + double findAngleTo(const ArPose pose) + { return myGlobalPose.findAngleTo(pose); } + /// Gets the difference between the angle to a point from the robot's current heading + double findDeltaHeadingTo(const ArPose pose) + { return ArMath::subAngle(myGlobalPose.findAngleTo(pose), + myGlobalPose.getTh()); } + + + /// Gets the current translational velocity of the robot + double getVel(void) const { return myVel; } + /// Gets the current rotational velocity of the robot + /** + Note that with new firmware versions (ARCOS as of April 2006 or so) + this is the velocity reported by the robot. With older firmware + this number is calculated using the difference between the robot's reported wheel + velocities multiplied by diffConvFactor from the .p (robot parameter) files. + **/ + double getRotVel(void) const { return myRotVel; } + /// Gets the current lateral velocity of the robot + /** + Note that this will only be valid if hasLatVel() returns true + @since 2.6.0 + **/ + double getLatVel(void) const { return myLatVel; } + /** Sees if the robot supports lateral velocities (e.g. Seekur(TM)) + @since 2.6.0 + */ + bool hasLatVel(void) const { return myParams->hasLatVel(); } + /// Gets the robot radius (in mm) + double getRobotRadius(void) const { return myParams->getRobotRadius(); } + /// Gets the robot width (in mm) + double getRobotWidth(void) const { return myParams->getRobotWidth(); } + /// Gets the robot length (in mm) + double getRobotLength(void) const { return myParams->getRobotLength(); } + /// Gets the robot length to the front (in mm) + double getRobotLengthFront(void) const { return myRobotLengthFront; } + /// Gets the robot length to the front (in mm) + double getRobotLengthRear(void) const { return myRobotLengthRear; } + /// Gets distance from center of robot to first vertex of octagon approximating the shape of robot. (mm) + double getRobotDiagonal(void) const { return myParams->getRobotDiagonal(); } + /// Gets the battery voltage of the robot (normalized to 12 volt system) + /** + This value is averaged over a number of readings, use getBatteryVoltageNow() to + get the value most recently received. (Access the number of readings + used in the running average with getBatteryVoltageAverageOfNum() and + setBatteryVoltageAverageOfNum().) + + This is a value normalized to 12 volts, if you want what the + actual voltage of the robot is use getRealBatteryVoltage(). + + @sa getRealBatteryVoltage() + @sa getBatteryVoltageNow() + **/ + double getBatteryVoltage(void) const {return myBatteryAverager.getAverage();} + /// Gets the instaneous battery voltage + /** + This is a value normalized to 12 volts, if you want what the + actual voltage of the robot is use getRealBatteryVoltage(). + + @sa getBatteryVoltage() + @sa getRealBatteryVoltage() + **/ + double getBatteryVoltageNow(void) const { return myBatteryVoltage; } + /// Gets the real battery voltage of the robot + /** + This value is averaged over a number of readings, use getRealBatteryVoltageNow() to + get the value most recently received. (Access the number of readings + used in the running average with getRealBatteryVoltageAverageOfNum() and + setRealBatteryVoltageAverageOfNum().) + + This is whatever the actual voltage of the robot is, if you want + a value normalized to common 12 volts for all robot types use getBatteryVoltage(). + + If the robot doesn't support a "real" battery voltage, then + this method will just return the normal battery voltage (normalized to 12 + volt scale). (Most older robots that don't support a real battery voltage + have 12 volts batteries anyway.) + **/ + double getRealBatteryVoltage(void) const + { return myRealBatteryAverager.getAverage(); } + /// Gets the instaneous battery voltage + /** + This is whatever the actual voltage of the robot is, if you want + a value normalized to a common 12 volts for all robot types use getBatteryVoltage(). If the + robot doesn't support this number the voltage will be less than 0 + and you should use getBatteryVoltageNow(). + **/ + double getRealBatteryVoltageNow(void) const { return myRealBatteryVoltage; } + /// Gets if the state of charge value is in use + bool haveStateOfCharge(void) const { return myHaveStateOfCharge; } + /// @copydoc haveStateOfCharge() + bool hasStateOfCHarge() const { return haveStateOfCharge(); } + /// Gets the state of charge (percent of charge, as number between 0 and 100) + double getStateOfCharge(void) const + { if (!myHaveStateOfCharge) return 0; else return myStateOfCharge; } + /// Gets the last time the state of charge was set + ArTime getStateOfChargeSetTime(void) const { return myStateOfChargeSetTime; } + /// Gets the state of charge that is considered low + double getStateOfChargeLow(void) const + { return myStateOfChargeLow; } + /// Gets the state of charge (percent of charge, as number between 0 and 100) + double getStateOfChargeShutdown(void) const + { return myStateOfChargeShutdown; } + /// Gets the velocity of the left wheel + double getLeftVel(void) const { return myLeftVel; } + /// Gets the velocity of the right wheel + double getRightVel(void) const { return myRightVel; } + /// Gets the 2 bytes of stall and bumper flags from the robot + /** See robot operations manual SIP packet documentation for details. + * @sa isLeftMotorStalled() + * @sa isRightMotorStalled() + */ + int getStallValue(void) const { return myStallValue; } + /// Returns true if the left motor is stalled + bool isLeftMotorStalled(void) const + { return (myStallValue & 0xff) & ArUtil::BIT0; } + /// Returns true if the left motor is stalled + bool isRightMotorStalled(void) const + { return ((myStallValue & 0xff00) >> 8) & ArUtil::BIT0; } + /// Gets the legacy control heading + /** + Gets the control heading as an offset from the current heading... + Note that this doesn't work in any modern firmware (uARCS, ARCOS, + seekur, AmigoSH) + @see getTh + */ + double getControl(void) const { return myControl; } + /// Sets whether to keep the control value raw or not + void setKeepControlRaw(bool keepControlRaw) + { myKeepControlRaw = keepControlRaw; } + /// Gets whether the control value is kept raw + bool getKeepControlRaw(void) + { return myKeepControlRaw; } + /// Gets the flags values + int getFlags(void) const { return myFlags; } + /// Gets the fault flags values + int getFaultFlags(void) const { return myFaultFlags; } + /// Gets whether or not we're getting the fault flags values + bool hasFaultFlags(void) const { return myHasFaultFlags; } + /// returns true if the motors are enabled + bool areMotorsEnabled(void) const { return (myFlags & ArUtil::BIT0); } + /// returns true if the sonars are enabled + /** This used to just check the low level firmware values, but + * that's now done by areSonarsEnabledLegacy. + */ + bool areSonarsEnabled(void) const + { return mySonarEnabled; } + /// returns true if the sonars are enabled for autonomous driving + bool areAutonomousDrivingSonarsEnabled(void) const + { return myAutonomousDrivingSonarEnabled; } + /// returns true if the sonars are enabled on legacy platforms (by checking the low level stuff) + bool areSonarsEnabledLegacy(void) const { + return (myFlags & + (ArUtil::BIT1 | ArUtil::BIT2 | ArUtil::BIT3 | ArUtil::BIT4)); } + /// returns true if the estop is pressed (or unrelieved) + bool isEStopPressed(void) const { return (myFlags & ArUtil::BIT5); } + + /// Returns true if the E-Stop button is pressed + bool getEstop(void) { return isEStopPressed(); } + + /// Gets the compass heading from the robot + double getCompass(void) const { return myCompass; } + /// Gets which analog port is selected + int getAnalogPortSelected(void) const { return myAnalogPortSelected; } + /// Gets the analog value + unsigned char getAnalog(void) const { return myAnalog; } + /// Gets the byte representing digital input status + unsigned char getDigIn(void) const { return myDigIn; } + /// Gets the byte representing digital output status + unsigned char getDigOut(void) const { return myDigOut; } + /// Gets the charge state of the robot (see long docs) + AREXPORT ChargeState getChargeState(void) const; + /// Gets if the robot is on a charger + AREXPORT bool isChargerPowerGood(void) const; + + /// Gets the number of bytes in the analog IO buffer + int getIOAnalogSize(void) const { return myIOAnalogSize; } + /// Gets the number of bytes in the digital input IO buffer + int getIODigInSize(void) const { return myIODigInSize; } + /// Gets the number of bytes in the digital output IO buffer + int getIODigOutSize(void) const { return myIODigOutSize; } + + /// Gets the n'th byte from the analog input data from the IO packet + AREXPORT int getIOAnalog(int num) const; + /// Gets the n'th byte from the analog input data from the IO packet + AREXPORT double getIOAnalogVoltage(int num) const; + /// Gets the n'th byte from the digital input data from the IO packet + AREXPORT unsigned char getIODigIn(int num) const; + /// Gets the n'th byte from the digital output data from the IO packet + AREXPORT unsigned char getIODigOut(int num) const; + + /// Gets whether the robot has table sensing IR or not (see params in docs) + bool hasTableSensingIR(void) const { return myParams->haveTableSensingIR(); } + /// Returns true if the left table sensing IR is triggered + AREXPORT bool isLeftTableSensingIRTriggered(void) const; + /// Returns true if the right table sensing IR is triggered + AREXPORT bool isRightTableSensingIRTriggered(void) const; + /// Returns true if the left break beam IR is triggered + AREXPORT bool isLeftBreakBeamTriggered(void) const; + /// Returns true if the right break beam IR is triggered + AREXPORT bool isRightBreakBeamTriggered(void) const; + /// Returns the time received of the last IO packet + ArTime getIOPacketTime(void) const { return myLastIOPacketReceivedTime; } + + /// Gets whether the robot has front bumpers (see ARCOS parameters in the robot manual) + bool hasFrontBumpers(void) const { return myParams->haveFrontBumpers(); } + /// Get the number of the front bumper switches + unsigned int getNumFrontBumpers(void) const + { return myParams->numFrontBumpers(); } + /// Gets whether the robot has rear bumpers (see ARCOS parameters in the robot manual) + bool hasRearBumpers(void) const { return myParams->haveRearBumpers(); } + /// Gets the number of rear bumper switches + unsigned int getNumRearBumpers(void) const + { return myParams->numRearBumpers(); } + + /** @brief Get the position of the robot according to the last robot SIP, + * possibly with gyro correction if installed and enabled, but without any + * transformations applied. + * @sa getPose() + * @sa getRawEncoderPose() + */ + ArPose getEncoderPose(void) const { return myEncoderPose; } + /// Gets the encoder X position of the robot + /** @sa getEncoderPose() */ + double getEncoderX(void) const { return myEncoderPose.getX(); } + /// Gets the encoder Y position of the robot + /** @sa getEncoderPose() */ + double getEncoderY(void) const { return myEncoderPose.getY(); } + /// Gets the encoder angular position ("theta") of the robot + /** @sa getEncoderPose() */ + double getEncoderTh(void) const { return myEncoderPose.getTh(); } + + /// Gets if the robot is trying to move or not + /** + "Trying" to move means that some action or other command has + requested motion, but another action or factor has cancelled + that request. + + This is so that if the robot is trying to move, but is prevented + (mainly by an action) there'll still be some indication that the + robot is trying to move (e.g. we can prevent the sonar from automatically being + turned off). Note that this flag + doesn't have anything to do with if the robot is really moving or + not, to check that, check the current velocities. + @sa forceTryingToMove() to force this state on + **/ + bool isTryingToMove(void) { return myTryingToMove; } + + /// Manually sets the flag that says the robot is trying to move for one cycle + /** + This is so that things that might move the robot at any time + can can make the robot look + like it is otherwise in the TryingToMove state, even if no motion + is currently being requested. For example, ArNetworking's teleoperation + mode forces TryingToMove at all times while active, not just when + requesting motion. This method must be called in each task cycle, + it is reset at the end of the task cycle (in state reflection stage) + to its natural (non-forced) value. + + @sa isTryingToMove() + **/ + void forceTryingToMove(void) { myTryingToMove = true; } + + + /// Gets the number of motor packets received in the last second + AREXPORT int getMotorPacCount(void) const; + /// Gets the number of sonar returns received in the last second + AREXPORT int getSonarPacCount(void) const; + + /// Gets the range of the last sonar reading for the given sonar + AREXPORT int getSonarRange(int num) const; + /// Find out if the given sonar reading was newly refreshed by the last incoming SIP received. + AREXPORT bool isSonarNew(int num) const; + /// Find the number of sonar sensors (that the robot has yet returned values for) + int getNumSonar(void) const { return myNumSonar; } + /// Returns the sonar reading for the given sonar + AREXPORT ArSensorReading *getSonarReading(int num) const; + /// Returns the closest of the current sonar reading in the given range + AREXPORT int getClosestSonarRange(double startAngle, double endAngle) const; + /// Returns the number of the sonar that has the closest current reading in the given range + AREXPORT int getClosestSonarNumber(double startAngle, double endAngle) const; + + /// Gets the robots name in ARIAs list + AREXPORT const char *getName(void) const; + /// Sets the robots name in ARIAs list + AREXPORT void setName(const char *name); + + /// Change stored pose (i.e. the value returned by getPose()) + AREXPORT void moveTo(ArPose pose, bool doCumulative = true); + /// Change stored pose (i.e. the value returned by getPose()) + AREXPORT void moveTo(ArPose to, ArPose from, bool doCumulative = true); + /// Manually sets the current percentage that the robot is charged (argument is percentage, as a number between 0 and 100) + AREXPORT void setStateOfCharge(double stateOfCharge); + /// Sets the state of charge (percentage) that is considered to be low + void setStateOfChargeLow(double stateOfChargeLow) + { myStateOfChargeLow = stateOfChargeLow; } + /// Sets the state of charge that will cause a shutdown + void setStateOfChargeShutdown(double stateOfChargeShutdown) + { myStateOfChargeShutdown = stateOfChargeShutdown; } + /// Sets the charge state (for use with setting the state of charge) + AREXPORT void setChargeState(ArRobot::ChargeState chargeState); + /// Sets if we're on the charger (for use with setting the state of charge) + AREXPORT void setIsChargerPowerGood(bool onCharger); + + /// Sets things so that the battery info from the microcontroller + /// will be ignored + AREXPORT void setIgnoreMicroControllerBatteryInfo( + bool ignoreMicroControllerBatteryInfo); + /// Sets the battery info + AREXPORT void setBatteryInfo(double realBatteryVoltage, + double normalizedBatteryVoltage, + bool haveStateOfCharge, + double stateOfCharge); + + /// Gets the number of readings the battery voltage is the average of + size_t getBatteryVoltageAverageOfNum(void) + { return myBatteryAverager.getNumToAverage(); } + + /// Sets the number of readings the battery voltage is the average of (default 20) + void setBatteryVoltageAverageOfNum(size_t numToAverage) + { myBatteryAverager.setNumToAverage(numToAverage); } + + /// Gets the number of readings the battery voltage is the average of + size_t getRealBatteryVoltageAverageOfNum(void) + { return myRealBatteryAverager.getNumToAverage(); } + + /// Sets the number of readings the real battery voltage is the average of (default 20) + void setRealBatteryVoltageAverageOfNum(size_t numToAverage) + { myRealBatteryAverager.setNumToAverage(numToAverage); } + + /// Returns true if we have a temperature, false otherwise + bool hasTemperature(void) + { if (myTemperature != -128) return true; else return false; } + + /// Gets the temperature of the robot, -128 if not available, -127 to 127 otherwise + int getTemperature(void) const { return myTemperature; } + + /// Starts a continuous stream of encoder packets + AREXPORT void requestEncoderPackets(void); + + /// Starts a continuous stream of IO packets + AREXPORT void requestIOPackets(void); + + /// Stops a continuous stream of encoder packets + AREXPORT void stopEncoderPackets(void); + + /// Stops a continuous stream of IO packets + AREXPORT void stopIOPackets(void); + + /// Sees if we've explicitly requested encoder packets + AREXPORT bool haveRequestedEncoderPackets(void); + + /// Sees if we've explicitly requested IO packets + AREXPORT bool haveRequestedIOPackets(void); + + /// Gets packet data from the left encoder + AREXPORT long int getLeftEncoder(void); + + /// Gets packet data from the right encoder + AREXPORT long int getRightEncoder(void); + + /// Changes the transform + AREXPORT void setEncoderTransform(ArPose deadReconPos, + ArPose globalPos); + + /// Changes the transform directly + AREXPORT void setEncoderTransform(ArPose transformPos); + + /// Changes the transform directly + AREXPORT void setEncoderTransform(ArTransform transform); + + /// Sets the encoder pose, for internal use + AREXPORT void setEncoderPose(ArPose encoderPose) + { myEncoderPose = encoderPose; } + + /// Sets the raw encoder pose, for internal use + AREXPORT void setRawEncoderPose(ArPose rawEncoderPose) + { myRawEncoderPose = rawEncoderPose; } + + /// Adds a callback for when the encoder transform is changed + AREXPORT void addSetEncoderTransformCB(ArFunctor *functor, int position = 50) + { mySetEncoderTransformCBList.addCallback(functor, position); } + + /// Removes a callback for when the encoder transform is changed + AREXPORT void remSetEncoderTransformCB(ArFunctor *functor) + { mySetEncoderTransformCBList.remCallback(functor); } + + /// Adds a callback that'll be used to see the time on the computer side (for an MTX) + AREXPORT void setMTXTimeUSecCB(ArRetFunctor1 *functor) + { myMTXTimeUSecCB = functor; } + + /// Gets the encoder transform + AREXPORT ArTransform getEncoderTransform(void) const; + + /// This gets the transform from local coords to global coords + AREXPORT ArTransform getToGlobalTransform(void) const; + + /// This gets the transform for going from global coords to local coords + AREXPORT ArTransform getToLocalTransform(void) const; + + /// This applies a transform to all the robot range devices and to the sonar + AREXPORT void applyTransform(ArTransform trans, bool doCumulative = true); + + /// Sets the dead recon position of the robot + AREXPORT void setDeadReconPose(ArPose pose); + + /// This gets the distance the robot has travelled since the last time resetTripOdometer() was called (mm) + /// This is a virtual odometer that measures the total linear distance the + /// robot has travelled since first connected, or resetTripOdometer() was + /// called, approximated by adding linear + /// distance between current pose and previous pose in each ArRobot cycle. + /// @note This value is not related to the + /// robot's actual odometry sensor or wheel encoders. For position based on that + /// plus possible additional correction, see getPose(). For raw encoder count + /// data, see requestEncoderPackets() instead. + AREXPORT double getTripOdometerDistance(void) + { return myTripOdometerDistance; } + + /// This gets the number of degrees the robot has turned since the last time resetTripOdometer() was called (deg) + /// This is a virtual odometer (by analogy with a car odometer) that measures the total linear distance the + /// robot has travelled since first connected, or resetTripOdometer() was last + /// called, approximated by adding linear + /// distance between current pose and previous pose in each ArRobot cycle. + /// @note This value is not related to the + /// robot's actual odometry sensor or wheel encoders. For position based on that + /// plus possible additional correction, see getPose(). For raw encoder count + /// data, see requestEncoderPackets() instead. + /// @see getTripOdometerDistance() + AREXPORT double getTripOdometerDegrees(void) + { return myTripOdometerDegrees; } + + /// This gets the time since the "Trip Odometer" was reset (sec) + /// @see getTripOdometerDistance() + AREXPORT double getTripOdometerTime(void) + { return myTripOdometerStart.secSince(); } + + /// Resets the "Trip Odometer" + /// @see getTripOdometerDistance() + AREXPORT void resetTripOdometer(void); + + /// This gets the total cumulative distance the robot has travelled (mm) + /// This is a virtual odometer (by analogy with a car odometer) that measures the total linear distance the + /// robot has travelled since ARIA connected, approximated by adding linear + /// distance between current pose and previous pose in each ArRobot cycle. + /// @note This value is not related to the + /// robot's actual odometry sensor or wheel encoders. For position based on that + /// plus possible additional correction, see getPose(). For raw encoder count + /// data, see requestEncoderPackets() instead. + AREXPORT double getOdometerDistance(void) + { return myOdometerDistance; } + + /// This gets the total cumulative number of degrees the robot has turned (deg) + /// This is a virtual odometer (by analogy with a car odometer) that measures the total linear distance the + /// robot has travelled since ARIA connected, approximated by adding linear + /// distance between current pose and previous pose in each ArRobot cycle. + /// @note This value is not related to the + /// robot's actual odometry sensor or wheel encoders. For position based on that + /// plus possible additional correction, see getPose(). For raw encoder count + /// data, see requestEncoderPackets() instead. + AREXPORT double getOdometerDegrees(void) + { return myOdometerDegrees; } + + /// This gets the time since the robot started (sec) + AREXPORT double getOdometerTime(void) + { return myOdometerStart.secSince(); } + + + /// Adds a rangeDevice to the robot's list of them, and set the ArRangeDevice + /// object's robot pointer to this ArRobot object. + AREXPORT void addRangeDevice(ArRangeDevice *device); + /// Remove a range device from the robot's list, by name + AREXPORT void remRangeDevice(const char *name); + /// Remove a range device from the robot's list, by instance + AREXPORT void remRangeDevice(ArRangeDevice *device); + + /// Finds a rangeDevice in the robot's list + AREXPORT const ArRangeDevice *findRangeDevice(const char *name, + bool ignoreCase = false) const; + + /// Finds a rangeDevice in the robot's list + AREXPORT ArRangeDevice *findRangeDevice(const char *name, + bool ignoreCase = false); + + /// Gets the range device list + AREXPORT std::list *getRangeDeviceList(void); + + /// Finds whether a particular range device is attached to this robot or not + AREXPORT bool hasRangeDevice(ArRangeDevice *device) const; + + /// Goes through all the range devices and checks them + AREXPORT double checkRangeDevicesCurrentPolar( + double startAngle, double endAngle, double *angle = NULL, + const ArRangeDevice **rangeDevice = NULL, + bool useLocationDependentDevices = true) const; + + /// Goes through all the range devices and checks them + AREXPORT double checkRangeDevicesCumulativePolar( + double startAngle, double endAngle, double *angle = NULL, + const ArRangeDevice **rangeDevice = NULL, + bool useLocationDependentDevices = true) const; + + + // Goes through all the range devices and checks them + AREXPORT double checkRangeDevicesCurrentBox( + double x1, double y1, double x2, double y2, + ArPose *readingPos = NULL, + const ArRangeDevice **rangeDevice = NULL, + bool useLocationDependentDevices = true) const; + + // Goes through all the range devices and checks them + AREXPORT double checkRangeDevicesCumulativeBox( + double x1, double y1, double x2, double y2, + ArPose *readingPos = NULL, + const ArRangeDevice **rangeDevice = NULL, + bool useLocationDependentDevices = true) const; + + /// Adds a laser to the robot's map of them + AREXPORT bool addLaser(ArLaser *laser, int laserNumber, + bool addAsRangeDevice = true); + /// Remove a range device from the robot's list, by instance + AREXPORT bool remLaser(ArLaser *laser, bool removeAsRangeDevice = true); + /// Remove a range device from the robot's list, by number + AREXPORT bool remLaser(int laserNumber, bool removeAsRangeDevice = true); + + /// Finds a laser in the robot's list (@a laserNumber indices start at 1) + AREXPORT const ArLaser *findLaser(int laserNumber) const; + + /// Finds a laser in the robot's list (@a laserNumber indices start at 1) + AREXPORT ArLaser *findLaser(int laserNumber); + + /// Gets the range device list + AREXPORT const std::map *getLaserMap(void) const; + + /// Gets the range device list + AREXPORT std::map *getLaserMap(void); + + /// Finds whether a particular range device is attached to this robot or not + AREXPORT bool hasLaser(ArLaser *device) const; + + + /// Adds a battery to the robot's map of them + /// @internal + /// (ArBatteryConnector/ArRobotConnector will automatically add ArBatteryMTX + /// object(s) if connected.) + AREXPORT bool addBattery(ArBatteryMTX *battery, int batteryNumber); + /// Remove a battery from the robot's list, by instance + /// (MTX robots only) + /// Primarily for ARIA internal use only. + AREXPORT bool remBattery(ArBatteryMTX *battery); + /// Remove a battery from the robot's list, by number + /// (MTX robots only) + /// Primarily for ARIA internal use only. + AREXPORT bool remBattery(int batteryNumber); + + /// Finds a battery in the robot's list (@a batteryNumber indices start at 1) + /// (MTX robots only) + AREXPORT const ArBatteryMTX *findBattery(int batteryNumber) const; + + /// Finds a battery in the robot's list (@a batteryNumber indices start at 1) + /// (MTX robots only) + AREXPORT ArBatteryMTX *findBattery(int batteryNumber); + + /// Gets the battery list + AREXPORT const std::map *getBatteryMap(void) const; + + /// Gets the battery list + AREXPORT std::map *getBatteryMap(void); + + /// Finds whether a particular battery is attached to this robot or not + AREXPORT bool hasBattery(ArBatteryMTX *device) const; + + + /// Adds a lcd to the robot's map of them + /// @internal + /// (ArLCDConnector/ArRobotConnector will automatically add LCD interfaces if + /// connected.) + AREXPORT bool addLCD(ArLCDMTX *lcd, int lcdNumber); + /// Remove a lcd from the robot's list, by instance + /// @internal + /// (ArLCDConnector/ArRobotConnector will automatically add LCD interfaces if + /// connected.) + AREXPORT bool remLCD(ArLCDMTX *lcd); + /// Remove a lcd from the robot's list, by number + /// @internal + /// (ArLCDConnector/ArRobotConnector will automatically add LCD interfaces if + /// connected.) + AREXPORT bool remLCD(int lcdNumber); + + /// Finds a lcd in the robot's list (@a lcdNumber indices start at 1) + /// (MTX robots only) + AREXPORT const ArLCDMTX *findLCD(int lcdNumber = 1) const; + + /// Finds a lcd in the robot's list (@a lcdNumber indices start at 1) + /// (MTX robots only) + AREXPORT ArLCDMTX *findLCD(int lcdNumber = 1); + + /// Gets the lcd list + /// (MTX robots only) + AREXPORT const std::map *getLCDMap(void) const; + + /// Gets the lcd list + /// (MTX robots only) + AREXPORT std::map *getLCDMap(void); + + /// Finds whether a particular lcd is attached to this robot or not + /// (MTX robots only) + AREXPORT bool hasLCD(ArLCDMTX *device) const; + + + + /// Adds a sonar to the robot's map of them + /// @internal (ArSonarConnector/ArRobotConnector will automatically and MTX + /// sonar interfaces upon connection) + AREXPORT bool addSonar(ArSonarMTX *sonar, int sonarNumber); + /// Remove a sonar from the robot's list, by instance + /// @internal + AREXPORT bool remSonar(ArSonarMTX *sonar); + /// Remove a sonar from the robot's list, by number + /// @internal + AREXPORT bool remSonar(int sonarNumber); + + /// Finds a sonar in the robot's list (@a sonarNumber indices start at 1) + /// (MTX robots only) + AREXPORT const ArSonarMTX *findSonar(int sonarNumber) const; + + /// Finds a sonar in the robot's list (@a sonarNumber indices start at 1) + /// (MTX robots only) + AREXPORT ArSonarMTX *findSonar(int sonarNumber); + + /// Gets the sonar list + /// (MTX robots only) + AREXPORT const std::map *getSonarMap(void) const; + + /// Gets the sonar list + /// (MTX robots only) + AREXPORT std::map *getSonarMap(void); + + /// Finds whether a particular sonar is attached to this robot or not + /// (MTX robots only) + AREXPORT bool hasSonar(ArSonarMTX *device) const; + + /// Associates an ArPTZ object with this robot (see getPTZ()) + void setPTZ(ArPTZ *ptz) { myPtz = ptz; } + /// Get PTZ interface associated with this robot. + ArPTZ *getPTZ(void) { return myPtz; } + + /// Sets the number of milliseconds between state reflection refreshes + /// if the state has not changed + AREXPORT void setStateReflectionRefreshTime(int msec); + + /// Gets the number of milliseconds between state reflection refreshes + /// if the state has not changed + AREXPORT int getStateReflectionRefreshTime(void) const; + + /// Adds a packet handler to the list of packet handlers + AREXPORT void addPacketHandler( + ArRetFunctor1 *functor, + ArListPos::Pos position = ArListPos::LAST); + + /// Removes a packet handler from the list of packet handlers + AREXPORT void remPacketHandler( + ArRetFunctor1 *functor); + + /// Adds a connect callback + AREXPORT void addConnectCB(ArFunctor *functor, + ArListPos::Pos position = ArListPos::LAST); + /// Removes a connect callback + AREXPORT void remConnectCB(ArFunctor *functor); + + /// Adds a callback for when a connection to the robot is failed + AREXPORT void addFailedConnectCB(ArFunctor *functor, + ArListPos::Pos position = ArListPos::LAST); + /// Removes a callback for when a connection to the robot is failed + AREXPORT void remFailedConnectCB(ArFunctor *functor); + + /// Adds a callback for when disconnect is called while connected + AREXPORT void addDisconnectNormallyCB(ArFunctor *functor, + ArListPos::Pos position = ArListPos::LAST); + /// Removes a callback for when disconnect is called while connected + AREXPORT void remDisconnectNormallyCB(ArFunctor *functor); + + /// Adds a callback for when disconnection happens because of an error + AREXPORT void addDisconnectOnErrorCB(ArFunctor *functor, + ArListPos::Pos position = ArListPos::LAST); + /// Removes a callback for when disconnection happens because of an error + AREXPORT void remDisconnectOnErrorCB(ArFunctor *functor); + + /// Adds a callback for when the run loop exits for what ever reason + AREXPORT void addRunExitCB(ArFunctor *functor, + ArListPos::Pos position = ArListPos::LAST); + /// Removes a callback for when the run loop exits for what ever reason + AREXPORT void remRunExitCB(ArFunctor *functor); + + /// Suspend calling thread until the ArRobot is connected + AREXPORT WaitState waitForConnect(unsigned int msecs=0); + /// Suspend calling thread until the ArRobot is connected or fails to connect + AREXPORT WaitState waitForConnectOrConnFail(unsigned int msecs=0); + /// Suspend calling thread until the ArRobot run loop has exited + AREXPORT WaitState waitForRunExit(unsigned int msecs=0); + + /// Wake up all threads waiting on this robot + AREXPORT void wakeAllWaitingThreads(); + /// Wake up all threads waiting for connection + AREXPORT void wakeAllConnWaitingThreads(); + /// Wake up all threads waiting for connection or connection failure + AREXPORT void wakeAllConnOrFailWaitingThreads(); + /// Wake up all threads waiting for the run loop to exit + AREXPORT void wakeAllRunExitWaitingThreads(); + + /// Adds a user task to the list of synchronous taskes + AREXPORT bool addUserTask(const char *name, int position, + ArFunctor *functor, + ArTaskState::State *state = NULL); + /// Removes a user task from the list of synchronous taskes by name + AREXPORT void remUserTask(const char *name); + /// Removes a user task from the list of synchronous taskes by functor + AREXPORT void remUserTask(ArFunctor *functor); + + /// Finds a user task by name + AREXPORT ArSyncTask *findUserTask(const char *name); + /// Finds a user task by functor + AREXPORT ArSyncTask *findUserTask(ArFunctor *functor); + + /// Logs the list of user tasks, strictly for your viewing pleasure + AREXPORT void logUserTasks(void) const; + /// Logs the list of all tasks, strictly for your viewing pleasure + AREXPORT void logAllTasks(void) const; + + /// Adds a task under the sensor interp part of the syncronous tasks + AREXPORT bool addSensorInterpTask(const char *name, int position, + ArFunctor *functor, + ArTaskState::State *state = NULL); + /// Removes a sensor interp tasks by name + AREXPORT void remSensorInterpTask(const char *name); + /// Removes a sensor interp tasks by functor + AREXPORT void remSensorInterpTask(ArFunctor *functor); + + /// Finds a task by name + AREXPORT ArSyncTask *findTask(const char *name); + /// Finds a task by functor + AREXPORT ArSyncTask *findTask(ArFunctor *functor); + + /// Adds an action to the list with the given priority + AREXPORT bool addAction(ArAction *action, int priority); + /// Removes an action from the list, by pointer + AREXPORT bool remAction(ArAction *action); + /// Removes an action from the list, by name + AREXPORT bool remAction(const char *actionName); + /// Returns the first (highest priority) action with the given name (or NULL) + AREXPORT ArAction *findAction(const char *actionName); + /// Returns the map of actions... don't do this unless you really + /// know what you're doing + AREXPORT ArResolver::ActionMap *getActionMap(void); + /// Deactivates all the actions + AREXPORT void deactivateActions(void); + + /// Logs out the actions and their priorities + AREXPORT void logActions(bool logDeactivated = false) const; + + /// Gets the resolver the robot is using + AREXPORT ArResolver *getResolver(void); + + /// Sets the resolver the robot is using + AREXPORT void setResolver(ArResolver *resolver); + + /// Sets the encoderCorrectionCallback + AREXPORT void setEncoderCorrectionCallback( + ArRetFunctor1 *functor); + /// Gets the encoderCorrectionCallback + AREXPORT ArRetFunctor1 * + getEncoderCorrectionCallback(void) const; + + /// Gets the time the connection to the robot was made + AREXPORT ArTime getConnectionOpenedTime(void) const + { return myConnectionOpenedTime; } + + // set up some of the internals of how the ArRobot class works + /// Sets the number of ms between cycles + AREXPORT void setCycleTime(unsigned int ms); + /// Gets the number of ms between cycles + AREXPORT unsigned int getCycleTime(void) const; + /// Sets the number of ms between cycles to warn over + AREXPORT void setCycleWarningTime(unsigned int ms); + /// Gets the number of ms between cycles to warn over + AREXPORT unsigned int getCycleWarningTime(void) const; + /// Gets the number of ms between cycles to warn over + AREXPORT unsigned int getCycleWarningTime(void); + /// Sets the multiplier for how many cycles ArRobot waits when connecting + AREXPORT void setConnectionCycleMultiplier(unsigned int multiplier); + /// Gets the multiplier for how many cycles ArRobot waits when connecting + AREXPORT unsigned int getConnectionCycleMultiplier(void) const; + + /// Sets whether to chain the robot cycle to when we get in SIP packets + void setCycleChained(bool cycleChained) { myCycleChained = cycleChained; } + /// Gets whether we chain the robot cycle to when we get in SIP packets + bool isCycleChained(void) const { return myCycleChained; } + /// Sets the time without a response until connection assumed lost + AREXPORT void setConnectionTimeoutTime(int mSecs); + /// Gets the time without a response until connection assumed lost + AREXPORT int getConnectionTimeoutTime(void) const; + /// Gets the time the last packet was received + AREXPORT ArTime getLastPacketTime(void) const; + /// Gets the time the last odometry was received + AREXPORT ArTime getLastOdometryTime(void) const; + + /// Sets the number of packets back in time the ArInterpolation goes + AREXPORT void setPoseInterpNumReadings(size_t numReadings) + { myInterpolation.setNumberOfReadings(numReadings); } + + /// Sets the number of packets back in time the position interpol goes + AREXPORT size_t getPoseInterpNumReadings(void) const + { return myInterpolation.getNumberOfReadings(); } + + + /// Gets the position the robot was at at the given timestamp + /** @see ArInterpolation::getPose + */ + AREXPORT int getPoseInterpPosition(ArTime timeStamp, ArPose *position, + ArPoseWithTime *mostRecent = NULL) + { return myInterpolation.getPose(timeStamp, position, mostRecent); } + + /// Gets the pose interpolation object, this should only really used internally + AREXPORT ArInterpolation *getPoseInterpolation(void) + { return &myInterpolation; } + + /// Gets the callback that will call getPoseInterpPosition + AREXPORT ArRetFunctor3 * + getPoseInterpPositionCallback(void) + { + return &myPoseInterpPositionCB; + } + + /// Sets the number of packets back in time the ArInterpolation goes for encoder readings + AREXPORT void setEncoderPoseInterpNumReadings(size_t numReadings) + { myEncoderInterpolation.setNumberOfReadings(numReadings); } + + /// Sets the number of packets back in time the encoder position interpolation goes + AREXPORT size_t getEncoderPoseInterpNumReadings(void) const + { return myEncoderInterpolation.getNumberOfReadings(); } + + /// Gets the encoder position the robot was at at the given timestamp + /** @see ArInterpolation::getPose + */ + AREXPORT int getEncoderPoseInterpPosition(ArTime timeStamp, ArPose *position, + ArPoseWithTime *mostRecent = NULL) + { return myEncoderInterpolation.getPose(timeStamp, position, mostRecent); } + + AREXPORT ArInterpolation *getEncoderPoseInterpolation(void) + { return &myEncoderInterpolation; } + + /// Gets the callback that will call getPoseInterpPosition + AREXPORT ArRetFunctor3 * + getEncoderPoseInterpPositionCallback(void) + { + return &myEncoderPoseInterpPositionCB; + } + + /// Applies the encoder motion from the passed in ArPoseWithTime to the passed in ArTime + AREXPORT int applyEncoderOffset(ArPoseWithTime from, ArTime to, + ArPose *result); + + /// Gets the Counter for the time through the loop + unsigned int getCounter(void) const { return myCounter; } + + /// Gets the parameters the robot is using + AREXPORT const ArRobotParams *getRobotParams(void) const; + + /// Sets if a config packet is requried or not... + /** By default it is not required, since some ancient robots have no + config packets... some of the modern software may die hideously + if there is no config packet, so you should set this to true if + you're using modern robots (basically anything other than a + pioneer 1) + **/ + void setRequireConfigPacket(bool requireConfigPacket) + { myRequireConfigPacket = requireConfigPacket; } + + /// Gets the original robot config packet information + AREXPORT const ArRobotConfigPacketReader *getOrigRobotConfig(void) const; + + /// Gets the battery packet reader + AREXPORT ArRobotBatteryPacketReader *getBatteryPacketReader(void) + { return myBatteryPacketReader; } + + /// Sets the maximum translational velocity + AREXPORT void setTransVelMax(double vel); + /// Sets the maximum translational velocity + AREXPORT void setTransNegVelMax(double negVel); + /// Sets the translational acceleration + AREXPORT void setTransAccel(double acc); + /// Sets the translational acceleration + AREXPORT void setTransDecel(double decel); + /// Sets the maximum rotational velocity + AREXPORT void setRotVelMax(double vel); + /// Sets the rotational acceleration + AREXPORT void setRotAccel(double acc); + /// Sets the rotational acceleration + AREXPORT void setRotDecel(double decel); + /// Sets the maximum lateral velocity + AREXPORT void setLatVelMax(double vel); + /// Sets the lateral acceleration + AREXPORT void setLatAccel(double acc); + /// Sets the lateral acceleration + AREXPORT void setLatDecel(double decel); + + /// If the robot has settable maximum velocities + bool hasSettableVelMaxes(void) const + { return myParams->hasSettableVelMaxes(); } + /// Gets the maximum translational velocity + AREXPORT double getTransVelMax(void) const; + /// Gets the maximum translational velocity + AREXPORT double getTransNegVelMax(void) const; + /// Gets the maximum rotational velocity + AREXPORT double getRotVelMax(void) const; + /// If the robot has settable accels and decels + bool hasSettableAccsDecs(void) + const { return myParams->hasSettableAccsDecs(); } + /// Gets the translational acceleration + AREXPORT double getTransAccel(void) const; + /// Gets the translational acceleration + AREXPORT double getTransDecel(void) const; + /// Gets the rotational acceleration + AREXPORT double getRotAccel(void) const; + /// Gets the rotational acceleration + AREXPORT double getRotDecel(void) const; + + /// Gets the maximum lateral velocity + AREXPORT double getLatVelMax(void) const; + /// Gets the lateral acceleration + AREXPORT double getLatAccel(void) const; + /// Gets the lateral acceleration + AREXPORT double getLatDecel(void) const; + + /// Loads a parameter file (replacing all other params) + AREXPORT bool loadParamFile(const char *file); + /// Sets the robot to use a passed in set of params (passes ownership) + AREXPORT void setRobotParams(ArRobotParams *params); + + /// Attachs a key handler + AREXPORT void attachKeyHandler(ArKeyHandler *keyHandler, + bool exitOnEscape = true, + bool useExitNotShutdown = true); + /// Gets the key handler attached to this robot + AREXPORT ArKeyHandler *getKeyHandler(void) const; + + /// Lock the robot instance + int lock() {return(myMutex.lock());} + /// Try to lock the robot instance without blocking + int tryLock() {return(myMutex.tryLock());} + /// Unlock the robot instance + int unlock() {return(myMutex.unlock());} + /// Turn on verbose locking of robot mutex + void setMutexLogging(bool v) { myMutex.setLog(v); } + /// Set robot lock warning time (see ArMutex::setLockWarningTime()) + void setMutexLockWarningTime(double sec) { myMutex.setLockWarningTime(sec); } + /// Set robot lock-unlock warning time (see ArMutex::setUnlockWarningTime()) + void setMutexUnlockWarningTime(double sec) { myMutex.setUnlockWarningTime(sec); } + + /// This tells us if we're in the preconnection state + AREXPORT bool isStabilizing(void) { return myIsStabilizing; } + + /// How long we should stabilize for in ms (0 disables stabilizing) + AREXPORT void setStabilizingTime(int mSecs); + + /// How long we stabilize for in ms (0 means no stabilizng) + AREXPORT int getStabilizingTime(void) const; + + + /// Adds a callback called when the robot starts stabilizing before declaring connection + AREXPORT void addStabilizingCB(ArFunctor *functor, + ArListPos::Pos position = ArListPos::LAST); + /// Removes stabilizing callback + AREXPORT void remStabilizingCB(ArFunctor *functor); + + /// This gets the root of the syncronous task tree, only serious + /// developers should use it + AREXPORT ArSyncTask *getSyncTaskRoot(void); + + /// This function loops once... only serious developers should use it + AREXPORT void loopOnce(void); + + /// Sets the delay in the odometry readings + /** + Note that this doesn't cause a delay, its informational so that + the delay can be adjusted for and causes nothing to happen in + this class. + **/ + AREXPORT void setOdometryDelay(int msec) { myOdometryDelay = msec; } + + /// Gets the delay in odometry readings + /** + This gets the odometry delay, not that this is just information + about what the delay is it doesn't cause anything to happen in + this class. + **/ + AREXPORT int getOdometryDelay(void) { return myOdometryDelay; } + + /// Gets if we're logging all the movement commands sent down + AREXPORT bool getLogMovementSent(void) { return myLogMovementSent; } + /// Sets if we're logging all the movement commands sent down + AREXPORT void setLogMovementSent(bool logMovementSent) + { myLogMovementSent = logMovementSent; } + + /// Gets if we're logging all the positions received from the robot + AREXPORT bool getLogMovementReceived(void) { return myLogMovementReceived; } + /// Sets if we're logging all the positions received from the robot + AREXPORT void setLogMovementReceived(bool logMovementReceived) + { myLogMovementReceived = logMovementReceived; } + + /// Gets if we're logging all the velocities (and heading) received + AREXPORT bool getLogVelocitiesReceived(void) + { return myLogVelocitiesReceived; } + /// Sets if we're logging all the velocities (and heading) received + AREXPORT void setLogVelocitiesReceived(bool logVelocitiesReceived) + { myLogVelocitiesReceived = logVelocitiesReceived; } + + /// Gets if we're logging all the packets received (just times and types) + AREXPORT bool getPacketsReceivedTracking(void) + { return myPacketsReceivedTracking; } + /// Sets if we're logging all the packets received (just times and types) + AREXPORT void setPacketsReceivedTracking(bool packetsReceivedTracking); + + /// Gets if we're logging the contents of the standard SIP (motors packet) + bool getLogSIPContents() { return myLogSIPContents; } + /// Set if we're logging the contents of the standard SIP (motor packets) + void setLogSIPContents(bool logSIP) { myLogSIPContents = logSIP; } + + /// Gets if we're logging all the packets sent and their payload + AREXPORT bool getPacketsSentTracking(void) + { return myPacketsSentTracking; } + /// Sets if we're logging all the packets sent and their payloads + AREXPORT void setPacketsSentTracking(bool packetsSentTracking) + { + if (packetsSentTracking) + ArLog::log(ArLog::Normal, "ArRobot: tracking packets sent"); + else + ArLog::log(ArLog::Normal, "ArRobot: not tracking packets sent"); + myPacketsSentTracking = packetsSentTracking; + } + + /// Gets if we're logging all the actions as they happen + AREXPORT bool getLogActions(void) { return myLogActions; } + /// Sets if we're logging all the actions as they happen + AREXPORT void setLogActions(bool logActions) + { myLogActions = logActions; } + + /// Sets the flag that controls if the robot will switch baud rates + AREXPORT void setDoNotSwitchBaud(bool doNotSwitchBaud) + { myDoNotSwitchBaud = true; } + + /// Gets the flag that controls if the robot won't switch baud rates + AREXPORT bool getDoNotSwitchBaud(void) { return myDoNotSwitchBaud; } + + /// This is only for use by syncLoop + /// @internal + AREXPORT void incCounter(void) { myCounter++; } + + /// Packet Handler, internal (calls old or new as appropriate) + /// @internal + AREXPORT void packetHandler(void); + /// Action Handler, internal + /// @internal + AREXPORT void actionHandler(void); + /// State Reflector, internal + /// @internal + AREXPORT void stateReflector(void); + /// Robot locker, internal + /// @internal + AREXPORT void robotLocker(void); + /// Robot unlocker, internal + /// @internal + AREXPORT void robotUnlocker(void); + + /// Packet handler, internal, for use in the syncloop when there's no threading + /// @internal + AREXPORT void packetHandlerNonThreaded(void); + /// Packet handler, internal, for use in the syncloop to handle the + /// actual packets + /// @internal + AREXPORT void packetHandlerThreadedProcessor(void); + /// Packet handler, internal, for using from a thread to actually + /// read all the packets + /// @internal + AREXPORT void packetHandlerThreadedReader(void); + + /// For the key handler, escape calls this to exit, internal + AREXPORT void keyHandlerExit(void); + + /// Processes a motor packet, internal + /// @internal + AREXPORT bool processMotorPacket(ArRobotPacket *packet); + /// Processes a new sonar reading, internal + /// @internal + AREXPORT void processNewSonar(char number, int range, ArTime timeReceived); + /// Processes a new encoder packet, internal + /// @internal + AREXPORT bool processEncoderPacket(ArRobotPacket *packet); + /// Processes a new IO packet, internal + /// @internal + AREXPORT bool processIOPacket(ArRobotPacket *packet); + + /// Internal function, shouldn't be used + /// @internal + AREXPORT void init(void); + + /// Internal function, shouldn't be used, sets up the default sync list + /// @internal + AREXPORT void setUpSyncList(void); + /// Internal function, shouldn't be used, sets up the default packet handlers + /// @internal + AREXPORT void setUpPacketHandlers(void); + + ArRetFunctor1C myMotorPacketCB; + ArRetFunctor1C myEncoderPacketCB; + ArRetFunctor1C myIOPacketCB; + ArFunctorC myPacketHandlerCB; + ArFunctorC myActionHandlerCB; + ArFunctorC myStateReflectorCB; + ArFunctorC myRobotLockerCB; + ArFunctorC myRobotUnlockerCB; + ArFunctorC myKeyHandlerExitCB; + ArFunctorC *myKeyHandlerCB; + + // These four are internal... only people monkeying deeply should mess + // with them, so they aren't documented... these process the cblists + // and such + // Internal function, shouldn't be used, does a single run of connecting + AREXPORT int asyncConnectHandler(bool tryHarderToConnect); + + /// Internal function, shouldn't be used, drops the conn because of error + /// @internal + AREXPORT void dropConnection(const char *reason = "Lost connection to the robot because of undefined error."); + /// Internal function that gets the reason the connection dropped + /// @internal + AREXPORT const char *getDropConnectionReason(void) { return myDropConnectionReason.c_str(); } + /// Internal function, shouldn't be used, denotes the conn failed + /// @internal + AREXPORT void failedConnect(void); + /// Internal function, shouldn't be used, does the initial conn stuff + /// @internal + AREXPORT bool madeConnection(bool resetConnectionTime = true); + /// Internal function, shouldn't be used, calls the preconnected stuff + /// @internal + AREXPORT void startStabilization(void); + /// Internal function, shouldn't be used, does the after conn stuff + /// @internal + AREXPORT void finishedConnection(void); + /// Internal function, shouldn't be used, cancels the connection quietly + /// @internal + AREXPORT void cancelConnection(void); + + /// Internal function, takes a packet and passes it to the packet handlers, + /// returns true if handled, false otherwise + /// @internal + AREXPORT bool handlePacket(ArRobotPacket *packet); + + AREXPORT std::list * getRunExitListCopy(); + // Internal function, processes a parameter file + AREXPORT void processParamFile(void); + + /** @brief Get the position of the robot according to the last robot SIP only, + * with no correction by the gyro, other devices or software proceses. + * + * @note For the most accurate pose, use getPose() or getEncoderPose(); + * only use this method if you must have raw encoder pose with no correction. + * @sa getPose() + * @sa getEncoderPose() + */ + AREXPORT ArPose getRawEncoderPose(void) const { return myRawEncoderPose; } + + /// Internal function for sync loop and sync task to see if we should warn this cycle or not + AREXPORT bool getNoTimeWarningThisCycle(void) + { return myNoTimeWarningThisCycle; } + /// Internal function for sync loop and sync task to say if we should warn this cycle or not + AREXPORT void setNoTimeWarningThisCycle(bool noTimeWarningThisCycle) + { myNoTimeWarningThisCycle = noTimeWarningThisCycle; } + // callbacks for warning time and if we should warn now to pass to sync tasks + ArRetFunctorC myGetCycleWarningTimeCB; + ArRetFunctorC myGetNoTimeWarningThisCycleCB; + /// internal function called when Aria::exit is called + /// @internal + AREXPORT void ariaExitCallback(void); + // internal call that will let the robot connect even if it can't find params + void setConnectWithNoParams(bool connectWithNoParams) + { myConnectWithNoParams = connectWithNoParams; } + // Internal call that will get the thread the robot is running in + ArThread::ThreadType getOSThread(void) { return mySyncLoop.getOSThread(); } + // Internal call that will get the async connect state + int getAsyncConnectState(void) { return myAsyncConnectState; } + /// Very Internal call that gets the packet sender, shouldn't be used + /// @internal + ArRobotPacketSender *getPacketSender(void) + { return &mySender; } + /// Very Internal call that gets the packet sender, shouldn't be used + /// @internal + ArRobotPacketReceiver *getPacketReceiver(void) + { return &myReceiver; } + + // Gets a pointer to the robot parameters in an internal way so they can be modified (only for internal use) + AREXPORT ArRobotParams *getRobotParamsInternal(void); + + // Sets if we've received the first encoder pose for very internal usage + AREXPORT void internalSetFakeFirstEncoderPose(bool fakeFirstEncoderPose) + { myFakeFirstEncoderPose = fakeFirstEncoderPose; } + // Sets a flag to ignore the next packet handled, for very internal usage + AREXPORT void internalIgnoreNextPacket(void); +protected: + enum RotDesired { + ROT_NONE, + ROT_IGNORE, + ROT_HEADING, + ROT_VEL + }; + enum TransDesired { + TRANS_NONE, + TRANS_IGNORE, + TRANS_VEL, + TRANS_VEL2, + TRANS_DIST, + TRANS_DIST_NEW + }; + enum LatDesired { + LAT_NONE, + LAT_IGNORE, + LAT_VEL + }; + void reset(void); + + + // the config the robot had at connection + ArRobotConfigPacketReader *myOrigRobotConfig; + // the reader for the battery packet + ArRobotBatteryPacketReader *myBatteryPacketReader; + // the values we'll maintain for the different motion parameters + double myRotVelMax; + double myRotAccel; + double myRotDecel; + double myTransVelMax; + double myTransNegVelMax; + double myTransAccel; + double myTransDecel; + double myLatVelMax; + double myLatAccel; + double myLatDecel; + + ArPTZ *myPtz; + bool myNoTimeWarningThisCycle; + + long int myLeftEncoder; + long int myRightEncoder; + bool myFirstEncoderPose; + bool myFakeFirstEncoderPose; + ArPoseWithTime myRawEncoderPose; + + ArTransform myEncoderTransform; + ArCallbackList mySetEncoderTransformCBList; + + ArRetFunctor1 *myMTXTimeUSecCB; + + bool myIgnoreNextPacket; + + bool myLogMovementSent; + bool myLogMovementReceived; + bool myPacketsReceivedTracking; + bool myLogActions; + bool myLogVelocitiesReceived; + bool myLogSIPContents; + + double myLastVel; + double myLastRotVel; + double myLastHeading; + double myLastCalculatedRotVel; + double myLastLatVel; + + bool myTryingToMove; + + long myPacketsReceivedTrackingCount; + ArTime myPacketsReceivedTrackingStarted; + bool myPacketsSentTracking; + ArMutex myMutex; + ArSyncTask *mySyncTaskRoot; + std::list *> myPacketHandlerList; + + ArSyncLoop mySyncLoop; + ArRobotPacketReaderThread myPacketReader; + + // the data items for reading packets in one thread and processing them in another + ArMutex myPacketMutex; + std::list myPacketList; + ArCondition myPacketReceivedCondition; + bool myRunningNonThreaded; + + + std::list myStabilizingCBList; + std::list myConnectCBList; + std::list myFailedConnectCBList; + std::list myDisconnectNormallyCBList; + std::list myDisconnectOnErrorCBList; + std::list myRunExitCBList; + + ArRetFunctor1 *myEncoderCorrectionCB; + std::list myRangeDeviceList; + std::map myLaserMap; + + std::map myBatteryMap; + + std::map myLCDMap; + + std::map mySonarMap; + + ArCondition myConnectCond; + ArCondition myConnOrFailCond; + ArCondition myRunExitCond; + + ArResolver::ActionMap myActions; + bool myOwnTheResolver; + ArResolver *myResolver; + + std::map mySonars; + int myNumSonar; + + unsigned int myCounter; + bool myIsConnected; + bool myIsStabilizing; + bool myRequireConfigPacket; + + bool mySonarEnabled; + bool myAutonomousDrivingSonarEnabled; + + bool myBlockingConnectRun; + bool myAsyncConnectFlag; + int myAsyncConnectState; + int myAsyncConnectNoPacketCount; + int myAsyncConnectTimesTried; + ArTime myAsyncStartedConnection; + int myAsyncConnectStartBaud; + ArTime myAsyncConnectStartedChangeBaud; + bool myAsyncConnectSentChangeBaud; + ArTime myStartedStabilizing; + + ArTime myConnectionOpenedTime; + + int myStabilizingTime; + + bool mySentPulse; + + double myTransVal; + double myTransVal2; + int myLastTransVal; + int myLastTransVal2; + TransDesired myTransType; + TransDesired myLastTransType; + ArTime myTransSetTime; + ArTime myLastTransSent; + int myLastActionTransVal; + bool myActionTransSet; + ArPose myTransDistStart; + double myMoveDoneDist; + + double myRotVal; + int myLastRotVal; + RotDesired myRotType; + RotDesired myLastRotType; + ArTime myRotSetTime; + ArTime myLastRotSent; + int myLastActionRotVal; + bool myLastActionRotHeading; + bool myLastActionRotStopped; + bool myActionRotSet; + double myHeadingDoneDiff; + + double myLatVal; + int myLastLatVal; + LatDesired myLatType; + LatDesired myLastLatType; + ArTime myLatSetTime; + ArTime myLastLatSent; + int myLastActionLatVal; + bool myActionLatSet; + + double myLastSentTransVelMax; + double myLastSentTransAccel; + double myLastSentTransDecel; + double myLastSentRotVelMax; + double myLastSentRotVelPosMax; + double myLastSentRotVelNegMax; + double myLastSentRotAccel; + double myLastSentRotDecel; + double myLastSentLatVelMax; + double myLastSentLatAccel; + double myLastSentLatDecel; + + ArTime myLastPulseSent; + + int myDirectPrecedenceTime; + + int myStateReflectionRefreshTime; + + ArActionDesired myActionDesired; + + std::string myName; + std::string myRobotName; + std::string myRobotType; + std::string myRobotSubType; + + double myAbsoluteMaxTransVel; + double myAbsoluteMaxTransNegVel; + double myAbsoluteMaxTransAccel; + double myAbsoluteMaxTransDecel; + double myAbsoluteMaxRotVel; + double myAbsoluteMaxRotAccel; + double myAbsoluteMaxRotDecel; + double myAbsoluteMaxLatVel; + double myAbsoluteMaxLatAccel; + double myAbsoluteMaxLatDecel; + + ArDeviceConnection *myConn; + + ArRobotPacketSender mySender; + ArRobotPacketReceiver myReceiver; + + std::string myDropConnectionReason; + + ArRobotParams *myParams; + double myRobotLengthFront; + double myRobotLengthRear; + + ArInterpolation myInterpolation; + ArInterpolation myEncoderInterpolation; + + ArKeyHandler *myKeyHandler; + bool myKeyHandlerUseExitNotShutdown; + + bool myConnectWithNoParams; + bool myWarnedAboutExtraSonar; + + // variables for tracking the data stream + time_t myTimeLastMotorPacket; + int myMotorPacCurrentCount; + int myMotorPacCount; + time_t myTimeLastSonarPacket; + int mySonarPacCurrentCount; + int mySonarPacCount; + unsigned int myCycleTime; + unsigned int myCycleWarningTime; + unsigned int myConnectionCycleMultiplier; + bool myCycleChained; + ArTime myLastPacketReceivedTime; + ArTime myLastOdometryReceivedTime; + int myTimeoutTime; + + bool myRequestedIOPackets; + bool myRequestedEncoderPackets; + + // all the state reflecing variables + ArPoseWithTime myEncoderPose; + ArTime myEncoderPoseTaken; + ArPose myGlobalPose; + // um, this myEncoderGlobalTrans doesn't do anything + ArTransform myEncoderGlobalTrans; + double myLeftVel; + double myRightVel; + bool myIgnoreMicroControllerBatteryInfo; + double myBatteryVoltage; + ArRunningAverage myBatteryAverager; + double myRealBatteryVoltage; + ArRunningAverage myRealBatteryAverager; + bool myHaveStateOfCharge; + double myStateOfCharge; + ArTime myStateOfChargeSetTime; + double myStateOfChargeLow; + double myStateOfChargeShutdown; + + int myStallValue; + double myControl; + bool myKeepControlRaw; + int myFlags; + int myFaultFlags; + bool myHasFaultFlags; + double myCompass; + int myAnalogPortSelected; + unsigned char myAnalog; + unsigned char myDigIn; + unsigned char myDigOut; + int myIOAnalog[128]; + unsigned char myIODigIn[255]; + unsigned char myIODigOut[255]; + int myIOAnalogSize; + int myIODigInSize; + int myIODigOutSize; + ArTime myLastIOPacketReceivedTime; + double myVel; + double myRotVel; + double myLatVel; + int myLastX; + int myLastY; + int myLastTh; + ChargeState myChargeState; + bool myOverriddenChargeState; + bool myIsChargerPowerGood; + bool myOverriddenIsChargerPowerGood; + + char myTemperature; + + double myTripOdometerDistance; + double myTripOdometerDegrees; + ArTime myTripOdometerStart; + + double myOdometerDistance; + double myOdometerDegrees; + ArTime myOdometerStart; + + int myOdometryDelay; + + bool myDoNotSwitchBaud; + + bool myAddedAriaExitCB; + ArFunctorC myAriaExitCB; + + ArRetFunctor3C myPoseInterpPositionCB; + ArRetFunctor3C myEncoderPoseInterpPositionCB; +}; + + +#endif // ARROBOT_H diff --git a/Legacy/Aria/include/ArRobotBatteryPacketReader.h b/Legacy/Aria/include/ArRobotBatteryPacketReader.h new file mode 100644 index 0000000..e3a7dcf --- /dev/null +++ b/Legacy/Aria/include/ArRobotBatteryPacketReader.h @@ -0,0 +1,100 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARROBOTBATTERYPACKETREADER_H +#define ARROBOTBATTERYPACKETREADER_H + +#include "ariaTypedefs.h" +#include "ariaUtil.h" +#include "ArFunctor.h" + +class ArRobot; +class ArRobotPacket; + +/// This class will read a config packet from the robot +class ArRobotBatteryPacketReader +{ +public: + /// Constructor + AREXPORT ArRobotBatteryPacketReader(ArRobot *robot); + /// Destructor + AREXPORT ~ArRobotBatteryPacketReader(); + /// Request a single packet.. + AREXPORT void requestSinglePacket(void); + /// Request a continous stream of packets + AREXPORT void requestContinuousPackets(void); + /// Stop the stream of packets + AREXPORT void stopPackets(void); + /// See if we've requested packets + AREXPORT bool haveRequestedPackets(void); + /// See if we've gotten the data + bool hasPacketArrived(void) const { return myPacketArrived; } + /// Gets the number of batteries + int getNumBatteries(void) const { return myNumBatteries; } + /// Gets the number of bytes per battery + int getNumBytesPerBattery(void) const { return myNumBytesPerBattery; } + /// Gets the flags1 for a particular battery + int getFlags1(int battery) { return myFlags1[battery]; } + /// Gets the flags2 for a particular battery + int getFlags2(int battery) { return myFlags2[battery]; } + /// Gets the flags3 for a particular battery + int getFlags3(int battery) { return myFlags3[battery]; } + /// Gets the relative state of charge for a particular battery + int getRelSOC(int battery) { return myRelSOC[battery]; } + /// Gets the absolute state of charge for a particular battery + int getAbsSOC(int battery) { return myAbsSOC[battery]; } + + +protected: + /// internal, packet handler + AREXPORT bool packetHandler(ArRobotPacket *packet); + /// internal, packet handler + AREXPORT void connectCallback(void); + + // the robot + ArRobot *myRobot; + + int myNumBatteries; + int myNumBytesPerBattery; + std::map myFlags1; + std::map myFlags2; + std::map myFlags3; + std::map myRelSOC; + std::map myAbsSOC; + + + // whether our data has been received or not + bool myPacketArrived; + // last time we requested a packet (we'll only ask every 200 ms) + ArTime myLastPacketRequest; + + bool myRequestedBatteryPackets; + + // the callback + ArRetFunctor1C myPacketHandlerCB; + ArFunctorC myConnectCB; +}; + +#endif // ARROBOTBATTERYPACKETREADER_H diff --git a/Legacy/Aria/include/ArRobotConfig.h b/Legacy/Aria/include/ArRobotConfig.h new file mode 100644 index 0000000..379c4a0 --- /dev/null +++ b/Legacy/Aria/include/ArRobotConfig.h @@ -0,0 +1,75 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARROBOTCONFIG_H +#define ARROBOTCONFIG_H + +#include "ArFunctor.h" + +class ArRobot; +class ArAnalogGyro; + +/// Class for controlling robot movement parameters from config +class ArRobotConfig +{ +public: + /// Constructor + AREXPORT ArRobotConfig(ArRobot *robot); + /// Destructor + AREXPORT virtual ~ArRobotConfig(); + /// Adds a gyro to turn on and off + AREXPORT void addAnalogGyro(ArAnalogGyro *gyro); + /// Called when we process the config + AREXPORT bool processFile(void); + /// Called when we connect to the robot + AREXPORT void connectCallback(void); +protected: + ArRobot *myRobot; + ArAnalogGyro *myAnalogGyro; + + bool mySavedOriginalMovementParameters; + int myOriginalTransVelMax; + int myOriginalTransAccel; + int myOriginalTransDecel; + int myOriginalRotVelMax; + int myOriginalRotAccel; + int myOriginalRotDecel; + + bool myAddedMovementParams; + int myTransVelMax; + int myTransAccel; + int myTransDecel; + int myRotVelMax; + int myRotAccel; + int myRotDecel; + + bool myAddedGyro; + bool myUseGyro; + + ArFunctorC myConnectCB; + ArRetFunctorC myProcessFileCB; +}; + +#endif diff --git a/Legacy/Aria/include/ArRobotConfigPacketReader.h b/Legacy/Aria/include/ArRobotConfigPacketReader.h new file mode 100644 index 0000000..4f8e544 --- /dev/null +++ b/Legacy/Aria/include/ArRobotConfigPacketReader.h @@ -0,0 +1,293 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARROBOTCONFIGPACKETREADER_H +#define ARROBOTCONFIGPACKETREADER_H + +#include "ariaTypedefs.h" +#include "ariaUtil.h" +#include "ArFunctor.h" +#include "ArRobotPacket.h" + +class ArRobot; + + +/// This class will read a config packet from the robot +class ArRobotConfigPacketReader +{ +public: + /// Constructor + AREXPORT ArRobotConfigPacketReader(ArRobot *robot, + bool onlyOneRequest = false, + ArFunctor *packetedArrivedCB = NULL); + /// Destructor + AREXPORT ~ArRobotConfigPacketReader(); + /// Request a packet.. true if we could, false if onlyOneRequest already done + AREXPORT bool requestPacket(void); + /// See if we've requested a packet yet + bool hasPacketBeenRequested(void) const { return myPacketRequested; } + /// See if we've gotten the data + bool hasPacketArrived(void) const { return myPacketArrived; } + /// Gets a pointer to the packet that we built the config packet from + const ArRobotPacket *getRobotPacket(void) const { return &myPacket; } + /// Log the config + AREXPORT void log(void) const; + /// Log the movement part of the config config + AREXPORT void logMovement(void) const; + /// Builds a string of the info + AREXPORT std::string buildString(void) const; + /// Builds a string of the movement info + AREXPORT std::string buildStringMovement(void) const; + /// Gets the type of robot + const char *getType(void) const { return myType.c_str(); } + /// Gets the subtype of robot + const char *getSubType(void) const { return mySubType.c_str(); } + /// Gets the serial number of the robot + const char *getSerialNumber(void) const { return mySerialNumber.c_str(); } + /// Gets the absolute maximum rotational velocity in deg/sec (cannot be set above this in firmware or through software) + int getRotVelTop(void) const { return myRotVelTop; } + /// Gets the absolute maximum translational velocity in mm/sec (cannot be set above this in firmware or through software) + int getTransVelTop(void) const { return myTransVelTop; } + /// Gets the absolute maximum rotational acceleration in deg/sec/sec (cannot be set above this in firmware or through software) + int getRotAccelTop(void) const { return myRotAccelTop; } + /// Gets the absolute maximum translational acceleration in mm/sec/sec (cannot be set above this in firmware or through software) + int getTransAccelTop(void) const { return myTransAccelTop; } + /// Gets the maximum PWM the robot will have (stallval cannot be above this) + int getPwmMax(void) const { return myPwmMax; } + /// Gets the name of the robot + const char *getName(void) const { return myName.c_str(); } + /// Gets the cycle time in ms of the motor packets + int getSipCycleTime(void) const { return mySipCycleTime; } + /// Gets the host baud number, look at the manual for what these mean + int getHostBaud(void) const { return myHostBaud; } + /// Gets the host baud number, look at the manual for what these mean + int getAux1Baud(void) const { return myAux1Baud; } + /// Gets the gripper value (whether or not the robot has a gripper) + bool getHasGripper(void) const { return myHasGripper; } + /// Gets whether or not the robot has front sonar + bool getFrontSonar(void) const { return myFrontSonar; } + /// Gets whether or not the robot has rear sonar + bool getRearSonar(void) const { return myRearSonar; } + /// Gets the low battery beeping indicating voltage times 10 + int getLowBattery(void) const { return myLowBattery; } + /// Gets the revcount + int getRevCount(void) const { return myRevCount; } + /// Gets the watchdog (how many ms after command robot stops) + int getWatchdog(void) const { return myWatchdog; } + /// Returns if the robot is using normal packets or new style packets + bool getNormalMPacs(void) const { return myNormalMPacs; } + /// Returns the stallval (pwms at which robot stalls) + int getStallVal(void) const { return myStallVal; } + /// Returns the stallcount (how many 10ms increments robot stops after stall) + int getStallCount(void) const { return myStallCount; } + /// Returns the joystick translational velocity + int getJoyVel(void) const { return myJoyVel; } + /// Returns the joystick rotational velocity + int getJoyRotVel(void) const { return myJoyRotVel; } + /// Returns the current maximum rotational velocity (deg/sec) (can be set) + int getRotVelMax(void) const { return myRotVelMax; } + /// Returns the current maximum translational velocity (mm/sec) (can be set) + int getTransVelMax(void) const { return myTransVelMax; } + /// Returns the rotational acceleration + int getRotAccel(void) const { return myRotAccel; } + /// Returns the rotational deceleration + int getRotDecel(void) const { return myRotDecel; } + /// Returns the rotational KP value (look at the manual) + int getRotKP(void) const { return myRotKP; } + /// Returns the rotational KV value (look at the manual) + int getRotKV(void) const { return myRotKV; } + /// Returns the rotational KI value (look at the manual) + int getRotKI(void) const { return myRotKI; } + /// Returns the translational acceleration + int getTransAccel(void) const { return myTransAccel; } + /// Returns the translational deceleration + int getTransDecel(void) const { return myTransDecel; } + /// Returns the translational KP value (look at the manual) + int getTransKP(void) const { return myTransKP; } + /// Returns the translational KV value (look at the manual) + int getTransKV(void) const { return myTransKV; } + /// Returns the translational KI value (look at the manual) + int getTransKI(void) const { return myTransKI; } + /// Returns the number of front bumpers + int getFrontBumps(void) const { return myFrontBumps; } + /// Returns the number of rear bumpers + int getRearBumps(void) const { return myRearBumps; } + /// Returns whether the robot has a charger + int getHasCharger(void) const { return myHasCharger; } + /// Returns the number of ms the sonar cycle is (default is 40) + int getSonarCycle(void) const { return mySonarCycle; } + /// Returns the baud rate + bool getResetBaud(void) const { return myResetBaud; } + /// Returns if the robot has a gyro or not + bool getHasGyro(void) const { return myHasGyro; } + /// Returns if the robot has a gyro or not + int getGyroType(void) const { return myGyroType; } + /// Returns the DriftFactor value (see the manual) + int getDriftFactor(void) const { return myDriftFactor; } + /// Returns the Aux2 baud number, look at the manual for what these mean + int getAux2Baud(void) const { return myAux2Baud; } + /// Returns the Aux3 baud number, look at the manual for what these mean + int getAux3Baud(void) const { return myAux3Baud; } + /// Returns the Ticks/MM for the robot + int getTicksMM(void) const { return myTicksMM; } + /// Returns the voltage (x10) that the robot will shut down the computer at + int getShutdownVoltage(void) const { return myShutdownVoltage; } + /// Gets the firmware version + const char *getFirmwareVersion(void) const + { return myFirmwareVersion.c_str(); } + /// Gets the gyro CW value + int getGyroCW(void) const { return myGyroCW; } + /// Gets the gyro CCW value + int getGyroCCW(void) const { return myGyroCCW; } + /// Gets the kinematics delay + int getKinematicsDelay(void) const { return myKinematicsDelay; } + /// Gets the absolute maximum lateral velocity in mm/sec (cannot be set above this in firmware or through software) + int getLatVelTop(void) const { return myLatVelTop; } + /// Gets the absolute maximum lateral acceleration in mm/sec/sec (cannot be set above this in firmware or through software) + int getLatAccelTop(void) const { return myLatAccelTop; } + /// Returns the current maximum lateral velocity (mm/sec) (can be set) + int getLatVelMax(void) const { return myLatVelMax; } + /// Returns the lateral acceleration + int getLatAccel(void) const { return myLatAccel; } + /// Returns the lateral deceleration + int getLatDecel(void) const { return myLatDecel; } + /// Gets the powerbot charge threshold + int getPowerbotChargeThreshold(void) const + { return myPowerbotChargeThreshold; } + /// Gets the port the PDB is on + unsigned char getPDBPort(void) const + { return myPDBPort; } + /// Gets the port the PDB is on + int getGyroRateLimit(void) const + { return myGyroRateLimit; } + /// Gets the high temperature threshold + char getHighTemperatureShutdown(void) const + { return myHighTemperatureShutdown; } + /// Gets the power bits + int getPowerBits(void) const + { return myPowerBits; } + /// Gets the battery type + unsigned char getBatteryType(void) const + { return myBatteryType; } + /// Gets the warning state of charge + int getStateOfChargeLow(void) const + { return myStateOfChargeLow; } + /// Gets the shutdown state of charge + int getStateOfChargeShutdown(void) const + { return myStateOfChargeShutdown; } + /// internal, packet handler + AREXPORT bool packetHandler(ArRobotPacket *packet); + /// internal, connection callback + AREXPORT void connected(void); +protected: + // the different parameters from the robot + std::string myType; + std::string mySubType; + std::string mySerialNumber; + int myRotVelTop; + int myTransVelTop; + int myRotAccelTop; + int myTransAccelTop; + int myPwmMax; + std::string myName; + int mySipCycleTime; + int myHostBaud; + int myAux1Baud; + bool myHasGripper; + bool myFrontSonar; + bool myRearSonar; + int myLowBattery; + int myRevCount; + int myWatchdog; + bool myNormalMPacs; + int myStallVal; + int myStallCount; + int myJoyVel; + int myJoyRotVel; + int myRotVelMax; + int myTransVelMax; + int myRotAccel; + int myRotDecel; + int myRotKP; + int myRotKV; + int myRotKI; + int myTransAccel; + int myTransDecel; + int myTransKP; + int myTransKV; + int myTransKI; + int myFrontBumps; + int myRearBumps; + int myHasCharger; + int mySonarCycle; + bool myResetBaud; + bool myHasGyro; + int myGyroType; + int myDriftFactor; + int myAux2Baud; + int myAux3Baud; + int myTicksMM; + int myShutdownVoltage; + std::string myFirmwareVersion; + int myGyroCW; + int myGyroCCW; + int myKinematicsDelay; + int myLatVelTop; + int myLatAccelTop; + int myLatVelMax; + int myLatAccel; + int myLatDecel; + int myPowerbotChargeThreshold; + unsigned char myPDBPort; + int myGyroRateLimit; + char myHighTemperatureShutdown; + int myPowerBits; + unsigned char myBatteryType; + int myStateOfChargeLow; + int myStateOfChargeShutdown; + + // the robot + ArRobot *myRobot; + // whether only one request can be done or not + bool myOnlyOneRequest; + // whether a request has been made or not + bool myPacketRequested; + // whether our data has been received or not + bool myPacketArrived; + // last time we requested a packet (we'll only ask every 200 ms) + ArTime myLastPacketRequest; + // a copy of the packet + ArRobotPacket myPacket; + + // the callback + ArRetFunctor1C myPacketHandlerCB; + // callback for connectiosn in case we need to request a config packet + ArFunctorC myConnectedCB; + // callback for when we get a packet + ArFunctor *myPacketArrivedCB; + +}; + +#endif // ARROBOTCONFIGPACKETREADER_H diff --git a/Legacy/Aria/include/ArRobotConnector.h b/Legacy/Aria/include/ArRobotConnector.h new file mode 100644 index 0000000..be94706 --- /dev/null +++ b/Legacy/Aria/include/ArRobotConnector.h @@ -0,0 +1,165 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARROBOTCONNECTOR_H +#define ARROBOTCONNECTOR_H + +#include "ariaTypedefs.h" +#include "ArSerialConnection.h" +#include "ArTcpConnection.h" +#include "ArArgumentBuilder.h" +#include "ArArgumentParser.h" +#include "ariaUtil.h" + +class ArRobot; +class ArSonarConnector; +class ArBatteryConnector; +//class ArLCDConnector; + +/** Connect to robot or simulator based on program command line parameters. + + ArRobotConnector makes a robot connection either through a TCP + port (for the simulator or for robots with Ethernet-serial bridge + devices instead of onboard computers), or through a direct serial + port connection. Normally, it first attempts a TCP connection on + @a localhost port 8101, to use a simulator if running. If the simulator + is not running, then it normally then connects using the serial port + (the first serial port, COM1, by default). Various other connection + parameters are configurable through command-line arguments. + + When you create your ArRobotConnector, pass it command line parameters via + either the argc and argv variables from main(), or pass it an + ArArgumentBuilder or ArArgumentParser object. (ArArgumentBuilder + is able to obtain command line parameters from a Windows program + that uses WinMain() instead of main()). + ArRobotConnector registers a callback with the global Aria class. Use + Aria::parseArgs() to parse all command line parameters to the program, and + Aria::logOptions() to print out information about all registered command-line parameters. + + The following command-line arguments are checked: + @verbinclude ArRobotConnector_options + + You can then prepare an ArRobot object for connection (with various connection + options configured via the command line parameters) and initiate the connection + attempt by that object by calling connectRobot(). + + After it's connected, you must then begin the robot processing cycle by calling + ArRobot::runAsync() or ArRobot::run(). + + @sa ArLaserConnector + @sa ArRobot + + @since 2.7.0 + + @ingroup ImportantClasses + @ingroup DeviceClasses + +**/ +class ArRobotConnector +{ +public: + /// Constructor that takes argument parser + AREXPORT ArRobotConnector(ArArgumentParser *parser, ArRobot *robot, + bool autoParseArgs = true, bool connectAllComponents = true); + /// Destructor + AREXPORT ~ArRobotConnector(void); + /// Sets up the given robot to be connected + AREXPORT bool setupRobot(void); + /// Sets up an arbitrary robot to be connected + AREXPORT bool setupRobot(ArRobot *robot); + /// Sets up the robot then connects it + AREXPORT bool connectRobot(void); + /// Sets up the robot then connects it + AREXPORT bool connectRobot(ArRobot *robot); + /// Function to parse the arguments given in the constructor + AREXPORT bool parseArgs(void); + /// Function to parse the arguments given in an arbitrary parser + AREXPORT bool parseArgs(ArArgumentParser *parser); + /// Log the options the simple connector has + AREXPORT void logOptions(void) const; + /// Gets the remote host, if one was used, or NULL if it wasn't + AREXPORT const char *getRemoteHost(void) const; + /// Gets if the remote connection is a sim + AREXPORT bool getRemoteIsSim(void) const; + /// Call for forcing the remote to be a sim (mostly for internal use) + AREXPORT void setRemoteIsSim(bool remoteIsSim); + /// Gets the robot this connector is using (mostly for backwards compatibility stuff) + AREXPORT ArRobot *getRobot(void); +protected: + // the robot we've set up (so we can find its params) + ArRobot *myRobot; + // if we're using the sim or not + bool myUsingSim; + // if we're connecting via tcp (not to the sim), what remote host + const char *myRemoteHost; + // robot port, if there isn't one this'll be NULL, which will just + // be the default of ArUtil::COM1 + const char *myRobotPort; + // baud for the serial + int myRobotBaud; + // robot tcp port if we're doing a remote host (defaults to 8101) + int myRemoteRobotTcpPort; + + // whether we're connecting to a remote sim or not (so we don't try + // to open a port for the laser) + bool myRemoteIsSim; + // force a sim to not look like a sim (for laser debugging mostly) + bool myRemoteIsNotSim; + // variables to hold if we're logging or not + bool myRobotLogPacketsReceived; + bool myRobotLogPacketsSent; + bool myRobotLogMovementReceived; + bool myRobotLogMovementSent; + bool myRobotLogVelocitiesReceived; + bool myRobotLogActions; + + // if we're auto parsing the arguments when setupRobot or + // connectRobot are called + bool myAutoParseArgs; + // If we've parsed the args already or not + bool myHaveParsedArgs; + + // If true, create additional connectors such as sonar, battery, lcd. + bool myConnectAllComponents; + + + // our parser + ArArgumentParser *myParser; + bool myOwnParser; + + // a few device connections to use to connect to the robot + ArTcpConnection myRobotTcpConn; + ArSerialConnection myRobotSerConn; + + ArRetFunctorC myParseArgsCB; + ArConstFunctorC myLogOptionsCB; + +// ArLCDConnector *myLCDConnector; + ArBatteryConnector *myBatteryConnector; + ArSonarConnector *mySonarConnector; +}; + + +#endif diff --git a/Legacy/Aria/include/ArRobotJoyHandler.h b/Legacy/Aria/include/ArRobotJoyHandler.h new file mode 100644 index 0000000..15779a7 --- /dev/null +++ b/Legacy/Aria/include/ArRobotJoyHandler.h @@ -0,0 +1,101 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARROBOTJOYHANDLER_H +#define ARROBOTJOYHANDLER_H + +#include "ariaTypedefs.h" +#include "ariaUtil.h" + +class ArRobot; +class ArRobotPacket; + +/// Interfaces to a joystick on the robot's microcontroller +/** + This is largely meant to be about the same as the normal joy + handler but gets the data back from the robot about the joystick, + but this sameness is why it reports things as it does. + + Also note that x is usually rotational velocity (since it right/left), + whereas Y is translational (since it is up/down). + + @ingroup OptionalClasses +**/ +class ArRobotJoyHandler +{ + public: + /// Constructor + AREXPORT ArRobotJoyHandler(ArRobot *robot); + /// Destructor + AREXPORT ~ArRobotJoyHandler(); + /// Gets the adjusted reading, as floats + AREXPORT void getDoubles(double *x, double *y, double *z); + /// Gets the first button + bool getButton1(void) { return myButton1; } + /// Gets the second button + bool getButton2(void) { return myButton2; } + /// Gets the time we last got information back + AREXPORT ArTime getDataReceivedTime(void) { return myDataReceived; } + /// If we've ever gotten a packet back + AREXPORT bool gotData(void) { return myGotData; } + /// Adds to a section in a config + AREXPORT void addToConfig(ArConfig *config, const char *section); + /// Gets the X value (only use for information, or with the robot locked, getDoubles is preferred) + int getRawX(void) { return myRawX; } + /// Gets the Y value (only use for information, or with the robot locked, getDoubles is preferred) + int getRawY(void) { return myRawY; } + /// Gets the throttle value (only use for information, or with the robot locked, getDoubles is preferred) + int getRawThrottle(void) { return myRawThrottle; } + + protected: + AREXPORT bool handleJoystickPacket(ArRobotPacket *packet); + AREXPORT void connectCallback(void); + + ArRobot *myRobot; + ArTime myDataReceived; + bool myButton1; + bool myButton2; + double myJoyX; + double myJoyY; + double myThrottle; + bool myGotData; + + int myJoyXCenter; + int myJoyYCenter; + + int myRawX; + int myRawY; + int myRawThrottle; + + ArTime myStarted; + ArRetFunctor1C myHandleJoystickPacketCB; + ArFunctorC myConnectCB; + +}; + + +#endif // ARJOYHANDLER_H + diff --git a/Legacy/Aria/include/ArRobotPacket.h b/Legacy/Aria/include/ArRobotPacket.h new file mode 100644 index 0000000..c737182 --- /dev/null +++ b/Legacy/Aria/include/ArRobotPacket.h @@ -0,0 +1,81 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARROBOTPACKET_H +#define ARROBOTPACKET_H + +#include "ariaTypedefs.h" +#include "ArBasePacket.h" +#include "ariaUtil.h" + +/// Represents the packets sent to the robot as well as those received from it +/** + This class reimplements some of the buf operations since the robot is + opposeite endian from intel. Also has the getID for convenience. + + You can just look at the documentation for the ArBasePacket except for + the 4 new functions here, verifyCheckSum, getID, print, and calcCheckSum. + */ +class ArRobotPacket: public ArBasePacket +{ +public: + /// Constructor + AREXPORT ArRobotPacket(unsigned char sync1 = 0xfa, + unsigned char sync2 = 0xfb); + /// Destructor + AREXPORT virtual ~ArRobotPacket(); + + /// Assignment operator + AREXPORT ArRobotPacket &operator=(const ArRobotPacket &other); + + /// returns true if the checksum matches what it should be + AREXPORT bool verifyCheckSum(void); + + /// returns the ID of the packet + AREXPORT ArTypes::UByte getID(void); + + /// Sets the ID of the packet + AREXPORT void setID(ArTypes::UByte id); + + /// returns the checksum, probably used only internally + AREXPORT ArTypes::Byte2 calcCheckSum(void); + + // only call finalizePacket before a send + AREXPORT virtual void finalizePacket(void); + + /// Gets the time the packet was received at + AREXPORT ArTime getTimeReceived(void); + /// Sets the time the packet was received at + AREXPORT void setTimeReceived(ArTime timeReceived); + + AREXPORT virtual void log(); + +protected: + unsigned char mySync1; + unsigned char mySync2; + ArTime myTimeReceived; +}; + +#endif // ARROBOTPACKET_H diff --git a/Legacy/Aria/include/ArRobotPacketReaderThread.h b/Legacy/Aria/include/ArRobotPacketReaderThread.h new file mode 100644 index 0000000..eb288a0 --- /dev/null +++ b/Legacy/Aria/include/ArRobotPacketReaderThread.h @@ -0,0 +1,59 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARROBOTPACKETREADER_H +#define ARROBOTPACKETREADER_H + + +#include "ariaTypedefs.h" +#include "ArASyncTask.h" + + +class ArRobot; + + +class ArRobotPacketReaderThread : public ArASyncTask +{ +public: + + AREXPORT ArRobotPacketReaderThread(); + AREXPORT virtual ~ArRobotPacketReaderThread(); + + AREXPORT void setRobot(ArRobot *robot); + + AREXPORT void stopRunIfNotConnected(bool stopRun); + AREXPORT virtual void * runThread(void *arg); + + AREXPORT virtual const char *getThreadActivity(void); + + +protected: + bool myStopRunIfNotConnected; + ArRobot *myRobot; + bool myInRun; +}; + + +#endif // ARSYNCLOOP_H diff --git a/Legacy/Aria/include/ArRobotPacketReceiver.h b/Legacy/Aria/include/ArRobotPacketReceiver.h new file mode 100644 index 0000000..13ac6ea --- /dev/null +++ b/Legacy/Aria/include/ArRobotPacketReceiver.h @@ -0,0 +1,101 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARROBOTPACKETRECEIVER_H +#define ARROBOTPACKETRECEIVER_H + +#include "ariaTypedefs.h" +#include "ArRobotPacket.h" + + +class ArDeviceConnection; + +/// Given a device connection it receives packets from the robot through it +class ArRobotPacketReceiver +{ +public: + /// Constructor without an already assigned device connection + AREXPORT ArRobotPacketReceiver(bool allocatePackets = false, + unsigned char sync1 = 0xfa, + unsigned char sync2 = 0xfb); + /// Constructor with assignment of a device connection + AREXPORT ArRobotPacketReceiver(ArDeviceConnection *deviceConnection, + bool allocatePackets = false, + unsigned char sync1 = 0xfa, + unsigned char sync2 = 0xfb); + /// Constructor with assignment of a device connection and tracking + AREXPORT ArRobotPacketReceiver(ArDeviceConnection *deviceConnection, + bool allocatePackets, + unsigned char sync1, + unsigned char sync2, + bool tracking, + const char *trackingLogName); + /// Destructor + AREXPORT virtual ~ArRobotPacketReceiver(); + + /// Receives a packet from the robot if there is one available + AREXPORT ArRobotPacket *receivePacket(unsigned int msWait = 0); + + /// Sets the device this instance receives packets from + AREXPORT void setDeviceConnection(ArDeviceConnection *deviceConnection); + /// Gets the device this instance receives packets from + AREXPORT ArDeviceConnection *getDeviceConnection(void); + + /// Gets whether or not the receiver is allocating packets + AREXPORT bool isAllocatingPackets(void) { return myAllocatePackets; } + /// Sets whether or not the receiver is allocating packets + AREXPORT void setAllocatingPackets(bool allocatePackets) + { myAllocatePackets = allocatePackets; } + +#ifdef DEBUG_SPARCS_TESTING + AREXPORT void setSync1(unsigned char s1) { mySync1 = s1; } + AREXPORT void setSync2(unsigned char s2) { mySync2 = s2; } +#endif + + AREXPORT void setTracking(bool tracking) + { myTracking = tracking; } + + AREXPORT void setTrackingLogName(const char *trackingLogName) + { myTrackingLogName = trackingLogName; } + + /// Sets the callback that gets called with the finalized version of + /// every packet set... this is ONLY for very internal very + /// specialized use + AREXPORT void setPacketReceivedCallback(ArFunctor1 *functor); +protected: + ArDeviceConnection *myDeviceConn; + bool myTracking; + std::string myTrackingLogName; + + bool myAllocatePackets; + ArRobotPacket myPacket; + enum { STATE_SYNC1, STATE_SYNC2, STATE_ACQUIRE_DATA }; + unsigned char mySync1; + unsigned char mySync2; + + ArFunctor1 *myPacketReceivedCallback; +}; + +#endif // ARROBOTPACKETRECEIVER_H diff --git a/Legacy/Aria/include/ArRobotPacketSender.h b/Legacy/Aria/include/ArRobotPacketSender.h new file mode 100644 index 0000000..7691187 --- /dev/null +++ b/Legacy/Aria/include/ArRobotPacketSender.h @@ -0,0 +1,95 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARROBOTPACKETSENDER_H +#define ARROBOTPACKETSENDER_H + +#include "ariaTypedefs.h" +#include "ArRobotPacket.h" + +class ArDeviceConnection; + +/// Given a device connection this sends commands through it to the robot + +class ArRobotPacketSender +{ +public: + /// Constructor without an already assigned device connection + AREXPORT ArRobotPacketSender(unsigned char sync1 = 0xfa, + unsigned char sync2 = 0xfb); + /// Constructor with assignment of a device connection + AREXPORT ArRobotPacketSender(ArDeviceConnection *deviceConnection, + unsigned char sync1 = 0xfa, + unsigned char sync2 = 0xfb); + /// Constructor with assignment of a device connection and tracking + AREXPORT ArRobotPacketSender(ArDeviceConnection *deviceConnection, + unsigned char sync1, + unsigned char sync2, + bool tracking, + const char *trackingLogName); + /// Destructor + AREXPORT virtual ~ArRobotPacketSender(); + + /// Sends a command to the robot with no arguments + AREXPORT bool com(unsigned char command); + /// Sends a command to the robot with an int for argument + AREXPORT bool comInt(unsigned char command, short int argument); + /// Sends a command to the robot with two bytes for argument + AREXPORT bool com2Bytes(unsigned char command, char high, char low); + /// Sends a command to the robot with a length-prefixed string for argument + AREXPORT bool comStr(unsigned char command, const char *argument); + /// Sends a command to the robot with a length-prefixed string for argument + AREXPORT bool comStrN(unsigned char command, const char *str, int size); + /// Sends a command containing exactly the data in the given buffer as argument + AREXPORT bool comDataN(unsigned char command, const char *data, int size); + /// Sends a ArRobotPacket + AREXPORT bool sendPacket(ArRobotPacket *packet); + + /// Sets the device this instance sends commands to + AREXPORT void setDeviceConnection(ArDeviceConnection *deviceConnection); + /// Gets the device this instance sends commands to + AREXPORT ArDeviceConnection *getDeviceConnection(void); + + /// Sets the callback that gets called with the finalized version of + /// every packet set... this is ONLY for very internal very + /// specialized use + AREXPORT void setPacketSentCallback(ArFunctor1 *functor); +protected: + bool connValid(void); + ArDeviceConnection * myDeviceConn; + ArRobotPacket myPacket; + + bool myTracking; + std::string myTrackingLogName; + + ArMutex mySendingMutex; + + ArFunctor1 *myPacketSentCallback; + + enum { INTARG = 0x3B, NINTARG = 0x1B, STRARG = 0x2B }; +}; + + +#endif //ARROBOTPACKETSENDER_H diff --git a/Legacy/Aria/include/ArRobotParams.h b/Legacy/Aria/include/ArRobotParams.h new file mode 100644 index 0000000..f3112b6 --- /dev/null +++ b/Legacy/Aria/include/ArRobotParams.h @@ -0,0 +1,1296 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARROBOTPARAMS_H +#define ARROBOTPARAMS_H + +#include "ariaTypedefs.h" +#include "ArConfig.h" +#include + +#ifndef SWIG + +/// Stores a set of video device parameters read from one of the video sections of a robot parameter file. +/// @internal +/// @swigomit +class ArVideoParams +{ +public: + std::string type; + bool connect; bool connectSet; + int imageWidth; + int imageHeight; + int deviceIndex; + std::string deviceName; + int channel; + std::string analogSignalFormat; + std::string address; + int tcpPort; bool tcpPortSet; + bool inverted; bool invertedSet; + ArVideoParams() : + type("unknown"), + connect(false), + connectSet(false), + imageWidth(-1), + imageHeight(-1), + deviceIndex(-1), + deviceName("none"), + channel(1), + analogSignalFormat(""), + address("192.168.0.90"), + tcpPort(80), + tcpPortSet(false), + inverted(false), + invertedSet(false) + {} + /// Copy values of any parameters in @a other into @a this, if given in @a other + AREXPORT void merge(const ArVideoParams& other); + void setType(const std::string& t) { type = t; } + void setConnect(bool c) { connect = c; connectSet = true; } + void setImageSize(int w, int h) { imageWidth = w; imageHeight = h; } + void setInverted(bool i) { inverted = i; invertedSet = true; } + void setDevice(const std::string& name, int idx, int chan) + { + deviceName = name; + deviceIndex = idx; + channel = chan; + } + void setAddress(const std::string& a) { address = a; } + void setTCPPort(int p) { tcpPort = p; tcpPortSet = true; } +}; + +/// Stores a set of PTZ/PTU device parameters read from one of the PTZ sections of a robot parameter file. +/// @internal +/// @swigomit +class ArPTZParams +{ +public: + std::string type; + bool connect; bool connectSet; + std::string serialPort; + int robotAuxPort; + std::string address; + int tcpPort; bool tcpPortSet; + bool inverted; bool invertedSet; + ArPTZParams() : + type("unknown"), + connect(false), + connectSet(false), + serialPort("none"), + robotAuxPort(-1), + address("192.168.0.90"), + tcpPort(80), + tcpPortSet(false), + inverted(false), + invertedSet(false) + {} + /// Copy values of any parameters in @a other into @a this, if given in @a other + void merge(const ArPTZParams& other); + void setType(const std::string& t) { type = t; } + void setConnect(bool c) { connect = c; connectSet = true; } + void setSerialPort(const std::string& sp) { serialPort = sp; } + void setTcpPort(int p) { tcpPort = p; tcpPortSet = true; } + void setRobotAuxPort(int p) { robotAuxPort = p; } + void setInverted(bool i) { inverted = i; invertedSet = true; } + void setAddress(const std::string& a) { address = a; } +}; + +#endif // ifndef SWIG + +///Stores parameters read from the robot's parameter files +/** + Use ArRobot::getRobotParams() after a successful robot + connection to obtain a pointer to an ArRobotParams instance containing the + values read from the files. + + See @ref ParamFiles for a description of the robot parameter files. + + ArRobotParams is a subclass of ArConfig which contains some useful methods + and features. +*/ +class ArRobotParams : public ArConfig +{ +public: + /// Constructor + AREXPORT ArRobotParams(); + /// Destructor + AREXPORT virtual ~ArRobotParams(); + /// Returns the class from the parameter file + const char *getClassName(void) const { return myClass; } + /// Returns the subclass from the parameter file + const char *getSubClassName(void) const { return mySubClass; } + /// Returns the robot's radius + double getRobotRadius(void) const { return myRobotRadius; } + /// Returns the robot diagonal (half-height to diagonal of octagon) + double getRobotDiagonal(void) const { return myRobotDiagonal; } + /// Returns the robot's width + double getRobotWidth(void) const { return myRobotWidth; } + /// Returns the robot's length + double getRobotLength(void) const { return myRobotLength; } + /// Returns the robot's length to the front of the robot + double getRobotLengthFront(void) const { return myRobotLengthFront; } + /// Returns the robot's length to the rear of the robot + double getRobotLengthRear(void) const { return myRobotLengthRear; } + /// Returns whether the robot is holonomic or not + bool isHolonomic(void) const { return myHolonomic; } + /// Returns if the robot has a built in move command + bool hasMoveCommand(void) const { return myHaveMoveCommand; } + /// Returns the max velocity of the robot + int getAbsoluteMaxVelocity(void) const { return myAbsoluteMaxVelocity; } + /// Returns the max rotational velocity of the robot + int getAbsoluteMaxRotVelocity(void) const { return myAbsoluteMaxRVelocity; } + /// Returns the max lateral velocity of the robot + int getAbsoluteMaxLatVelocity(void) const + { return myAbsoluteMaxLatVelocity; } + /// Returns true if IO packets are automatically requested upon connection to the robot. + bool getRequestIOPackets(void) const { return myRequestIOPackets; } + /// Returns true if encoder packets are automatically requested upon connection to the robot. + bool getRequestEncoderPackets(void) const { return myRequestEncoderPackets; } + /// Returns the baud rate set in the param to talk to the robot at + int getSwitchToBaudRate(void) const { return mySwitchToBaudRate; } + /// Returns the angle conversion factor + double getAngleConvFactor(void) const { return myAngleConvFactor; } + /// Returns the distance conversion factor + double getDistConvFactor(void) const { return myDistConvFactor; } + /// Returns the velocity conversion factor + double getVelConvFactor(void) const { return myVelConvFactor; } + /// Returns the sonar range conversion factor + double getRangeConvFactor(void) const { return myRangeConvFactor; } + /// Returns the wheel velocity difference to angular velocity conv factor + double getDiffConvFactor(void) const { return myDiffConvFactor; } + /// Returns the multiplier for VEL2 commands + double getVel2Divisor(void) const { return myVel2Divisor; } + /// Returns the multiplier for the Analog Gyro + double getGyroScaler(void) const { return myGyroScaler; } + /// Returns true if the robot has table sensing IR + bool haveTableSensingIR(void) const { return myTableSensingIR; } + /// Returns true if the robot's table sensing IR bits are sent in the 4th-byte of the IO packet + bool haveNewTableSensingIR(void) const { return myNewTableSensingIR; } + /// Returns true if the robot has front bumpers + bool haveFrontBumpers(void) const { return myFrontBumpers; } + /// Returns the number of front bumpers + int numFrontBumpers(void) const { return myNumFrontBumpers; } + /// Returns true if the robot has rear bumpers + bool haveRearBumpers(void) const { return myRearBumpers; } + /// Returns the number of rear bumpers + int numRearBumpers(void) const { return myNumRearBumpers; } + /// Returns the number of IRs + int getNumIR(void) const { return myNumIR; } + /// Returns if the IR of the given number is valid + bool haveIR(int number) const + { + if (myIRMap.find(number) != myIRMap.end()) + return true; + else + return false; + } + /// Returns the X location of the given numbered IR + int getIRX(int number) const + { + std::map >::const_iterator it; + std::map::const_iterator it2; + if ((it = myIRMap.find(number)) == myIRMap.end()) + return 0; + if ((it2 = (*it).second.find(IR_X)) == (*it).second.end()) + + return 0; + return (*it2).second; + } + /// Returns the Y location of the given numbered IR + int getIRY(int number) const + { + std::map >::const_iterator it; + std::map::const_iterator it2; + if ((it = myIRMap.find(number)) == myIRMap.end()) + return 0; + if ((it2 = (*it).second.find(IR_Y)) == (*it).second.end()) + return 0; + return (*it2).second; + } + int getIRType(int number) const + { + std::map >::const_iterator it; + std::map::const_iterator it2; + if ((it = myIRMap.find(number)) == myIRMap.end()) + return 0; + if ((it2 = (*it).second.find(IR_TYPE)) == (*it).second.end()) + return 0; + return (*it2).second; + } + int getIRCycles(int number) const + { + std::map >::const_iterator it; + std::map::const_iterator it2; + if ((it = myIRMap.find(number)) == myIRMap.end()) + return 0; + if ((it2 = (*it).second.find(IR_CYCLES)) == (*it).second.end()) + return 0; + return (*it2).second; + } + + /// Returns the number of sonar + int getNumSonar(void) const { return myNumSonar; } + + + /// Returns if the robot has a laser (according to param file) + /** + @deprecated + **/ + bool getLaserPossessed(void) const + { + ArLog::log(ArLog::Normal, "Something called ArRobotParams::getLaserPossessed, but this is obsolete and doesn't mean anything."); + return false; + } + + /// What type of laser this is + const char *getLaserType(int laserNumber = 1) const + { + if (getLaserData(laserNumber) != NULL) + return getLaserData(laserNumber)->myLaserType; + else + return NULL; + } + /// What type of port the laser is on + const char *getLaserPortType(int laserNumber = 1) const + { + if (getLaserData(laserNumber) != NULL) + return getLaserData(laserNumber)->myLaserPortType; + else + return NULL; + } + /// What port the laser is on + const char *getLaserPort(int laserNumber = 1) const + { + if (getLaserData(laserNumber) != NULL) + return getLaserData(laserNumber)->myLaserPort; + else + return NULL; + } + /// If the laser should be auto connected + bool getConnectLaser(int laserNumber = 1) const + { + if (getLaserData(laserNumber) != NULL) + return getLaserData(laserNumber)->myLaserAutoConnect; + else + return false; + } + /// If the laser is flipped on the robot + bool getLaserFlipped(int laserNumber = 1) const + { + if (getLaserData(laserNumber) != NULL) + return getLaserData(laserNumber)->myLaserFlipped; + else + return false; + } + /// If the laser power is controlled by the serial port lines + bool getLaserPowerControlled(int laserNumber = 1) const + { + if (getLaserData(laserNumber) != NULL) + return getLaserData(laserNumber)->myLaserPowerControlled; + else + return false; + } + /// The max range to use the laser + int getLaserMaxRange(int laserNumber = 1) const + { + if (getLaserData(laserNumber) != NULL) + return getLaserData(laserNumber)->myLaserMaxRange; + else + return 0; + } + /// The cumulative buffer size to use for the laser + int getLaserCumulativeBufferSize(int laserNumber = 1) const + { + if (getLaserData(laserNumber) != NULL) + return getLaserData(laserNumber)->myLaserCumulativeBufferSize; + else + return 0; + } + /// The X location of the laser + int getLaserX(int laserNumber = 1) const + { + if (getLaserData(laserNumber) != NULL) + return getLaserData(laserNumber)->myLaserX; + else + return 0; + } + /// The Y location of the laser + int getLaserY(int laserNumber = 1) const + { + if (getLaserData(laserNumber) != NULL) + return getLaserData(laserNumber)->myLaserY; + else + return 0; + } + /// The rotation of the laser on the robot + double getLaserTh(int laserNumber = 1) const + { + if (getLaserData(laserNumber) != NULL) + return getLaserData(laserNumber)->myLaserTh; + else + return 0; + } + /// The height of the laser off of the ground (0 means unknown) + int getLaserZ(int laserNumber = 1) const + { + if (getLaserData(laserNumber) != NULL) + return getLaserData(laserNumber)->myLaserZ; + else + return 0; + } + /// Gets the string that is the readings the laser should ignore + const char *getLaserIgnore(int laserNumber = 1) const + { + if (getLaserData(laserNumber) != NULL) + return getLaserData(laserNumber)->myLaserIgnore; + else + return NULL; + } + /// Gets the string that is the degrees the laser should start on + const char *getLaserStartDegrees(int laserNumber = 1) const + { + if (getLaserData(laserNumber) != NULL) + return getLaserData(laserNumber)->myLaserStartDegrees; + else + return NULL; + } + /// Gets the string that is the degrees the laser should end on + const char *getLaserEndDegrees(int laserNumber = 1) const + { + if (getLaserData(laserNumber) != NULL) + return getLaserData(laserNumber)->myLaserEndDegrees; + else + return NULL; + } + /// Gets the string that is choice for the number of degrees the laser should use + const char *getLaserDegreesChoice(int laserNumber = 1) const + { + if (getLaserData(laserNumber) != NULL) + return getLaserData(laserNumber)->myLaserDegreesChoice; + else + return NULL; + } + /// Gets the string that is choice for the increment the laser should use + const char *getLaserIncrement(int laserNumber = 1) const + { + if (getLaserData(laserNumber) != NULL) + return getLaserData(laserNumber)->myLaserIncrement; + else + return NULL; + } + /// Gets the string that is choice for increment the laser should use + const char *getLaserIncrementChoice(int laserNumber = 1) const + { + if (getLaserData(laserNumber) != NULL) + return getLaserData(laserNumber)->myLaserIncrementChoice; + else + return NULL; + } + /// Gets the string that is choice for units the laser should use + const char *getLaserUnitsChoice(int laserNumber = 1) const + { + if (getLaserData(laserNumber) != NULL) + return getLaserData(laserNumber)->myLaserUnitsChoice; + else + return NULL; + } + /// Gets the string that is choice for reflectorBits the laser should use + const char *getLaserReflectorBitsChoice(int laserNumber = 1) const + { + if (getLaserData(laserNumber) != NULL) + return getLaserData(laserNumber)->myLaserReflectorBitsChoice; + else + return NULL; + } + /// Gets the string that is choice for starting baud the laser should use + const char *getLaserStartingBaudChoice(int laserNumber = 1) const + { + if (getLaserData(laserNumber) != NULL) + return getLaserData(laserNumber)->myLaserStartingBaudChoice; + else + return NULL; + } + /// Gets the string that is choice for auto baud the laser should use + const char *getLaserAutoBaudChoice(int laserNumber = 1) const + { + if (getLaserData(laserNumber) != NULL) + return getLaserData(laserNumber)->myLaserAutoBaudChoice; + else + return NULL; + } + + /// Gets the name of the section the laser information is in (this + /// mostly doesn't mean anything except for commercial) + const char *getLaserSection(int laserNumber = 1) const + { + if (getLaserData(laserNumber) != NULL) + return getLaserData(laserNumber)->mySection; + else + return NULL; + } + + /// Gets which power output that turns the laser on/off + const char *getLaserPowerOutput(int laserNumber = 1) const + { + if (getLaserData(laserNumber) != NULL) + return getLaserData(laserNumber)->myLaserPowerOutput; + else + return NULL; + } + + /// PS 8/21/12 - new code to support BatteryMTX + /// What type of battery this is + const char *getBatteryMTXBoardType (int batteryNumber = 1) const + { + if (getBatteryMTXBoardData (batteryNumber) != NULL) + return getBatteryMTXBoardData (batteryNumber)->myBatteryMTXBoardType; + else + return NULL; + } + /// What type of port the battery is on + const char *getBatteryMTXBoardPortType (int batteryNumber = 1) const + { + if (getBatteryMTXBoardData (batteryNumber) != NULL) + return getBatteryMTXBoardData (batteryNumber)->myBatteryMTXBoardPortType; + else + return NULL; + } + /// What port the battery is on + const char *getBatteryMTXBoardPort (int batteryNumber = 1) const + { + if (getBatteryMTXBoardData (batteryNumber) != NULL) + return getBatteryMTXBoardData (batteryNumber)->myBatteryMTXBoardPort; + else + return NULL; + } + /// Gets the int that is the baud for the battery + int getBatteryMTXBoardBaud (int batteryNumber = 1) const + { + if (getBatteryMTXBoardData (batteryNumber) != NULL) + return getBatteryMTXBoardData (batteryNumber)->myBatteryMTXBoardBaud; + else + return 0; + } + /// Gets a bool that specifies weather to auto connect or not + bool getBatteryMTXBoardAutoConn (int batteryNumber = 1) const + { + if (getBatteryMTXBoardData (batteryNumber) != NULL) + return getBatteryMTXBoardData (batteryNumber)->myBatteryMTXBoardAutoConn; + else + return false; + } + + + /// PS 9/4/12 - new code to support LCDMTX + /// What type of LCD this is + const char *getLCDMTXBoardType (int lcdNumber = 1) const + { + if (getLCDMTXBoardData (lcdNumber) != NULL) + return getLCDMTXBoardData (lcdNumber)->myLCDMTXBoardType; + else + return NULL; + } + /// What type of port the lcd is on + const char *getLCDMTXBoardPortType (int lcdNumber = 1) const + { + if (getLCDMTXBoardData (lcdNumber) != NULL) + return getLCDMTXBoardData (lcdNumber)->myLCDMTXBoardPortType; + else + return NULL; + } + /// What port the lcd is on + const char *getLCDMTXBoardPort (int lcdNumber = 1) const + { + if (getLCDMTXBoardData (lcdNumber) != NULL) + return getLCDMTXBoardData (lcdNumber)->myLCDMTXBoardPort; + else + return NULL; + } + /// Gets the int that is the baud for the lcd + int getLCDMTXBoardBaud (int lcdNumber = 1) const + { + if (getLCDMTXBoardData (lcdNumber) != NULL) + return getLCDMTXBoardData (lcdNumber)->myLCDMTXBoardBaud; + else + return 0; + } + /// Gets a bool that specifies weather to auto connect or not + bool getLCDMTXBoardAutoConn (int lcdNumber = 1) const + { + if (getLCDMTXBoardData (lcdNumber) != NULL) + return getLCDMTXBoardData (lcdNumber)->myLCDMTXBoardAutoConn; + else + return false; + } + /// Gets a bool that specifies weather to disconnect on conn failure or not + bool getLCDMTXBoardConnFailOption (int lcdNumber = 1) const + { + if (getLCDMTXBoardData (lcdNumber) != NULL) + return getLCDMTXBoardData (lcdNumber)->myLCDMTXBoardConnFailOption; + else + return false; + } + + /// Gets which power controls this LCD + const char * getLCDMTXBoardPowerOutput (int lcdNumber = 1) const + { + if (getLCDMTXBoardData (lcdNumber) != NULL) + return getLCDMTXBoardData (lcdNumber)->myLCDMTXBoardPowerOutput; + else + return NULL; + } + + + + /// PS 8/21/12 - new code to support SonarMTX + /// What type of sonar this is + const char *getSonarMTXBoardType (int sonarNumber = 1) const + { + if (getSonarMTXBoardData (sonarNumber) != NULL) + return getSonarMTXBoardData (sonarNumber)->mySonarMTXBoardType; + else + return NULL; + } + /// What type of port the sonar is on + const char *getSonarMTXBoardPortType (int sonarNumber = 1) const + { + if (getSonarMTXBoardData (sonarNumber) != NULL) + return getSonarMTXBoardData (sonarNumber)->mySonarMTXBoardPortType; + else + return NULL; + } + /// What port the sonar is on + const char *getSonarMTXBoardPort (int sonarNumber = 1) const + { + if (getSonarMTXBoardData (sonarNumber) != NULL) + return getSonarMTXBoardData (sonarNumber)->mySonarMTXBoardPort; + else + return NULL; + } + /// Gets the int that is the baud for the sonar + int getSonarMTXBoardBaud (int sonarNumber = 1) const + { + if (getSonarMTXBoardData (sonarNumber) != NULL) + return getSonarMTXBoardData (sonarNumber)->mySonarMTXBoardBaud; + else + return 0; + } + /// Gets a bool that specifies weather to auto connect or not + bool getSonarMTXBoardAutoConn (int sonarNumber = 1) const + { + if (getSonarMTXBoardData (sonarNumber) != NULL) + return getSonarMTXBoardData (sonarNumber)->mySonarMTXBoardAutoConn; + else + return false; + } + + /// What delay the sonar board has + int getSonarMTXBoardDelay(int sonarBoardNum = 1) const + { + if (getSonarMTXBoardData(sonarBoardNum) != NULL) + return getSonarMTXBoardData(sonarBoardNum)->mySonarDelay; + else + return 0; + } + + /// What default gain the sonar board has + int getSonarMTXBoardGain(int sonarBoardNum = 1) const + { + if (getSonarMTXBoardData(sonarBoardNum) != NULL) + return getSonarMTXBoardData(sonarBoardNum)->mySonarGain; + else + return 0; + } + + /* + /// What delay the sonar has + int getSonarMTXBoardNoiseDelta(int sonarBoardNum = 1) const + { + if (getSonarMTXBoardData(sonarBoardNum) != NULL) + return getSonarMTXBoardData(sonarBoardNum)->mySonarGain; + else + return 0; + } + */ + + /// What delay the sonar has + int getSonarMTXBoardDetectionThreshold(int sonarBoardNum = 1) const + { + if (getSonarMTXBoardData(sonarBoardNum) != NULL) + return getSonarMTXBoardData(sonarBoardNum)->mySonarDetectionThreshold; + else + return 0; + } + + /// What max range the sonar has + int getSonarMTXBoardMaxRange(int sonarBoardNum = 1) const + { + if (getSonarMTXBoardData(sonarBoardNum) != NULL) + return getSonarMTXBoardData(sonarBoardNum)->mySonarMaxRange; + else + return 0; + } + + /// What autonomous driving flage the sonar has + int getSonarMTXBoardUseForAutonomousDriving(int sonarBoardNum = 1) const + { + if (getSonarMTXBoardData(sonarBoardNum) != NULL) + return getSonarMTXBoardData(sonarBoardNum)->mySonarUseForAutonomousDriving; + else + return 0; + } + + /// Gets which power output turns the sonar board on or off + const char *getSonarMTXBoardPowerOutput(int sonarBoardNum = 1) const + { + if (getSonarMTXBoardData(sonarBoardNum) != NULL) + return getSonarMTXBoardData(sonarBoardNum)->mySonarMTXBoardPowerOutput; + else + return NULL; + } + + /// get number of units (ie transducers) configured on a specific board + int getNumSonarOnMTXBoard(int sonarBoardNum = 1) const + { + + if (getSonarMTXBoardData(sonarBoardNum) != NULL) + return getSonarMTXBoardData(sonarBoardNum)->myNumSonarTransducers; + else + return 0; + } + + /// get number of units (ie transducers) configued + int getNumSonarUnits() const + { + return myNumSonarUnits; + } + + /// MPL TODO discuss boardNum here? + /// Returns if the sonar of the given number is valid + bool haveSonar(int boardNum) const + { + if (mySonarMap.find(boardNum) != mySonarMap.end()) + return true; + else + return false; + } + /// Returns the X location of the given numbered sonar disc + int getSonarX(int number) const + { + std::map >::const_iterator it; + std::map::const_iterator it2; + if ((it = mySonarMap.find(number)) == mySonarMap.end()) + return 0; + if ((it2 = (*it).second.find(SONAR_X)) == (*it).second.end()) + return 0; + return (*it2).second; + } + /// Returns the Y location of the given numbered sonar disc + int getSonarY(int number) const + { + std::map >::const_iterator it; + std::map::const_iterator it2; + if ((it = mySonarMap.find(number)) == mySonarMap.end()) + return 0; + if ((it2 = (*it).second.find(SONAR_Y)) == (*it).second.end()) + return 0; + return (*it2).second; + } + /// Returns the heading of the given numbered sonar disc + int getSonarTh(int number) const + { + std::map >::const_iterator it; + std::map::const_iterator it2; + if ((it = mySonarMap.find(number)) == mySonarMap.end()) + return 0; + if ((it2 = (*it).second.find(SONAR_TH)) == (*it).second.end()) + return 0; + return (*it2).second; + } + /// Returns the gain of the given numbered sonar disc (only + /// valid for MTX sonar) + int getSonarGain(int number) const + { + std::map >::const_iterator it; + std::map::const_iterator it2; + if ((it = mySonarMap.find(number)) == mySonarMap.end()) + return 0; + if ((it2 = (*it).second.find(SONAR_GAIN)) == (*it).second.end()) + return 0; + return (*it2).second; + } + /// Returns the noise delta of the given numbered sonar disk (only + /// valid for MTX sonar) + /* + int getSonarNoiseDelta(int number) const + { + std::map >::const_iterator it; + std::map::const_iterator it2; + if ((it = mySonarMap.find(number)) == mySonarMap.end()) + return 0; + if ((it2 = (*it).second.find(SONAR_NOISE_DELTA)) == (*it).second.end()) + return 0; + return (*it2).second; + } + */ + /// Returns the detection threshold of the given numbered sonar disc (only + /// valid for MTX sonar) + int getSonarDetectionThreshold(int number) const + { + std::map >::const_iterator it; + std::map::const_iterator it2; + if ((it = mySonarMap.find(number)) == mySonarMap.end()) + return 0; + if ((it2 = (*it).second.find(SONAR_DETECTION_THRESHOLD)) == + (*it).second.end()) + return 0; + return (*it2).second; + } + /// Returns the thres med of the given numbered sonar disc (only + /// valid for MTX sonar) + int getSonarMaxRange(int number) const + { + std::map >::const_iterator it; + std::map::const_iterator it2; + if ((it = mySonarMap.find(number)) == mySonarMap.end()) + return 0; + if ((it2 = (*it).second.find(SONAR_MAX_RANGE)) == + (*it).second.end()) + return 0; + return (*it2).second; + } + + /// Returns the useforautonomousdriving of the given numbered sonar disc (only + /// valid for MTX sonar) + int getSonarUseForAutonomousDriving(int number) const + { + std::map >::const_iterator it; + std::map::const_iterator it2; + if ((it = mySonarMap.find(number)) == mySonarMap.end()) + return 0; + if ((it2 = (*it).second.find(SONAR_USE_FOR_AUTONOMOUS_DRIVING)) == + (*it).second.end()) + return 0; + return (*it2).second; + } + + /// Returns the board a sonar is on + int getSonarMTXBoard(int number) const + { + std::map >::const_iterator it; + std::map::const_iterator it2; + if ((it = mySonarMap.find(number)) == mySonarMap.end()) + return 0; + if ((it2 = (*it).second.find(SONAR_BOARD)) == (*it).second.end()) + return 0; + return (*it2).second; + } + + /// Returns the unit on the board a sonar transducer is on + int getSonarMTXBoardUnitPosition(int number) const + { + std::map >::const_iterator it; + std::map::const_iterator it2; + if ((it = mySonarMap.find(number)) == mySonarMap.end()) + return 0; + if ((it2 = (*it).second.find(SONAR_BOARDUNITPOSITION)) == (*it).second.end()) + return 0; + return (*it2).second; + } + + + + /// Gets whether the VelMax values are settable or not + bool hasSettableVelMaxes(void) const { return mySettableVelMaxes; } + /// Gets the max trans vel from param file (0 uses microcontroller param) + int getTransVelMax(void) const { return myTransVelMax; } + /// Gets the max rot vel from param file (0 uses microcontroller param) + int getRotVelMax(void) const { return myRotVelMax; } + /// Whether the accelerations and decelerations are settable or not + bool hasSettableAccsDecs(void) const { return mySettableAccsDecs; } + /// Gets the trans accel from param file (0 uses microcontroller param) + int getTransAccel(void) const { return myTransAccel; } + /// Gets the trans decel from param file (0 uses microcontroller param) + int getTransDecel(void) const { return myTransDecel; } + /// Gets the rot accel from param file (0 uses microcontroller param) + int getRotAccel(void) const { return myRotAccel; } + /// Gets the rot decel from param file (0 uses microcontroller param) + int getRotDecel(void) const { return myRotDecel; } + /// Whether we have lateral control or not + bool hasLatVel(void) const { return myHasLatVel; } + /// Gets the max lat vel from param file (0 uses microcontroller param) + int getLatVelMax(void) const { return myTransVelMax; } + /// Gets the lat accel from param file (0 uses microcontroller param) + int getLatAccel(void) const { return myTransAccel; } + /// Gets the lat decel from param file (0 uses microcontroller param) + int getLatDecel(void) const { return myTransDecel; } + /// Saves it to the subtype.p in Aria::getDirectory/params + AREXPORT bool save(void); + + /// The X (forward-back) location of the GPS (antenna) on the robot + int getGPSX() const { return myGPSX; } + /// The Y (left-right) location of the GPS (antenna) on the robot + int getGPSY() const { return myGPSY; } + /// The Baud rate to use when connecting to the GPS + int getGPSBaud() const { return myGPSBaud; } + /// The serial port the GPS is on + const char *getGPSPort() const { return myGPSPort; } + const char *getGPSType() const { return myGPSType; } + + // The Baud rate to use when connecting to the Sonar + //int getSonarBaud() const { return mySonarBaud; } + /// The serial port the Sonar is on + //const char *getSonarPort() const { return mySonarPort; } + //const char *getSonarType() const { return mySonarType; } + + /// What kind of compass the robot has + const char *getCompassType() const { return myCompassType; } + /// Gets what port the compass is on + const char *getCompassPort() const { return myCompassPort; } + + /// For internal use only, gets a pointer to the dist conv factor value + double *internalGetDistConvFactorPointer(void) { return &myDistConvFactor; } + + /// Internal function to set if we use the default behavior + /// (shouldn't be used outside of core developers) + static void internalSetUseDefaultBehavior(bool useDefaultBehavior, + const char *owerOutputDisplayHint); + + /// Internal function to get if we use the default behavior + /// (shouldn't be used outside of core developers) + static bool internalGetUseDefaultBehavior(void); + + /// Adds things to the config for the commercial software + void internalAddToConfigCommercial(ArConfig *config); + + /// Internal call that adds to this config the same way it's always + /// been done (this is only exposed for some internal testing) + void internalAddToConfigDefault(void); + + /// return a const reference to the video device parameters + const std::vector& getVideoParams() const { return myVideoParams; } + + /// return a const reference to the PTU/PTZ parameters + const std::vector& getPTZParams() const { return myPTZParams; } + +protected: + static bool ourUseDefaultBehavior; + static std::string ourPowerOutputChoices; + + // Adds a laser to the config + AREXPORT void addLaserToConfig(int laserNumber, ArConfig *config, + bool useDefaultBehavior, + const char *section); + + // Adds a battery to the config + AREXPORT void addBatteryToConfig(int batteryNumber, ArConfig *config, + bool useDefaultBehavior); + + // Adds an LCD to the config + AREXPORT void addLCDToConfig(int lcdNumber, ArConfig *config, + bool useDefaultBehavior); + + // Adds the sonar to the config (it's added automatically for + // non-commercial) + AREXPORT void addSonarToConfigCommercial(ArConfig *config, bool isMTXSonar); + + // Processes the + AREXPORT void processSonarCommercial(ArConfig *config); + + // Adds a sonarBoard to the config + AREXPORT void addSonarBoardToConfig(int sonarBoardNumber, + ArConfig *config, + bool useDefaultBehavior); + + AREXPORT void addPTZToConfig(int i, ArConfig *config); + AREXPORT void addVideoToConfig(int i, ArConfig *config); + + // Processes the config for commercial + AREXPORT bool commercialProcessFile(void); + + char myClass[1024]; + char mySubClass[1024]; + double myRobotRadius; + double myRobotDiagonal; + double myRobotWidth; + double myRobotLength; + double myRobotLengthFront; + double myRobotLengthRear; + bool myHolonomic; + int myAbsoluteMaxRVelocity; + int myAbsoluteMaxVelocity; + bool myHaveMoveCommand; + bool myRequestIOPackets; + bool myRequestEncoderPackets; + int mySwitchToBaudRate; + double myAngleConvFactor; + double myDistConvFactor; + double myVelConvFactor; + double myRangeConvFactor; + double myDiffConvFactor; + double myVel2Divisor; + double myGyroScaler; + bool myTableSensingIR; + bool myNewTableSensingIR; + bool myFrontBumpers; + int myNumFrontBumpers; + bool myRearBumpers; + int myNumRearBumpers; + + class LaserData + { + public: + LaserData() + { + myLaserType[0] = '\0'; + myLaserPortType[0] = '\0'; + myLaserPort[0] = '\0'; + myLaserAutoConnect = false; + myLaserFlipped = false; + myLaserPowerControlled = true; + myLaserMaxRange = 0; + myLaserCumulativeBufferSize = 0; + myLaserX = 0; + myLaserY = 0; + myLaserTh = 0.0; + myLaserZ = 0; + myLaserIgnore[0] = '\0'; + myLaserStartDegrees[0] = '\0'; + myLaserEndDegrees[0] = '\0'; + myLaserDegreesChoice[0] = '\0'; + myLaserIncrement[0] = '\0'; + myLaserIncrementChoice[0] = '\0'; + myLaserUnitsChoice[0] = '\0'; + myLaserReflectorBitsChoice[0] = '\0'; + myLaserStartingBaudChoice[0] = '\0'; + myLaserAutoBaudChoice[0] = '\0'; + mySection[0] = '\0'; + myLaserPowerOutput[0] = '\0'; + } + virtual ~LaserData() {} + + char myLaserType[256]; + char myLaserPortType[256]; + char myLaserPort[256]; + bool myLaserAutoConnect; + bool myLaserFlipped; + bool myLaserPowerControlled; + unsigned int myLaserMaxRange; + unsigned int myLaserCumulativeBufferSize; + int myLaserX; + int myLaserY; + double myLaserTh; + int myLaserZ; + char myLaserIgnore[256]; + char myLaserStartDegrees[256]; + char myLaserEndDegrees[256]; + char myLaserDegreesChoice[256]; + char myLaserIncrement[256]; + char myLaserIncrementChoice[256]; + char myLaserUnitsChoice[256]; + char myLaserReflectorBitsChoice[256]; + char myLaserStartingBaudChoice[256]; + char myLaserAutoBaudChoice[256]; + char mySection[256]; + char myLaserPowerOutput[256]; + }; + std::map myLasers; + + const LaserData *getLaserData(int laserNumber) const + { + std::map::const_iterator it; + if ((it = myLasers.find(laserNumber)) != myLasers.end()) + return (*it).second; + else + return NULL; + } + + LaserData *getLaserData(int laserNumber) + { + std::map::const_iterator it; + if ((it = myLasers.find(laserNumber)) != myLasers.end()) + return (*it).second; + else + return NULL; + } + + class BatteryMTXBoardData + { + public: + BatteryMTXBoardData() + { + myBatteryMTXBoardType[0] = '\0'; + myBatteryMTXBoardPortType[0] = '\0'; + //sprintf((char *)myBatteryMTXBoardPortType, "serial"); + myBatteryMTXBoardPort[0] = '\0'; + myBatteryMTXBoardBaud = 0; + myBatteryMTXBoardAutoConn = false; + } + virtual ~BatteryMTXBoardData() {} + + char myBatteryMTXBoardType[256]; + char myBatteryMTXBoardPortType[256]; + char myBatteryMTXBoardPort[256]; + int myBatteryMTXBoardBaud; + bool myBatteryMTXBoardAutoConn; + }; + std::map myBatteryMTXBoards; + + const BatteryMTXBoardData *getBatteryMTXBoardData(int batteryBoardNum) const + { + std::map::const_iterator it; + if ((it = myBatteryMTXBoards.find(batteryBoardNum)) != myBatteryMTXBoards.end()) + return (*it).second; + else + return NULL; + } + + BatteryMTXBoardData *getBatteryMTXBoardData(int batteryBoardNum) + { + std::map::const_iterator it; + if ((it = myBatteryMTXBoards.find(batteryBoardNum)) != myBatteryMTXBoards.end()) + return (*it).second; + else + return NULL; + } + + + class LCDMTXBoardData + { + public: + LCDMTXBoardData() + { + myLCDMTXBoardType[0] = '\0'; + myLCDMTXBoardPortType[0] = '\0'; + //sprintf((char *)myLCDMTXBoardPortType, "serial"); + myLCDMTXBoardPort[0] = '\0'; + myLCDMTXBoardBaud = 0; + myLCDMTXBoardAutoConn = false; + myLCDMTXBoardConnFailOption = false; + myLCDMTXBoardPowerOutput[0] = '\0'; + } + virtual ~LCDMTXBoardData() {} + + char myLCDMTXBoardType[256]; + char myLCDMTXBoardPortType[256]; + char myLCDMTXBoardPort[256]; + int myLCDMTXBoardBaud; + bool myLCDMTXBoardAutoConn; + bool myLCDMTXBoardConnFailOption; + char myLCDMTXBoardPowerOutput[256]; + }; + std::map myLCDMTXBoards; + + const LCDMTXBoardData *getLCDMTXBoardData(int lcdBoardNum) const + { + std::map::const_iterator it; + if ((it = myLCDMTXBoards.find(lcdBoardNum)) != myLCDMTXBoards.end()) + return (*it).second; + else + return NULL; + } + + LCDMTXBoardData *getLCDMTXBoardData(int lcdBoardNum) + { + std::map::const_iterator it; + if ((it = myLCDMTXBoards.find(lcdBoardNum)) != myLCDMTXBoards.end()) + return (*it).second; + else + return NULL; + } + + + class SonarMTXBoardData + { + public: + SonarMTXBoardData() + { + mySonarMTXBoardType[0] = '\0'; + mySonarMTXBoardPortType[0] = '\0'; + mySonarMTXBoardPort[0] = '\0'; + mySonarMTXBoardBaud = 0; + mySonarMTXBoardAutoConn = false; + myNumSonarTransducers = 0; + mySonarDelay = 2; + mySonarGain = 10; + /* + mySonarNoiseDelta = 1250; + */ + mySonarDetectionThreshold = 25; + mySonarMaxRange = 255 * 17; + mySonarUseForAutonomousDriving = false; + mySonarMTXBoardPowerOutput[0] = '\0'; + } + virtual ~SonarMTXBoardData() {} + + char mySonarMTXBoardType[256]; + char mySonarMTXBoardPortType[256]; + char mySonarMTXBoardPort[256]; + int mySonarMTXBoardBaud; + bool mySonarMTXBoardAutoConn; + int myNumSonarTransducers; + int mySonarBaud; + int mySonarDelay; + int mySonarGain; + /* + int mySonarNoiseDelta; + */ + int mySonarDetectionThreshold; + int mySonarMaxRange; + bool mySonarUseForAutonomousDriving; + char mySonarMTXBoardPowerOutput[256]; + }; + std::map mySonarMTXBoards; + + const SonarMTXBoardData *getSonarMTXBoardData(int sonarBoardNum) const + { + std::map::const_iterator it; + if ((it = mySonarMTXBoards.find(sonarBoardNum)) != mySonarMTXBoards.end()) + return (*it).second; + else + return NULL; + } + + SonarMTXBoardData *getSonarMTXBoardData(int sonarBoardNum) + { + std::map::const_iterator it; + if ((it = mySonarMTXBoards.find(sonarBoardNum)) != mySonarMTXBoards.end()) + return (*it).second; + else + return NULL; + } + + bool mySettableVelMaxes; + int myTransVelMax; + int myRotVelMax; + bool mySettableAccsDecs; + int myTransAccel; + int myTransDecel; + int myRotAccel; + int myRotDecel; + + bool myHasLatVel; + int myLatVelMax; + int myLatAccel; + int myLatDecel; + int myAbsoluteMaxLatVelocity; + + + // Sonar + int mySonarBoardCount; + int myNumSonarUnits; + int myNumSonar; + std::map > mySonarMap; + enum SonarInfo + { + SONAR_X, + SONAR_Y, + SONAR_TH, + SONAR_BOARD, + SONAR_BOARDUNITPOSITION, + SONAR_GAIN, + /* + SONAR_NOISE_DELTA, + */ + SONAR_DETECTION_THRESHOLD, + SONAR_MAX_RANGE, + SONAR_USE_FOR_AUTONOMOUS_DRIVING + }; + AREXPORT void internalSetSonar(int num, int x, int y, int th); + AREXPORT bool parseSonarUnit(ArArgumentBuilder *builder); + AREXPORT bool parseMTXSonarUnit(ArArgumentBuilder *builder); + AREXPORT const std::list *getSonarUnits(void); + //AREXPORT const std::list *getMTXSonarUnits(void); + std::list myGetSonarUnitList; + ArRetFunctorC *, ArRobotParams> mySonarUnitGetFunctor; + ArRetFunctor1C mySonarUnitSetFunctor; + + + // Battery + int myBatteryMTXBoardCount; + + // LCD + int myLCDMTXBoardCount; + + // Sonar + int mySonarMTXBoardCount; + + // IRs + int myNumIR; + std::map > myIRMap; + enum IRInfo + { + IR_X, + IR_Y, + IR_TYPE, + IR_CYCLES + }; + AREXPORT void internalSetIR(int num, int type, int cycles, int x, int y); + AREXPORT bool parseIRUnit(ArArgumentBuilder *builder); + AREXPORT const std::list *getIRUnits(void); + std::list myGetIRUnitList; + ArRetFunctorC *, ArRobotParams> myIRUnitGetFunctor; + ArRetFunctor1C myIRUnitSetFunctor; + + // GPS + bool myGPSPossessed; + int myGPSX; + int myGPSY; + char myGPSPort[256]; + char myGPSType[256]; + int myGPSBaud; + + // Sonar + //char mySonarPort[256]; + //char mySonarType[256]; + //int mySonarBaud; + + // Compass + char myCompassType[256]; + char myCompassPort[256]; + + + // PTZ/PTU parameters + std::vector myPTZParams; + + // Video device parameters + std::vector myVideoParams; + + ArConfig *myCommercialConfig; + bool myCommercialAddedConnectables; + bool myCommercialProcessedSonar; + int myCommercialNumSonar; + int myCommercialMaxNumberOfLasers; + int myCommercialMaxNumberOfBatteries; + int myCommercialMaxNumberOfLCDs; + int myCommercialMaxNumberOfSonarBoards; + /// This lets us just have a straight mapping from the child + /// argument number to the sonar map above + std::map myCommercialSonarFieldMap; + + ArRetFunctorC myCommercialProcessFileCB; +}; + +#endif // ARROBOTPARAMS_H diff --git a/Legacy/Aria/include/ArRobotTypes.h b/Legacy/Aria/include/ArRobotTypes.h new file mode 100644 index 0000000..9faf14a --- /dev/null +++ b/Legacy/Aria/include/ArRobotTypes.h @@ -0,0 +1,381 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARROBOTTYPES_H +#define ARROBOTTYPES_H + + +#include "ariaUtil.h" +#include "ArRobotParams.h" + +/** @cond INCLUDE_INTERNAL_ROBOT_PARAM_CLASSES */ + +class ArRobotGeneric : public ArRobotParams +{ +public: + AREXPORT ArRobotGeneric(const char *dir=""); + AREXPORT virtual ~ArRobotGeneric() {} +}; + +class ArRobotAmigo : public ArRobotParams +{ +public: + + AREXPORT ArRobotAmigo(const char *dir=""); + AREXPORT virtual ~ArRobotAmigo() {} +}; + +class ArRobotAmigoSh : public ArRobotParams +{ +public: + + AREXPORT ArRobotAmigoSh(const char *dir=""); + AREXPORT virtual ~ArRobotAmigoSh() {} +}; + +class ArRobotP2AT : public ArRobotParams +{ +public: + AREXPORT ArRobotP2AT(const char *dir=""); + AREXPORT virtual ~ArRobotP2AT() {} +}; + +class ArRobotP2AT8 : public ArRobotParams +{ +public: + AREXPORT ArRobotP2AT8(const char *dir=""); + AREXPORT virtual ~ArRobotP2AT8() {} +}; + +class ArRobotP2AT8Plus : public ArRobotParams +{ +public: + AREXPORT ArRobotP2AT8Plus(const char *dir=""); + AREXPORT virtual ~ArRobotP2AT8Plus() {} +}; + +class ArRobotP2IT : public ArRobotParams +{ +public: + AREXPORT ArRobotP2IT(const char *dir=""); + AREXPORT virtual ~ArRobotP2IT() {} +}; + +class ArRobotP2DX : public ArRobotParams +{ +public: + AREXPORT ArRobotP2DX(const char *dir=""); + AREXPORT virtual ~ArRobotP2DX() {} +}; + +class ArRobotP2DXe : public ArRobotParams +{ +public: + AREXPORT ArRobotP2DXe(const char *dir=""); + AREXPORT virtual ~ArRobotP2DXe() {} +}; + +class ArRobotP2DF : public ArRobotParams +{ +public: + AREXPORT ArRobotP2DF(const char *dir=""); + AREXPORT virtual ~ArRobotP2DF() {} +}; + +class ArRobotP2D8 : public ArRobotParams +{ +public: + AREXPORT ArRobotP2D8(const char *dir=""); + AREXPORT virtual ~ArRobotP2D8() {} +}; + +class ArRobotP2D8Plus : public ArRobotParams +{ +public: + AREXPORT ArRobotP2D8Plus(const char *dir=""); + AREXPORT virtual ~ArRobotP2D8Plus() {} +}; + +class ArRobotP2CE : public ArRobotParams +{ +public: + AREXPORT ArRobotP2CE(const char *dir=""); + AREXPORT virtual ~ArRobotP2CE() {} +}; + +class ArRobotP2PP : public ArRobotParams +{ +public: + AREXPORT ArRobotP2PP(const char *dir=""); + AREXPORT virtual ~ArRobotP2PP() {} +}; + +class ArRobotP2PB : public ArRobotParams +{ +public: + AREXPORT ArRobotP2PB(const char *dir=""); + AREXPORT virtual ~ArRobotP2PB() {} +}; + + +class ArRobotP3AT : public ArRobotParams +{ +public: + AREXPORT ArRobotP3AT(const char *dir=""); + AREXPORT virtual ~ArRobotP3AT() {} +}; + + +class ArRobotP3DX : public ArRobotParams +{ +public: + AREXPORT ArRobotP3DX(const char *dir=""); + AREXPORT virtual ~ArRobotP3DX() {} +}; + +class ArRobotPerfPB : public ArRobotParams +{ +public: + AREXPORT ArRobotPerfPB(const char *dir=""); + AREXPORT virtual ~ArRobotPerfPB() {} +}; + +class ArRobotPerfPBPlus : public ArRobotParams +{ +public: + AREXPORT ArRobotPerfPBPlus(const char *dir=""); + AREXPORT virtual ~ArRobotPerfPBPlus() {} +}; + +class ArRobotPion1M : public ArRobotParams +{ +public: + AREXPORT ArRobotPion1M(const char *dir=""); + AREXPORT virtual ~ArRobotPion1M() {} +}; + +class ArRobotPion1X : public ArRobotParams +{ +public: + AREXPORT ArRobotPion1X(const char *dir=""); + AREXPORT virtual ~ArRobotPion1X() {} +}; + +class ArRobotPsos1M : public ArRobotParams +{ +public: + AREXPORT ArRobotPsos1M(const char *dir=""); + AREXPORT virtual ~ArRobotPsos1M() {} +}; + +class ArRobotPsos43M : public ArRobotParams +{ +public: + AREXPORT ArRobotPsos43M(const char *dir=""); + AREXPORT virtual ~ArRobotPsos43M() {} +}; + +class ArRobotPsos1X : public ArRobotParams +{ +public: + AREXPORT ArRobotPsos1X(const char *dir=""); + AREXPORT virtual ~ArRobotPsos1X() {} +}; + +class ArRobotPionAT : public ArRobotParams +{ +public: + AREXPORT ArRobotPionAT(const char *dir=""); + AREXPORT virtual ~ArRobotPionAT() {} +}; + +class ArRobotMapper : public ArRobotParams +{ +public: + AREXPORT ArRobotMapper(const char *dir=""); + AREXPORT virtual ~ArRobotMapper() {} +}; + +class ArRobotPowerBot : public ArRobotParams +{ +public: + AREXPORT ArRobotPowerBot(const char *dir=""); + AREXPORT virtual ~ArRobotPowerBot() {} +}; + +class ArRobotP3DXSH : public ArRobotParams +{ + public: + AREXPORT ArRobotP3DXSH(const char *dir=""); + AREXPORT virtual ~ArRobotP3DXSH() {} +}; + +class ArRobotP3ATSH : public ArRobotParams +{ + public: + AREXPORT ArRobotP3ATSH(const char *dir=""); + AREXPORT virtual ~ArRobotP3ATSH() {} +}; + +class ArRobotP3ATIWSH : public ArRobotParams +{ + public: + AREXPORT ArRobotP3ATIWSH(const char *dir=""); + AREXPORT virtual ~ArRobotP3ATIWSH() {} +}; + +class ArRobotPatrolBotSH : public ArRobotParams +{ + public: + AREXPORT ArRobotPatrolBotSH(const char *dir=""); + AREXPORT virtual ~ArRobotPatrolBotSH() {} +}; + +class ArRobotPeopleBotSH : public ArRobotParams +{ + public: + AREXPORT ArRobotPeopleBotSH(const char *dir=""); + AREXPORT virtual ~ArRobotPeopleBotSH() {} +}; + +class ArRobotPowerBotSH : public ArRobotParams +{ + public: + AREXPORT ArRobotPowerBotSH(const char *dir=""); + AREXPORT virtual ~ArRobotPowerBotSH() {} +}; + +class ArRobotWheelchairSH : public ArRobotParams +{ + public: + AREXPORT ArRobotWheelchairSH(const char *dir=""); + AREXPORT virtual ~ArRobotWheelchairSH() {} +}; + +class ArRobotPowerBotSHuARCS : public ArRobotParams +{ + public: + AREXPORT ArRobotPowerBotSHuARCS(const char *dir=""); + AREXPORT virtual ~ArRobotPowerBotSHuARCS() {} +}; + +class ArRobotSeekur : public ArRobotParams +{ + public: + AREXPORT ArRobotSeekur(const char *dir=""); + AREXPORT virtual ~ArRobotSeekur() {} +}; + +/// @since Aria 2.7.2 +class ArRobotMT400 : public ArRobotParams +{ + public: + AREXPORT ArRobotMT400(const char *dir=""); + AREXPORT virtual ~ArRobotMT400() {} +}; + +/// @since Aria 2.7.2 +class ArRobotResearchPB : public ArRobotParams +{ + public: + AREXPORT ArRobotResearchPB(const char *dir=""); + AREXPORT virtual ~ArRobotResearchPB() {} +}; + +/// @since Aria 2.7.2 +class ArRobotSeekurJr : public ArRobotParams +{ + public: + AREXPORT ArRobotSeekurJr(const char *dir=""); + AREXPORT virtual ~ArRobotSeekurJr() {} +}; + +/// @since Aria 2.7.4 +class ArRobotP3DXSH_lms1xx : public ArRobotP3DXSH +{ +public: + AREXPORT ArRobotP3DXSH_lms1xx(const char *dir=""); +}; + +/// @since Aria 2.7.4 +class ArRobotP3ATSH_lms1xx : public ArRobotP3ATSH +{ +public: + AREXPORT ArRobotP3ATSH_lms1xx(const char *dir=""); +}; + +/// @since Aria 2.7.4 +class ArRobotPeopleBotSH_lms1xx : public ArRobotPeopleBotSH +{ +public: + AREXPORT ArRobotPeopleBotSH_lms1xx(const char *dir=""); +}; + +/// @since Aria 2.7.4 +class ArRobotP3DXSH_lms500 : public ArRobotP3DXSH +{ +public: + AREXPORT ArRobotP3DXSH_lms500(const char *dir=""); +}; + +/// @since Aria 2.7.4 +class ArRobotP3ATSH_lms500 : public ArRobotP3ATSH +{ +public: + AREXPORT ArRobotP3ATSH_lms500(const char *dir=""); +}; + +/// @since Aria 2.7.4 +class ArRobotPeopleBotSH_lms500 : public ArRobotPeopleBotSH +{ +public: + AREXPORT ArRobotPeopleBotSH_lms500(const char *dir=""); +}; + +/// @since Aria 2.7.4 +class ArRobotPowerBotSH_lms500 : public ArRobotPowerBotSH +{ +public: + AREXPORT ArRobotPowerBotSH_lms500(const char *dir=""); +}; + +/// @since Aria 2.7.4 +class ArRobotResearchPB_lms500 : public ArRobotResearchPB +{ +public: + AREXPORT ArRobotResearchPB_lms500(const char *dir=""); +}; + +/// @since Aria 2.8 +class ArRobotPioneerLX : public ArRobotParams +{ +public: + AREXPORT ArRobotPioneerLX(const char *dir=""); + AREXPORT virtual ~ArRobotPioneerLX() {} +}; + +/** @endcond INCLUDE_INTERNAL_ROBOT_PARAM_CLASSES */ + +#endif // ARROBOTTYPES_H diff --git a/Legacy/Aria/include/ArS3Series.h b/Legacy/Aria/include/ArS3Series.h new file mode 100644 index 0000000..24e8ac2 --- /dev/null +++ b/Legacy/Aria/include/ArS3Series.h @@ -0,0 +1,250 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARS3SERIES_H +#define ARS3SERIES_H + +#include "ariaTypedefs.h" +#include "ariaOSDef.h" +#include "ArRobotPacket.h" +#include "ArLaser.h" +#include "ArFunctor.h" + +/** @internal */ +class ArS3SeriesPacket : public ArBasePacket +{ +public: + /// Constructor + AREXPORT ArS3SeriesPacket(); + /// Destructor + AREXPORT virtual ~ArS3SeriesPacket(); + + /// Gets the time the packet was received at + AREXPORT ArTime getTimeReceived(void); + /// Sets the time the packet was received at + AREXPORT void setTimeReceived(ArTime timeReceived); + + AREXPORT virtual void duplicatePacket(ArS3SeriesPacket *packet); + AREXPORT virtual void empty(void); + + + void setDataLength(int x) + { myDataLength = x; } + int getDataLength() + { return myDataLength; } + void setNumReadings(int x) + { myNumReadings = x; } + int getNumReadings() + { return myNumReadings; } + void setStatusByte(unsigned char c) + { myStatusByte = c; } + unsigned char getStatusByte() + { return myStatusByte; } + void setTimeStampByte1(unsigned char c) + { myTimeStampByte1 = c; } + unsigned char getTimeStampByte1() + { return myTimeStampByte1; } + void setTimeStampByte2(unsigned char c) + { myTimeStampByte2 = c; } + unsigned char getTimeStampByte2() + { return myTimeStampByte2; } + void setTimeStampByte3(unsigned char c) + { myTimeStampByte3 = c; } + unsigned char getTimeStampByte3() + { return myTimeStampByte3; } + void setTimeStampByte4(unsigned char c) + { myTimeStampByte4 = c; } + unsigned char getTimeStampByte4() + { return myTimeStampByte4; } + unsigned char getTelegramNumByte1() + { return myTelegramNumByte1; } + unsigned char getTelegramNumByte2() + { return myTelegramNumByte2; } + void setTelegramNumByte2(unsigned char c) + { myTelegramNumByte2 = c; } + void setTelegramNumByte1(unsigned char c) + { myTelegramNumByte1 = c; } + unsigned char getCrcByte1() + { return myCrcByte1; } + void setCrcByte1(unsigned char c) + { myCrcByte1 = c; } + unsigned char getCrcByte2() + { return myCrcByte2; } + void setCrcByte2(unsigned char c) + { myCrcByte2 = c; } + unsigned char getMonitoringDataByte1() + { return myMonitoringDataByte1; } + void setMonitoringDataByte1(unsigned char c) + { myMonitoringDataByte1 = c; } + unsigned char getMonitoringDataByte2() + { return myMonitoringDataByte2; } + void setMonitoringDataByte2(unsigned char c) + { myMonitoringDataByte2 = c; } + bool getMonitoringDataAvailable() + { return myMonitoringDataAvailable; } + void setMonitoringDataAvailable(bool c) + { myMonitoringDataAvailable = c; } + unsigned char getProtocolVersionByte1() + { return myProtocolVersionByte1; } + void setProtocolVersionByte1(unsigned char c) + { myProtocolVersionByte1 = c; } + unsigned char getProtocolVersionByte2() + { return myProtocolVersionByte2; } + void setProtocolVersionByte2(unsigned char c) + { myProtocolVersionByte2 = c; } + +protected: + + ArTime myTimeReceived; + + // S3S specific + int myDataLength; + int myNumReadings; + unsigned char myStatusByte; + unsigned char myTimeStampByte1; + unsigned char myTimeStampByte2; + unsigned char myTimeStampByte3; + unsigned char myTimeStampByte4; + unsigned char myTelegramNumByte1; + unsigned char myTelegramNumByte2; + unsigned char myCrcByte1; + unsigned char myCrcByte2; + bool myMonitoringDataAvailable; + unsigned char myMonitoringDataByte1; + unsigned char myMonitoringDataByte2; + unsigned char myProtocolVersionByte1; + unsigned char myProtocolVersionByte2; + +}; + + +/// Given a device connection it receives packets from the sick through it +/// @internal +class ArS3SeriesPacketReceiver +{ +public: + /// Constructor with assignment of a device connection + AREXPORT ArS3SeriesPacketReceiver(); + /// Destructor + AREXPORT virtual ~ArS3SeriesPacketReceiver(); + + /// Receives a packet from the robot if there is one available + AREXPORT ArS3SeriesPacket *receivePacket(unsigned int msWait = 0, + bool shortcut = false); + + /// Sets the device this instance receives packets from + AREXPORT void setDeviceConnection(ArDeviceConnection *conn); + /// Gets the device this instance receives packets from + AREXPORT ArDeviceConnection *getDeviceConnection(void); + unsigned short CRC16(unsigned char *, int); + + // PS - added to pass info to this class + AREXPORT void setInfoLogLevel(ArLog::LogLevel infoLogLevel) + { myInfoLogLevel = infoLogLevel; } + AREXPORT void setIsS300(bool isS300) + { myIsS300 = isS300; } + AREXPORT void setName(const char *name ) + { strcpy(myName, name); } + +protected: + ArDeviceConnection *myConn; + ArS3SeriesPacket myPacket; + + char myName[1024]; + unsigned int myNameLength; + unsigned char myReadBuf[100000]; + int myReadCount; + bool myIsS300; + ArLog::LogLevel myInfoLogLevel; + + + +}; + +/** + @since Aria 2.7.4 + @see ArLaserConnector + Use ArLaserConnector to connect to a laser, determining type based on robot and program configuration parameters. +*/ +class ArS3Series : public ArLaser +{ +public: + /// Constructor + AREXPORT ArS3Series(int laserNumber, + const char *name = "S3Series"); + /// Destructor + AREXPORT ~ArS3Series(); + AREXPORT virtual bool blockingConnect(void); + AREXPORT virtual bool asyncConnect(void); + AREXPORT virtual bool disconnect(void); + virtual bool isConnected(void) { return myIsConnected; } + virtual bool isTryingToConnect(void) + { + if (myStartConnect) + return true; + else if (myTryingToConnect) + return true; + else + return false; + } + AREXPORT bool isMonitoringDataAvailable(void) + { return myIsMonitoringDataAvailable; } + AREXPORT int getMonitoringData(void) + { return myMonitoringData; } + AREXPORT bool compareMonitoringDataAgainst(int val) + { return myMonitoringData == val; } + + /// Logs the information about the sensor + AREXPORT void log(void); +protected: + AREXPORT virtual void laserSetName(const char *name); + AREXPORT virtual void * runThread(void *arg); + AREXPORT virtual void setRobot(ArRobot *robot); + void sensorInterp(void); + void failedToConnect(void); + void clear(void); + bool myIsConnected; + bool myTryingToConnect; + bool myStartConnect; + + int myNumChans; + + bool myIsMonitoringDataAvailable; + int myMonitoringData; + + ArLog::LogLevel myLogLevel; + + ArS3SeriesPacketReceiver myReceiver; + + ArMutex myPacketsMutex; + ArMutex myDataMutex; + + std::list myPackets; + + ArFunctorC mySensorInterpTask; + ArRetFunctorC myAriaExitCB; +}; + +#endif diff --git a/Legacy/Aria/include/ArSZSeries.h b/Legacy/Aria/include/ArSZSeries.h new file mode 100644 index 0000000..f5ee3cf --- /dev/null +++ b/Legacy/Aria/include/ArSZSeries.h @@ -0,0 +1,204 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARSZSERIES_H +#define ARSZSERIES_H + +#include "ariaTypedefs.h" +#include "ariaOSDef.h" +#include "ArRobotPacket.h" +#include "ArLaser.h" +#include "ArFunctor.h" + +/** @internal */ +class ArSZSeriesPacket : public ArBasePacket +{ +public: + /// Constructor + AREXPORT ArSZSeriesPacket(); + /// Destructor + AREXPORT virtual ~ArSZSeriesPacket(); + + /// Gets the time the packet was received at + AREXPORT ArTime getTimeReceived(void); + /// Sets the time the packet was received at + AREXPORT void setTimeReceived(ArTime timeReceived); + + AREXPORT virtual void duplicatePacket(ArSZSeriesPacket *packet); + AREXPORT virtual void empty(void); + + AREXPORT virtual void byteToBuf(ArTypes::Byte val); + + AREXPORT virtual ArTypes::Byte bufToByte(void); + + void setDataLength(int x) + { myDataLength = x; } + int getDataLength() + { return myDataLength; } + void setNumReadings(int x) + { myNumReadings = x; } + int getNumReadings() + { return myNumReadings; } + void setScanFrequency(int x) + { myScanFrequency = x; } + int getScanFrequency() + { return myScanFrequency; } + + void setPrevScanFrequency(int x) + { myPrevScanFrequency = x; } + int getPrevScanFrequency() + { return myPrevScanFrequency; } + + + unsigned char getCrcByte1() + { return myCrcByte1; } + void setCrcByte1(unsigned char c) + { myCrcByte1 = c; } + unsigned char getCrcByte2() + { return myCrcByte2; } + void setCrcByte2(unsigned char c) + { myCrcByte2 = c; } + +protected: + int deascii(char c); + + ArTime myTimeReceived; + + // SZS specific + int myDataLength; + int myNumReadings; + int myScanFrequency; + unsigned char myCrcByte1; + unsigned char myCrcByte2; + + int myPrevScanFrequency; + + +}; + + +/// Given a device connection it receives packets from the sick through it +/// @internal +class ArSZSeriesPacketReceiver +{ +public: + /// Constructor with assignment of a device connection + AREXPORT ArSZSeriesPacketReceiver(); + /// Destructor + AREXPORT virtual ~ArSZSeriesPacketReceiver(); + + /// Receives a packet from the robot if there is one available + AREXPORT ArSZSeriesPacket *receivePacket(unsigned int msWait = 0, + bool shortcut = false); + + /// Sets the device this instance receives packets from + AREXPORT void setDeviceConnection(ArDeviceConnection *conn); + /// Gets the device this instance receives packets from + AREXPORT ArDeviceConnection *getDeviceConnection(void); + unsigned short CRC16(unsigned char *, int); + + // PS - added to pass info to this class + AREXPORT void setmyInfoLogLevel(ArLog::LogLevel infoLogLevel) + { myInfoLogLevel = infoLogLevel; } + AREXPORT void setmyIsSZ00(bool isSZ00) + { myIsSZ00 = isSZ00; } + AREXPORT void setmyName(const char *name ) + { strcpy(myName, name); } + +protected: + ArDeviceConnection *myConn; + ArSZSeriesPacket myPacket; + + char myName[1024]; + unsigned int myNameLength; + unsigned char myReadBuf[100000]; + int myReadCount; + bool myIsSZ00; + ArLog::LogLevel myInfoLogLevel; + + unsigned short myPrevCrc; + + +}; + +/** + @since Aria 2.7.4 + @see ArLaserConnector + Use ArLaserConnector to connect to a laser, determining type based on robot and program configuration parameters. +*/ +class ArSZSeries : public ArLaser +{ +public: + /// Constructor + AREXPORT ArSZSeries(int laserNumber, + const char *name = "SZSeries"); + /// Destructor + AREXPORT ~ArSZSeries(); + AREXPORT virtual bool blockingConnect(void); + AREXPORT virtual bool asyncConnect(void); + AREXPORT virtual bool disconnect(void); + virtual bool isConnected(void) { return myIsConnected; } + virtual bool isTryingToConnect(void) + { + if (myStartConnect) + return true; + else if (myTryingToConnect) + return true; + else + return false; + } + + /// Logs the information about the sensor + AREXPORT void log(void); +protected: + AREXPORT virtual void laserSetName(const char *name); + AREXPORT virtual void * runThread(void *arg); + AREXPORT virtual void setRobot(ArRobot *robot); + void sensorInterp(void); + void failedToConnect(void); + void clear(void); + bool myIsConnected; + bool myTryingToConnect; + bool myStartConnect; + + int myNumChans; + + + ArLog::LogLevel myLogLevel; + + ArSZSeriesPacketReceiver myReceiver; + + ArMutex myPacketsMutex; + ArMutex myDataMutex; + + std::list myPackets; + + ArTime myPrevSensorIntTime; + + ArFunctorC mySensorInterpTask; + ArRetFunctorC myAriaExitCB; +}; + +#endif diff --git a/Legacy/Aria/include/ArSensorReading.h b/Legacy/Aria/include/ArSensorReading.h new file mode 100644 index 0000000..011d719 --- /dev/null +++ b/Legacy/Aria/include/ArSensorReading.h @@ -0,0 +1,213 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARSENSORREADING_H +#define ARSENSORREADING_H + +#include "ariaTypedefs.h" +#include "ariaUtil.h" +#include "ArTransform.h" + +/// A class to hold a sensor reading, should be one instance per sensor +/** This class holds sensor data and a sensor reading... it can happen + that it contains the data for a sonar, but not the reading, in + which case the range (from getRange) will be -1, and the counter + it was taken (from getCounterTaken) will be 0, also it will never + be new (from isNew). If ignoreThisReading returns true then + ignore this reading (its still here since this is used for raw + data). +*/ +class ArSensorReading +{ +public: + /// Constructor, the three args are the physical location of the sensor + AREXPORT ArSensorReading(double xPos = 0.0, double yPos = 0.0, double thPos = 0.0); + /// Copy constructor + AREXPORT ArSensorReading(const ArSensorReading & reading); + /// Assignment operator + AREXPORT ArSensorReading &operator=(const ArSensorReading &reading); + /// Destructor + AREXPORT virtual ~ArSensorReading(); + + /// Gets the range from sensor of the reading + /** + @return the distance to the reading from the sensor itself + */ + unsigned int getRange(void) const { return myRange; } + + /// Given the counter from the robot, it returns whether the reading is new + /** + @param counter the counter from the robot at the current time + @return true if the reading was taken on the current loop + @see getCounter + */ + bool isNew(unsigned int counter) const { return counter == myCounterTaken; } + /// Gets the X location of the sensor reading + double getX(void) const { return myReading.getX(); } + /// Gets the Y location of the sensor reading + double getY(void) const { return myReading.getY(); } + /// Gets the position of the reading + /// @return the position of the reading (ie where the sonar pinged back) + ArPose getPose(void) const { return myReading; } + + /// Gets the X location of the sensor reading in local coords + double getLocalX(void) const { return myLocalReading.getX(); } + /// Gets the Y location of the sensor reading + double getLocalY(void) const { return myLocalReading.getY(); } + /// Gets the position of the reading + /// @return the position of the reading (ie the obstacle where the sonar pinged back) + ArPose getLocalPose(void) const { return myLocalReading; } + + /** Gets the pose of the robot at which the reading was taken + @sa getEncoderPoseTaken() + @sa getTimeTaken() + @sa ArRobot::getPose() + */ + ArPose getPoseTaken(void) const { return myReadingTaken; } + + /** Gets the robot's encoder pose the reading was taken at + @sa getPoseTaken() + @sa ArRobot::getEncoderPose() + */ + ArPose getEncoderPoseTaken(void) const { return myEncoderPoseTaken; } + + /** Gets the X location of the sonar on the robot + @sa getSensorPosition() + */ + double getSensorX(void) const { return mySensorPos.getX(); } + /** Gets the Y location of the sensor on the robot + @sa getsensorPosition() + */ + double getSensorY(void) const { return mySensorPos.getY(); } + /** Gets the heading of the sensor on the robot + @sa getsensorPosition() + */ + double getSensorTh(void) const { return mySensorPos.getTh(); } + + /// Gets whether this reading should be ignore or not. e.g. the sensor + /// encountered an error or did not actually detect anything. + bool getIgnoreThisReading(void) const { return myIgnoreThisReading; } + + /// Gets the extra int with this reading + /** + Some range devices provide extra device-dependent information + with each reading. What that means depends on the range device, + if a range device doesn't give the meaning in its constructor + description then it has no meaning at all. + + Note that for all laser like devices this should be a value + between 0 - 255 which is the measure of reflectance. It should + be 0 if that device doesn't measure reflectance (the default). + **/ + int getExtraInt(void) const { return myExtraInt; } + + + /// Gets the sensor's position on the robot + /** + @return the position of the sensor on the robot + */ + ArPose getSensorPosition(void) const { return mySensorPos; } + + /// Gets the cosine component of the heading of the sensor reading + double getSensorDX(void) const { return mySensorCos; } + /// Gets the sine component of the heading of the sensor reading + double getSensorDY(void) const { return mySensorSin; } + + /** Gets the X locaiton of the robot when the reading was received + @sa getPoseTaken() + */ + double getXTaken(void) const { return myReadingTaken.getX(); } + /** Gets the Y location of the robot when the reading was received + @sa getPoseTaken() + */ + double getYTaken(void) const { return myReadingTaken.getY(); } + /** Gets the th (heading) of the robot when the reading was received + @sa getPoseTaken() + */ + double getThTaken(void) const { return myReadingTaken.getTh(); } + + /// Gets the counter from when the reading arrived + /** + @return the counter from the robot when the sonar reading was taken + @see isNew + */ + unsigned int getCounterTaken(void) const { return myCounterTaken; } + + ArTime getTimeTaken(void) const { return myTimeTaken; } + + /// Takes the data and makes the reading reflect it + AREXPORT void newData(int range, ArPose robotPose, ArPose encoderPose, + ArTransform trans, unsigned int counter, + ArTime timeTaken, bool ignoreThisReading = false, + int extraInt = 0); + + /// Takes the data and makes the reading reflect it + AREXPORT void newData(int sx, int sy, ArPose robotPose, + ArPose encoderPose, + ArTransform trans, + unsigned int counter, + ArTime timeTaken, + bool ignoreThisReading = false, + int extraInt = 0); + + /// Resets the sensors idea of its physical location on the robot + AREXPORT void resetSensorPosition(double xPos, double yPos, double thPos, + bool forceComputation = false); + + /// Sets that we should ignore this reading + AREXPORT void setIgnoreThisReading(bool ignoreThisReading) + { myIgnoreThisReading = ignoreThisReading; } + + /// Sets the extra int + AREXPORT void setExtraInt(int extraInt) + { myExtraInt = extraInt; } + + + /// Applies a transform to the reading position, and where it was taken + AREXPORT void applyTransform(ArTransform trans); + /// Applies a transform to the encoder pose taken + AREXPORT void applyEncoderTransform(ArTransform trans); + /// Applies a transform to the reading position, and where it was taken + AREXPORT bool getAdjusted(void) { return myAdjusted; } + /// Applies a transform to the reading position, and where it was taken + AREXPORT void setAdjusted(bool adjusted) { myAdjusted = adjusted; } +protected: + unsigned int myCounterTaken; + ArPose myReading; + ArPose myLocalReading; + ArPose myReadingTaken; + ArPose myEncoderPoseTaken; + ArPose mySensorPos; + double mySensorCos, mySensorSin; + double myDistToCenter; + double myAngleToCenter; + int myRange; + ArTime myTimeTaken; + bool myIgnoreThisReading; + int myExtraInt; + bool myAdjusted; +}; + +#endif diff --git a/Legacy/Aria/include/ArSerialConnection.h b/Legacy/Aria/include/ArSerialConnection.h new file mode 100644 index 0000000..cbe0bec --- /dev/null +++ b/Legacy/Aria/include/ArSerialConnection.h @@ -0,0 +1,141 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARSERIALCONNECTION_H +#define ARSERIALCONNECTION_H + +#include +#include "ariaTypedefs.h" +#include "ArDeviceConnection.h" + +/// Utility for connecting to and communicating with devices through a serial port +/** @ingroup UtilityClasses + @ingroup DeviceClasses +*/ +class ArSerialConnection: public ArDeviceConnection +{ + public: + /// Constructor + AREXPORT ArSerialConnection(bool is422 = false); + /// Destructor also closes the connection + AREXPORT virtual ~ArSerialConnection(); + + /** Opens the serial port + * @return 0 on success. Return one of the error codes in the + * ArSerialConnection::Open enumeration on error. + * @sa ArUtil::COM1, ArUtil::COM2, ArUtil::COM3, ArUtil::COM4 + */ + AREXPORT int open(const char * port = NULL); + + /** Sets the port this connection will use + * @sa ArUtil::COM1, ArUtil::COM2, ArUtil::COM3, ArUtil::COM4 + */ + AREXPORT void setPort(const char *port = NULL); + + /** Gets the port this is using + * @sa ArUtil::COM1, ArUtil::COM2, ArUtil::COM3, ArUtil::COM4 + */ + AREXPORT const char * getPort(void); + + AREXPORT virtual bool openSimple(void); + AREXPORT virtual int getStatus(void); + AREXPORT virtual bool close(void); + AREXPORT virtual int read(const char *data, unsigned int size, + unsigned int msWait = 0); + AREXPORT virtual int write(const char *data, unsigned int size); + AREXPORT virtual const char * getOpenMessage(int messageNumber); + + /** + Sets the BAUD rate to use when connection is opened, or change the baud rate if already opened + @param baud the baud rate to set the connection to + @return true if rate was sucessfully set, false otherwise (unsupported rate, system error changing rate on port, etc.) + @sa getBaud() + */ + AREXPORT bool setBaud(int baud); + /// Gets what the current baud rate is set to + AREXPORT int getBaud(void); + + /// Sets whether to enable or disable the hardware control lines + AREXPORT bool setHardwareControl(bool hardwareControl); + /// Gets whether the hardware control lines are enabled or disabled + AREXPORT bool getHardwareControl(void); + + /// Sees how the CTS line is set (true = high) + AREXPORT bool getCTS(void); + + /// Sees how the DSR line is set (true = high) + AREXPORT bool getDSR(void); + + /// Sees how the DCD line is set (true = high) + AREXPORT bool getDCD(void); + + /// Sees how the Ring line is set (true = high) + AREXPORT bool getRing(void); + + // Internal open, for use by open and openSimple + AREXPORT int internalOpen(void); + + enum Open { + OPEN_COULD_NOT_OPEN_PORT = 1, ///< Could not open the port + OPEN_COULD_NOT_SET_UP_PORT, ///< Could not set up the port + OPEN_INVALID_BAUD_RATE, ///< Baud rate is not valid + OPEN_COULD_NOT_SET_BAUD, ///< Baud rate valid, but could not set it + OPEN_ALREADY_OPEN ///< Connection was already open + }; + AREXPORT virtual ArTime getTimeRead(int index); + AREXPORT virtual bool isTimeStamping(void); + + protected: + void buildStrMap(void); + +#ifndef WIN32 + // these both return -1 for errors + int rateToBaud(int rate); + int baudToRate(int baud); + // this just tries + void startTimeStamping(void); + bool myTakingTimeStamps; +#endif + + ArStrMap myStrMap; + std::string myPortName; + int myBaudRate; + int myStatus; + bool myHardwareControl; + +#ifndef WIN32 + int myPort; +#endif // ifdef linux + + bool myIs422; + +#ifdef WIN32 + HANDLE myPort; +#endif // ifdef WIN32 + + +}; + +#endif diff --git a/Legacy/Aria/include/ArSick.h b/Legacy/Aria/include/ArSick.h new file mode 100644 index 0000000..3cbbfba --- /dev/null +++ b/Legacy/Aria/include/ArSick.h @@ -0,0 +1,340 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARSICK_H +#define ARSICK_H + +#include "ariaTypedefs.h" +#include "ArRobotPacket.h" +#include "ArLaser.h" +#include "ArFunctor.h" +#include "ArCondition.h" +#include "ArLMS2xx.h" + + +/** +Compatability class used to access SICK LMS-200 laser rangefinder device in +versions of ARIA prior to 2.7.0; used alone or with ArSimpleConnector (also +deprecated). In 2.7.0 and later, ArSick implements the same +API as in previous versions, but serves only as an interface to ArLMS2xx; the +preferred way to access laser rangefinders is to first connect to a robot using +ArRobotConnector to load robot parameter files specifying laser types +and options, then use ArLaserConnector to connect to all lasers the robot has. +ArRobot stores a list of ArLaser objects for these lasers. +@deprecated +*/ +class ArSick : public ArLMS2xx +{ +public: + /// Constructor + AREXPORT ArSick(size_t currentBufferSize = 361, + size_t cumulativeBufferSize = 0, + const char *name = "laser", + bool addAriaExitCB = true, + bool isSecondLaser = false); + /// Destructor + AREXPORT virtual ~ArSick(); + + enum BaudRate { + BAUD9600, ///< 9600 Baud + BAUD19200, ///< 19200 Baud + BAUD38400, ///< 38400 Baud + BAUD_INVALID ///< Invalid baud + }; + enum Degrees { + DEGREES180, ///< 180 Degrees + DEGREES100, ///< 100 Degrees + DEGREES_INVALID ///< Invalid degrees + }; + enum Increment { + INCREMENT_ONE, ///< One degree increments + INCREMENT_HALF, ///< Half a degree increments + INCREMENT_INVALID ///< Increment invalid + }; + enum Units { + UNITS_1MM, ///< Uses 1 mm resolution (8/16/32 meter max range) + UNITS_1CM, ///< Uses 1 cm resolution (80/160/320 meter max range) + UNITS_10CM, ///< Uses 10 cm resolution (150 meter max range) + UNITS_INVALID ///< Invalid units + }; + enum Bits { + BITS_1REFLECTOR, ///< Uses 1 reflector bits (means 32/320/150 meter range) + BITS_2REFLECTOR, ///< Uses 2 reflector bits (means 16/160/150 meter range) + BITS_3REFLECTOR, ///< Uses 3 reflector bits (means 8/80/150 meter range) + BITS_INVALID ///< Invalid bits + }; + + /// Sees if this is trying to connect to the laser at the moment (note no other range devices work like this so you probably shouldn't use this) + bool tryingToConnect(void) + { return isTryingToConnect(); } + + /// Runs the laser off of the robot + bool runOnRobot(void) { return internalRunOnRobot(); } + + + /// Use this to manually configure the laser before connecting to it + AREXPORT void configure(bool useSim = false, bool powerControl = true, + bool laserFlipped = false, + BaudRate baud = BAUD38400, + Degrees deg = DEGREES180, + Increment incr = INCREMENT_ONE); + /// Shorter configure for the laser (settings are overridden by the .p file) + AREXPORT void configureShort(bool useSim = false, + BaudRate baud = BAUD38400, + Degrees deg = DEGREES180, + Increment incr = INCREMENT_ONE); + /// Sets the ranging/reflector information + AREXPORT void setRangeInformation(Bits bits = BITS_1REFLECTOR, + Units units = UNITS_1MM); + + + // Gets whether the laser is simulated or not + AREXPORT bool isUsingSim(void); + /// Gets whether the computer is controling laser power or not + AREXPORT bool isControllingPower(void); + /// Gets whether the laser is flipped over or not + AREXPORT bool isLaserFlipped(void); + /// Gets the degrees the laser is scanning + AREXPORT Degrees getDegrees(void); +#ifndef SWIG + // this ends up causing problems in the Java wrapper, since it has the + // wrong return type vs. ArLaser::getIncrement(). But we need to keep + // this function for backwards compatability. + /// Gets the amount each scan increments + AREXPORT Increment getIncrement(void); +#endif + /// Gets the Bits the laser is using + AREXPORT Bits getBits(void); + /// Gets the Units the laser is using + AREXPORT Units getUnits(void); + + // Sets whether the laser is simulated or not + AREXPORT void setIsUsingSim(bool usingSim); + /// Sets whether the computer is controling laser power or not + AREXPORT void setIsControllingPower(bool controlPower); + /// Sets whether the laser is flipped over or not + AREXPORT void setIsLaserFlipped(bool laserFlipped); + + + + /** You should use setCumulativeCleanDist for this now + @deprecated + */ + void setFilterCumulativeCleanDist(double dist) + { + setCumulativeCleanDist(dist); + } + /** You should use getCumulativeCleanDist for this now + @deprecated + */ + double getFilterCumulativeCleanDist(void) + { + return getCumulativeCleanDist(); + } + /** You should use setCumulativeCleanInterval for this now + @deprecated + */ + void setFilterCleanCumulativeInterval(int milliSeconds) + { + setCumulativeCleanInterval(milliSeconds); + } + /** You should use getPlanarCumulativeCleanInterval for this now + @deprecated + */ + int getFilterCleanCumulativeInterval(void) + { + return getCumulativeCleanInterval(); + } + + /** You should use setMinDistBetweenCumulative for this now + @deprecated + */ + void setFilterCumulativeNearDist(double dist) + { + setMinDistBetweenCumulative(dist); + } + /** You should use getMinDistBetweenCumulative for this now + @deprecated + */ + double getFilterCumulativeNearDist(void) + { return getMinDistBetweenCumulative(); } + + /** You should use setMinDistBetweenCurrent for this now + @deprecated + */ + void setFilterNearDist(double dist) + { setMinDistBetweenCurrent(dist); } + /** You should use getMinDistBetweenCurrent for this now + @deprecated + */ + double getFilterNearDist(void) + { return getMinDistBetweenCurrent(); } + + /** + You should use setMaxInsertDistCumulative for this now + @deprecated + */ + void setFilterCumulativeInsertMaxDist(double dist) + { setMaxInsertDistCumulative(dist); } + /** + You should use getMaxInsertDistCumulative for this now + @deprecated + */ + double getFilterCumulativeInsertMaxDist(void) + { return getMaxInsertDistCumulative(); } + + /** Used to set the min range, this is no longer used because it + doesn't actually solve anything (because beams that see near + things and far things average) + @deprecated + **/ + unsigned int getMinRange(void) { return 0; } + /** Used to get the min range, this is no longer used because it + doesn't actually solve anything (because beams that see near + things and far things average) + @deprecated + **/ + void setMinRange(unsigned int minRange) { } + + /** You should see setMaxDistToKeepCumulative (it replaces this) + @deprecated + */ + void setFilterCumulativeMaxDist(double dist) + { setMaxDistToKeepCumulative(dist); } + /** You should see getMaxDistToKeepCumulative (it replaces this) + @deprecated + */ + double getFilterCumulativeMaxDist(void) + { return getMaxDistToKeepCumulative(); } + /** you should use setMaxSecondsToKeepCumulative instead, (replaces this) + * @deprecated + */ + void setFilterCumulativeMaxAge(int seconds) + { setMaxSecondsToKeepCumulative(seconds); } + /** you should use getMaxSecondsToKeepCumulative instead, (replaces this) + * @deprecated + */ + int getFilterCumulativeMaxAge(void) + { return getMaxSecondsToKeepCumulative(); } + + /// Gets the number of laser packets received in the last second + int getSickPacCount(void) + { return getReadingCount(); } + + /// Adds a connect callback + void addConnectCB(ArFunctor *functor, + ArListPos::Pos position = ArListPos::LAST) + { + if (position == ArListPos::FIRST) + ArLMS2xx::addConnectCB(functor, 75); + else if (position == ArListPos::LAST) + ArLMS2xx::addConnectCB(functor, 25); + else + ArLMS2xx::addConnectCB(functor, 25); + } + /// Adds a disconnect callback + void remConnectCB(ArFunctor *functor) + { + ArLMS2xx::remConnectCB(functor); + } + + /// Adds a callback for when a connection to the robot is failed + void addFailedConnectCB(ArFunctor *functor, + ArListPos::Pos position = ArListPos::LAST) + { + if (position == ArListPos::FIRST) + ArLMS2xx::addFailedConnectCB(functor, 75); + else if (position == ArListPos::LAST) + ArLMS2xx::addFailedConnectCB(functor, 25); + else + ArLMS2xx::addFailedConnectCB(functor, 25); + } + /// Removes a callback for when a connection to the robot is failed + void remFailedConnectCB(ArFunctor *functor) + { + ArLMS2xx::remFailedConnectCB(functor); + } + + /// Adds a callback for when disconnect is called while connected + void addDisconnectNormallyCB(ArFunctor *functor, + ArListPos::Pos position = ArListPos::LAST) + { + if (position == ArListPos::FIRST) + ArLMS2xx::addDisconnectNormallyCB(functor, 75); + else if (position == ArListPos::LAST) + ArLMS2xx::addDisconnectNormallyCB(functor, 25); + else + ArLMS2xx::addDisconnectNormallyCB(functor, 25); + } + /// Removes a callback for when disconnect is called while connected + void remDisconnectNormallyCB(ArFunctor *functor) + { + ArLMS2xx::remDisconnectNormallyCB(functor); + } + + /// Adds a callback for when disconnection happens because of an error + void addDisconnectOnErrorCB(ArFunctor *functor, + ArListPos::Pos position = ArListPos::LAST) + { + if (position == ArListPos::FIRST) + ArLMS2xx::addDisconnectOnErrorCB(functor, 75); + else if (position == ArListPos::LAST) + ArLMS2xx::addDisconnectOnErrorCB(functor, 25); + else + ArLMS2xx::addDisconnectOnErrorCB(functor, 25); + } + /// Removes a callback for when disconnection happens because of an error + void remDisconnectOnErrorCB(ArFunctor *functor) + { + ArLMS2xx::remDisconnectOnErrorCB(functor); + } + /// Adds a callback that is called whenever a laser packet is processed + void addDataCB(ArFunctor *functor, + ArListPos::Pos position = ArListPos::LAST) + { + if (position == ArListPos::FIRST) + ArLMS2xx::addReadingCB(functor, 75); + else if (position == ArListPos::LAST) + ArLMS2xx::addReadingCB(functor, 25); + else + ArLMS2xx::addReadingCB(functor, 25); + } + /// Removes a callback that is called whenever a laser packet is processed + void remDataCB(ArFunctor *functor) + { + ArLMS2xx::remReadingCB(functor); + } + + /// Sets the time without a response until connection assumed lost + void setConnectionTimeoutTime(int secs) + { setConnectionTimeoutSeconds(secs); } + /// Gets the time without a response until connection assumed lost + int getConnectionTimeoutTime(void) + { return ArMath::roundInt(getConnectionTimeoutSeconds()); } + +}; + + +#endif //ARSICK_H diff --git a/Legacy/Aria/include/ArSignalHandler.h b/Legacy/Aria/include/ArSignalHandler.h new file mode 100644 index 0000000..48670f9 --- /dev/null +++ b/Legacy/Aria/include/ArSignalHandler.h @@ -0,0 +1,163 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARSIGNALHANDLER_H +#define ARSIGNALHANDLER_H + + +#include +#ifdef WIN32 +#else +#include +#endif +#include "ariaTypedefs.h" +#include "ArASyncTask.h" +#include "ArFunctor.h" + + +/// Signal handling class +/** + This is a signal handling class. It has both a threaded and non-threaded + mode of operation. The non-threaded mode will work in a threaded application + but it is best to use the threaded mode. The benefit of the threaded mode + is that if the signal incures some processing, but does not shutdown the + program (ie. SIGUSR1 or SIGUSR2), the threaded mode will handle the signal + in its own thread and hopefully that will not hurt the performance of the + tight loop robot control. Exaclty how much performance you get out of this + depends on your machines physical hardware and exactly what the processing + the signal handler does. For instance, a multi-processor machine has a much + greater chance of the signal handler not interfering with the robot control + loop. + + See the Aria main class for how to initialize a default setup of the + signal handling. + + There are functions to block, unblock, handle and unhandle signals. These + functions all must be called before creating the signalhandler. In either + single or multi-threaded mode. The functions to block and handle signals + creates a set of blocking and handling which is then used by the create + functions to tell the Linux kernel what to do. + + In the threaded mode, there is a signal handler thread that is created. + That thread is created in a detached state, which means it can not be + joined on. When the program exits, the signal handler thread will be + ignored and that thread will never exit its run loop. This is perfectly + fine behavior. There is no state that can be messed up in this fashion. + It is just easier to exit the program than to try to wake up that thread + and get it to exit itself. + + This class is for Linux only. Windows has virtualy no support for signals + and the little support that it does have is not realy usefull. There is + an empty implementation of this class for Windows so that code can compile + in both Linux and Windows. Just do not expect the code that uses this + signal handling to do anything in Windows. This should not be a problem + since signals are not used in Windows. +*/ +class ArSignalHandler : public ArASyncTask +{ +public: + + typedef enum + { + SigHUP=1, SigINT, SigQUIT, SigILL, SigTRAP, SigABRT, SigBUS, SigFPE, + SigKILL, SigUSR1, SigSEGV, SigUSR2, SigPIPE, SigALRM, SigTERM, SigSTKFLT, + SigCHLD, SigCONT, SigSTOP, SigTSTP, SigTTIN, SigTTOU, SigURG, + SigXCPU, SigXFSZ, SigVTALRM, SigPROF, SigWINCH, SigIO, SigPWR + } Signal; + + /// Setup the signal handling for a non-threaded program + AREXPORT static void createHandlerNonThreaded(); + + /// Setup the signal handling for a multi-threaded program + AREXPORT static void createHandlerThreaded(); + + /// Block all the common signals the kill a program + AREXPORT static void blockCommon(); + + /// Unblock all the signals + AREXPORT static void unblockAll(); + + /// Block the given signal + AREXPORT static void block(Signal sig); + + /// Unblock the given signal + AREXPORT static void unblock(Signal sig); + + /// Handle the given signal + AREXPORT static void handle(Signal sig); + + /// Dont handle the given signal + AREXPORT static void unhandle(Signal sig); + + /// Add a handler callback + AREXPORT static void addHandlerCB(ArFunctor1 *func, + ArListPos::Pos position); + + /// Remove a handler callback + AREXPORT static void delHandlerCB(ArFunctor1 *func); + + /// Removes all the handlers + AREXPORT static void delAllHandlerCBs(void); + + /// Get a pointer to the single ArSignalHandler instance + AREXPORT static ArSignalHandler * getHandler(); + + /// Get the name of the given signal + AREXPORT static const char * nameSignal(int sig); + + /// Block all the common signals for the calling thread only + AREXPORT static void blockCommonThisThread(); + + /// Block all the signals for the calling thread only + AREXPORT static void blockAllThisThread(); + + /// Destructor + virtual ~ArSignalHandler(); + + AREXPORT virtual void * runThread(void *arg); + + AREXPORT static void signalCB(int sig); + + AREXPORT static void logThread(void); +protected: + + ArSignalHandler(); + + static void initSigMap(); + + bool ourIgnoreQUIT; + + static ArSignalHandler *ourSignalHandler; + static ArStrMap ourSigMap; +#ifdef WIN32 +#else + static sigset_t ourBlockSigSet; + static sigset_t ourHandleSigSet; +#endif + static std::list*> ourHandlerList; +}; + + +#endif // ARSIGNALHANDLER_H diff --git a/Legacy/Aria/include/ArSimpleConnector.h b/Legacy/Aria/include/ArSimpleConnector.h new file mode 100644 index 0000000..15db94a --- /dev/null +++ b/Legacy/Aria/include/ArSimpleConnector.h @@ -0,0 +1,97 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARSIMPLECONNECTOR_H +#define ARSIMPLECONNECTOR_H + +#include "ariaTypedefs.h" +#include "ArSerialConnection.h" +#include "ArTcpConnection.h" +#include "ArArgumentBuilder.h" +#include "ArArgumentParser.h" +#include "ariaUtil.h" +#include "ArRobotConnector.h" +#include "ArLaserConnector.h" + +class ArSick; +class ArRobot; + + + +/// Legacy connector for robot and laser +/** + This is deprecated but is left in for compatibility with old code, + Instead use ArRobotConnector to set up ArRobot's connection to the robot, and + ArLaserConnector to set up connections with laser rangefinder devices. + + @deprecated Use ArRobotConnector and ArLaserConnector instead + **/ +class ArSimpleConnector +{ +public: + /// Constructor that takes args from the main + AREXPORT ArSimpleConnector(int *argc, char **argv); + /// Constructor that takes argument builder + AREXPORT ArSimpleConnector(ArArgumentBuilder *arguments); + /// Constructor that takes argument parser + AREXPORT ArSimpleConnector(ArArgumentParser *parser); + /// Destructor + AREXPORT ~ArSimpleConnector(void); + /// Sets up the robot to be connected + AREXPORT bool setupRobot(ArRobot *robot); + /// Sets up the robot then connects it + AREXPORT bool connectRobot(ArRobot *robot); + /// Sets up the laser to be connected + AREXPORT bool setupLaser(ArSick *laser); + /// Sets up a second laser to be connected + AREXPORT bool setupSecondLaser(ArSick *laser); + /// Sets up a laser t obe connected (make sure you setMaxNumLasers) + AREXPORT bool setupLaserArbitrary(ArSick *laser, + int laserNumber); + /// Connects the laser synchronously (will take up to a minute) + AREXPORT bool connectLaser(ArSick *laser); + /// Connects the laser synchronously (will take up to a minute) + AREXPORT bool connectSecondLaser(ArSick *laser); + /// Connects the laser synchronously (make sure you setMaxNumLasers) + AREXPORT bool connectLaserArbitrary(ArSick *laser, int laserNumber); + /// Function to parse the arguments given in the constructor + AREXPORT bool parseArgs(void); + /// Function to parse the arguments given in an arbitrary parser + AREXPORT bool parseArgs(ArArgumentParser *parser); + /// Log the options the simple connector has + AREXPORT void logOptions(void) const; + /// Sets the number of possible lasers + AREXPORT void setMaxNumLasers(int maxNumLasers = 1); +protected: + /// Finishes the stuff the constructor needs to do + void finishConstructor(void); + + ArArgumentParser *myParser; + bool myOwnParser; + ArRobotConnector *myRobotConnector; + ArLaserConnector *myLaserConnector; +}; + +#endif // ARSIMPLECONNECTOR_H diff --git a/Legacy/Aria/include/ArSimulatedLaser.h b/Legacy/Aria/include/ArSimulatedLaser.h new file mode 100644 index 0000000..3fc12cf --- /dev/null +++ b/Legacy/Aria/include/ArSimulatedLaser.h @@ -0,0 +1,110 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARSIMULATEDLASER_H +#define ARSIMULATEDLASER_H + +#include "ariaTypedefs.h" +#include "ArLaser.h" + +class ArRobot; +class ArRobotPacket; + +/** + This class is a subclass of ArRangeDeviceThreaded meant for any + planar scanning lasers, like the SICK lasers, Hokoyo URG series + lasers, etc. Unlike most base classes this contains the superset + of everything that may need to be configured on any of the sensors, + this is so that the configuration and parameter files don't have to + deal with anything sensor specific. + + To see the different things you can set on a laser, call the + functions canSetDegrees, canChooseRange, canSetIncrement, + canChooseIncrement, canChooseUnits, canChooseReflectorBits, + canSetPowerControlled, canChooseStartBaud, and canChooseAutoBaud to + see what is available (the help for each of those tells you what + functions they are associated with, and for each function + associated with one of those it tells you to see the associated + function). + + @since 2.7.0 +**/ + +class ArSimulatedLaser : public ArLaser +{ +public: + /// Constructor + AREXPORT ArSimulatedLaser(ArLaser *laser); + /// Destructor + AREXPORT virtual ~ArSimulatedLaser(); + + AREXPORT virtual bool blockingConnect(void); + AREXPORT virtual bool asyncConnect(void); + AREXPORT virtual bool disconnect(void); + AREXPORT virtual bool isConnected(void) + { return myIsConnected; } + AREXPORT virtual bool isTryingToConnect(void) + { + if (myStartConnect) + return true; + else if (myTryingToConnect) + return true; + else + return false; + } + +protected: + AREXPORT virtual void * runThread(void *arg); + AREXPORT virtual bool laserCheckParams(void); + AREXPORT bool finishParams(void); + AREXPORT bool simPacketHandler(ArRobotPacket *packet); + ArLaser *myLaser; + + double mySimBegin; + double mySimEnd; + double mySimIncrement; + + // stuff for the sim packet + ArPose mySimPacketStart; + ArTransform mySimPacketTrans; + ArTransform mySimPacketEncoderTrans; + unsigned int mySimPacketCounter; + unsigned int myWhichReading; + unsigned int myTotalNumReadings; + + bool myStartConnect; + bool myIsConnected; + bool myTryingToConnect; + bool myReceivedData; + + std::list::iterator myIter; + // range buffers to hold current range set and assembling range set + std::list *myAssembleReadings; + std::list *myCurrentReadings; + + ArRetFunctor1C mySimPacketHandler; +}; + +#endif // ARSIMULATEDLASER_H diff --git a/Legacy/Aria/include/ArSocket.h b/Legacy/Aria/include/ArSocket.h new file mode 100644 index 0000000..b16fee2 --- /dev/null +++ b/Legacy/Aria/include/ArSocket.h @@ -0,0 +1,400 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARSOCKET_H +#define ARSOCKET_H + + +#ifndef WIN32 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#endif + + +#include +#include "ariaTypedefs.h" +#include "ArMutex.h" +#include "ariaUtil.h" + +class ArFunctor; + + +/// socket communication wrapper +/** + ArSocket is a layer which allows you to use the sockets networking + interface in an operating system independent manner. All of the standard + commonly used socket functions are implemented such as open(), close(), + connect(), accept(), read(), write(), hostToNetOrder(), netToHostOrder(). ArSocket extends some of these functions to set useful options (see method documentation for details). It also provides additional useful functions like + writeString(), readString, setCloseCallback(), and more. + + In Windows, the sockets subsystem needs to be initialized and shutdown + by the program. So when a program starts it must call Aria::init() and + call Aria::shutdown() when it exits. (Or, to only initialize the socket + system, and not do any other global Aria initialization, use ArSocket::init() + and ArSocket::shutdown().) + + Some calls set an error code on failure in addition to returning false. This value is available from getError(). + If getError() returns something other than NoErr, a text description of the error may be available from getErrorStr(). + + @sa @ref socketServerExample.cpp + @sa @ref socketClientExample.cpp + + @ingroup UtilityClasses +*/ +class ArSocket +{ +public: + + enum Type {UDP, TCP, Unknown}; + enum Error {NoErr, NetFail, ConBadHost, ConNoRoute, ConRefused, NameLookup}; + + /// Constructor. You must then use either connect() or open(). + AREXPORT ArSocket(); + + /// Constructor which immediately connects to a server as a client + /// @a host Hostname or IP address of remote server + /// @a port Port number on server + /// @a Which IP protocol to use, type ArSocket::TCP or ArSocket::UDP + AREXPORT ArSocket(const char *host, int port, Type type); + + /// Constructor which immediately opens a port as a server + /// @a port Port number to open. Use a value greater than 1024. + /// @a doClose Automatically close the port when ArSocket is destroyed (recommend using true) + /// @a type Which IP protocol to use, ArSocket::TCP or ArSocket::UDP + AREXPORT ArSocket(int port, bool doClose, Type type); + + /// Destructor + AREXPORT ~ArSocket(); + + /// Initialize the OS sockets system, if neccesary + AREXPORT static bool init(); + + /// Shutdown the OS sockets system, if neccesary + AREXPORT static void shutdown(); + + /// Converts the given socket type to a displayable text string (for debugging). + AREXPORT static const char *toString(Type t); + + /** @internal */ + AREXPORT static bool ourInitialized; + + /// Copy internal socket structures + /// @internal + AREXPORT bool copy(int fd, bool doclose); + + /// Copy socket + /// @internal + AREXPORT void copy(ArSocket *s) + {myFD=s->myFD; myDoClose=false; mySin=s->mySin;} + + /// Transfer ownership of a socket + /** transfer() will transfer ownership to this socket. The input socket + will no longer close the file descriptor when it is destructed. + */ + AREXPORT void transfer(ArSocket *s) + {myFD=s->myFD; myDoClose=true; s->myDoClose=false; mySin=s->mySin; + myType=s->myType; strcpy(myRawIPString, s->myRawIPString); + setIPString(s->getIPString()); } + + /// Connect as a client to a server + AREXPORT bool connect(const char *host, int port, Type type = TCP, + const char *openOnIP = NULL); + + /** Open a server port + + Opens a server port, that is, a port that is bound to a local port (and optionally, address) + and listens for new incoming connections. Use accept() to wait for a + new incoming connection from a client. + + In additon, internally this method calls setLinger(0), setReuseAddress(), + and setNonBlock() to turn on these options (having these on is + particularly useful for servers). + + @param port Port number + @param type ArSocket::TCP or ArSocket::UDP. + @param openOnIP If given, only bind to the interface + accociated with this address (Linux only) (by default, all interfaces are used) + */ + AREXPORT bool open(int port, Type type, const char *openOnIP = NULL); + + /// Simply create a port. + AREXPORT bool create(Type type); + + /** Find the first valid unused port after @a startPort, and bind the socket to it. + @param startPort first port to try + @param openOnIP If given, only check ports open on the interface accociated with this address (Linux only) + */ + AREXPORT bool findValidPort(int startPort, const char *openOnIP = NULL); + + /// Connect the socket to the given address + AREXPORT bool connectTo(const char *host, int port); + + /// Connect the socket to the given address + AREXPORT bool connectTo(struct sockaddr_in *sin); + + /// Accept a new connection + AREXPORT bool accept(ArSocket *sock); + + /// Close the socket + AREXPORT bool close(); + + /// Write data to the socket + AREXPORT int write(const void *buff, size_t len); + + /// Read data from the socket + AREXPORT int read(void *buff, size_t len, unsigned int msWait = 0); + + /// Send a message (short string) on the socket + AREXPORT int sendTo(const void *msg, int len); + + /// Send a message (short string) on the socket + AREXPORT int sendTo(const void *msg, int len, struct sockaddr_in *sin); + + /// Receive a message (short string) from the socket + AREXPORT int recvFrom(void *msg, int len, sockaddr_in *sin); + + /// Convert a hostname string to an address structure + AREXPORT static bool hostAddr(const char *host, struct in_addr &addr); + + /// Convert an address structure to a hostname string + AREXPORT static bool addrHost(struct in_addr &addr, char *host); + + /// Get the localhost address + AREXPORT static std::string getHostName(); + + /// Get socket information (socket "name"). Aspects of this "name" are accessible with sockAddrIn(), inAddr(), inPort() + AREXPORT bool getSockName(); + + /// Accessor for the sockaddr + struct sockaddr_in * sockAddrIn() {return(&mySin);} + + /// Accessor for the in_addr part of sockaddr + struct in_addr * inAddr() {return(&mySin.sin_addr);} + + /// Accessor for the port of the sockaddr + unsigned short int inPort() {return(mySin.sin_port);} + + /// Convert @a addr into string numerical address + AREXPORT static void inToA(struct in_addr *addr, char *buff); + + /// Size of the sockaddr + static size_t sockAddrLen() {return(sizeof(struct sockaddr_in));} + +#ifdef WIN32 + /// Max host name length + static size_t maxHostNameLen() {return(MAXGETHOSTSTRUCT);} +#else + /// Max host name length + static size_t maxHostNameLen() {return(MAXHOSTNAMELEN);} +#endif + + /// Convert an int from host byte order to network byte order + AREXPORT static unsigned int hostToNetOrder(int i); + + /// Convert an int from network byte order to host byte order + AREXPORT static unsigned int netToHostOrder(int i); + + /// Set the linger value + AREXPORT bool setLinger(int time); + + /// Set broadcast value + AREXPORT bool setBroadcast(); + + /// Set the reuse address value + AREXPORT bool setReuseAddress(); + + /// Set socket to nonblocking. Most importantly, calls to read() will return immediately, even if no data is available. + AREXPORT bool setNonBlock(); + + /// Change the doClose value + AREXPORT void setDoClose(bool yesno) {myDoClose=yesno;} + + /// Get the file descriptor + AREXPORT int getFD() const {return(myFD);} + + /// Get the protocol type + AREXPORT Type getType() const {return(myType);} + + /// Get a string containing a description of the last error. Only valid if getError() does not return NoErr. + AREXPORT const std::string & getErrorStr() const {return(myErrorStr);} + + /// Get a code representing the last error + AREXPORT Error getError() const {return(myError);} + + /// Sets whether we're error tracking or not + AREXPORT void setErrorTracking(bool errorTracking) + { myErrorTracking = errorTracking; } + + /// Gets whether we're doing error tracking or not + AREXPORT bool getErrorTracking(void) { return myErrorTracking; } + + /// Gets if we've had a bad write (you have to use error tracking for this) + AREXPORT bool getBadWrite(void) const { return myBadWrite; } + + /// Gets if we've had a bad read (you have to use error tracking for this) + AREXPORT bool getBadRead(void) const { return myBadRead; } + + +#ifndef SWIG + /** @brief Writes a string to the socket (adding end of line characters) + * @swigomit + * @sa writeStringPlain() + */ + AREXPORT int writeString(const char *str, ...); +#endif + + /// Same as writeString(), but no varargs + AREXPORT int writeStringPlain(const char *str) { return writeString(str); } + + /// Reads a string from the socket + AREXPORT char *readString(unsigned int msWait = 0); + /// Whether to ignore carriage return characters in readString or not + AREXPORT void setReadStringIgnoreReturn(bool ignore) + { myStringIgnoreReturn = ignore; } + /// Clears the partial string read + AREXPORT void clearPartialReadString(void); + /// Compares a string against what was partially read + AREXPORT int comparePartialReadString(const char *partialString); + /// Gets the time we last successfully read a string from the socket + AREXPORT ArTime getLastStringReadTime(void) { return myLastStringReadTime; } + /// Sets echoing on the readString calls this socket does + AREXPORT void setEcho(bool echo) + { myStringAutoEcho = false; myStringEcho = echo; } + /// Gets if we are echoing on the readString calls this socket does + AREXPORT bool getEcho(void) { return myStringEcho; } + /// Sets whether we log the writeStrings or not + AREXPORT void setLogWriteStrings(bool logWriteStrings) + { myLogWriteStrings = logWriteStrings; } + /// Gets whether we log the writeStrings or not + AREXPORT bool getLogWriteStrings(void) { return myLogWriteStrings; } + /// Sets whether we use the wrong (legacy) end chars or not + AREXPORT void setStringUseWrongEndChars(bool useWrongEndChars) + { myStringWrongEndChars = useWrongEndChars; } + /// Gets whether we log the writeStrings or not + AREXPORT bool getStringUseWrongEndChars(void) + { return myStringWrongEndChars; } + /// Gets the raw ip number as a string + AREXPORT const char *getRawIPString(void) const { return myRawIPString; } + /// Gets the ip number as a string (this can be modified though) + AREXPORT const char *getIPString(void) const { return myIPString.c_str(); } + /// Sets the ip string + AREXPORT void setIPString(const char *ipString) + { if (ipString != NULL) myIPString = ipString; else myIPString = ""; } + /// Sets the callback for when the socket is closed (nicely or harshly) + AREXPORT void setCloseCallback(ArFunctor *functor) + { myCloseFunctor = functor; } + /// Sets the callback for when the socket is closed (nicely or harshly) + AREXPORT ArFunctor *getCloseCallback(void) { return myCloseFunctor; } + /// Gets the number of writes we've done + long getSends(void) { return mySends; } + /// Gets the number of bytes we've written + long getBytesSent(void) { return myBytesSent; } + /// Gets the number of reads we've done + long getRecvs(void) { return myRecvs; } + /// Gets the number of bytes we've read + long getBytesRecvd(void) { return myBytesRecvd; } + /// Resets the tracking information on the socket + void resetTracking(void) + { mySends = 0; myBytesSent = 0; myRecvs = 0; myBytesRecvd = 0; } + + /// Sets NODELAY option on TCP socket, which can reduce latency for small packet sizes. + AREXPORT bool setNoDelay(bool flag); + bool isOpen() { return myFD > 0; } +protected: + /// Sets the ip string + /// internal function that sets the ip string from the inAddr + void setRawIPString(void); + /// internal function that echos strings from read string + void doStringEcho(void); + // internal crossplatform init (mostly for string reading stuff) + void internalInit(void); + + // separates out a host string (possibly host:port) into a host and + // the port that should be used. + void separateHost(const char *rawHost, int rawPort, char *useHost, + size_t useHostSize, int *port); + + Type myType; + Error myError; + std::string myErrorStr; + bool myDoClose; + +#ifdef WIN32 + SOCKET myFD; + // Using the SOCKET data type mostly because this is what the Win32 methods + // return. + std::string myHost; + int myPort; +#else // Windows + int myFD; +#endif + + bool myNonBlocking; + struct sockaddr_in mySin; + + bool myLogWriteStrings; + ArMutex myReadStringMutex; + ArMutex myWriteStringMutex; + bool myStringAutoEcho; + bool myStringEcho; + bool myStringIgnoreReturn; + bool myStringWrongEndChars; + char myStringBuf[5000]; + size_t myStringPos; + char myStringBufEmpty[1]; + size_t myStringPosLast; + std::string myIPString; + char myRawIPString[128]; + ArTime myLastStringReadTime; + bool myStringGotEscapeChars; + bool myStringGotComplete; + bool myStringHaveEchoed; + + long mySends; + long myBytesSent; + long myRecvs; + long myBytesRecvd; + + bool myBadWrite; + bool myBadRead; + bool myErrorTracking; + + // A functor to call when the socket closes + ArFunctor *myCloseFunctor; +}; + + +#endif // ARSOCKET_H + diff --git a/Legacy/Aria/include/ArSonarAutoDisabler.h b/Legacy/Aria/include/ArSonarAutoDisabler.h new file mode 100644 index 0000000..b174148 --- /dev/null +++ b/Legacy/Aria/include/ArSonarAutoDisabler.h @@ -0,0 +1,91 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARSONARAUTODISABLER_H +#define ARSONARAUTODISABLER_H + +/// Class for automatically disabling sonar when the robot is stopped +/** + If you create one of this class it will disable the sonar when the + robot stops moving and then enable the sonar when the robot moves. + Later this may get more parameters and the ability to be turned on + and off and things like that (email on aria-users if you want + them). + + Note that this class assumes it is the only class turning the sonar + on or off and that the sonar start on. + + @ingroup OptionalClasses + **/ + +#include "ariaTypedefs.h" +#include "ariaUtil.h" +#include "ArFunctor.h" + +class ArRobot; + +class ArSonarAutoDisabler +{ +public: + /// Constructor + AREXPORT ArSonarAutoDisabler(ArRobot *robot); + /// Destructor + AREXPORT virtual ~ArSonarAutoDisabler(); + /// Supresses this disabler (which turns off the sonar) + void supress(void) { mySupressed = true; } + /// Gets the callback to supress the autodisabler + ArFunctor *getSupressCallback(void) { return &mySupressCB; } + /// Unsupresses this disabler (goes back to auto enabling/disabling) + void unsupress(void) { mySupressed = false; } + /// Gets the callback to supress the autodisabler + ArFunctor *getUnsupressCallback(void) { return &myUnsupressCB; } + + /// Sets that we're autonomous drivign so we only enable some sonar + void setAutonomousDriving(void) { myAutonomousDriving = true; } + /// Gets the callback to set that we're driving autonomously + ArFunctor *getSetAutonomousDrivingCallback(void) + { return &mySetAutonomousDrivingCB; } + /// Sets that we're driving non-autonomously so we enable all sonar + void clearAutonomousDriving(void) { myAutonomousDriving = false; } + /// Gets the callback to set that we're not driving autonomously + ArFunctor *getClearAutonomousDrivingCallback(void) + { return &myClearAutonomousDrivingCB; } +protected: + /// our user task + AREXPORT void userTask(void); + ArRobot *myRobot; + ArTime myLastMoved; + ArTime myLastSupressed; + bool mySupressed; + bool myAutonomousDriving; + + ArFunctorC myUserTaskCB; + ArFunctorC mySupressCB; + ArFunctorC myUnsupressCB; + ArFunctorC mySetAutonomousDrivingCB; + ArFunctorC myClearAutonomousDrivingCB; +}; + +#endif // ARSONARAUTODISABLER diff --git a/Legacy/Aria/include/ArSonarConnector.h b/Legacy/Aria/include/ArSonarConnector.h new file mode 100644 index 0000000..c5630ba --- /dev/null +++ b/Legacy/Aria/include/ArSonarConnector.h @@ -0,0 +1,200 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARSONARCONNECTOR_H +#define ARSONARCONNECTOR_H + +#include "ariaTypedefs.h" +#include "ArSerialConnection.h" +#include "ArTcpConnection.h" +#include "ArArgumentBuilder.h" +#include "ArArgumentParser.h" +#include "ariaUtil.h" +#include "ArRobotConnector.h" + +class ArSonarMTX; +class ArRobot; + + + +/// Connect to sonar based on robot parameters and command-line arguments +/** + + ArSonarConnector makes a sonar connection either through a serial port + connection. + When you create your ArSonarConnector, pass it command line parameters via + either the argc and argv variables from main(), or pass it an + ArArgumentBuilder or ArArgumentParser object. (ArArgumentBuilder + is able to obtain command line parameters from a Windows program + that uses WinMain() instead of main()). + ArSonarConnector registers a callback with the global Aria class. Use + Aria::parseArgs() to parse all command line parameters to the program, and + Aria::logOptions() to print out information about all registered command-line parameters. + + The following command-line arguments are checked: + @verbinclude ArSonarConnector_options + + To connect to any sonars that were set up in the robot parameter file or + via command line arguments, call connectSonars(). If successful, + connectSonars() will return true and add an entry for each sonar connected + in the ArRobot object's list of sonars. These ArSonarMTX objects can be + accessed from your ArRobot object via ArRobot::findSonar() or ArRobot::getSonarMap(). + + + @since 2.8.0 + + **/ +class ArSonarConnector +{ +public: + /// Constructor that takes argument parser + AREXPORT ArSonarConnector( + ArArgumentParser *parser, + ArRobot *robot, ArRobotConnector *robotConnector, + bool autoParseArgs = true, + ArLog::LogLevel infoLogLevel = ArLog::Verbose, + ArRetFunctor1 *turnOnPowerOutputCB = NULL, + ArRetFunctor1 *turnOffPowerOutputCB = NULL); + /// Destructor + AREXPORT ~ArSonarConnector(void); + /// Connects all the sonars the robot has that should be auto connected + AREXPORT bool connectSonars( + bool continueOnFailedConnect = false, + bool addConnectedSonarsToRobot = true, + bool addAllSonarsToRobot = false, + bool turnOnSonars = true, + bool powerCycleSonarOnFailedConnect = true); + // Connects all the sonars in replay mode + AREXPORT bool connectReplaySonars( + bool continueOnFailedConnect = false, + bool addConnectedSonarsToRobot = true, + bool addAllSonarsToRobot = false, + bool turnOnSonars = true, + bool powerCycleSonarOnFailedConnect = true); + /// Sets up a sonar to be connected + AREXPORT bool setupSonar(ArSonarMTX *sonar, + int sonarNumber = 1); + /// Connects the sonar synchronously (will take up to a minute) + AREXPORT bool connectSonar(ArSonarMTX *sonar, + int sonarNumber = 1, + bool forceConnection = true); + /// Adds a sonar so parsing will get it + AREXPORT bool addSonar(ArSonarMTX *sonar, + int sonarNumber = 1); + /// Function to parse the arguments given in the constructor + AREXPORT bool parseArgs(void); + /// Function to parse the arguments given in an arbitrary parser + AREXPORT bool parseArgs(ArArgumentParser *parser); + /// Log the options the simple connector has + AREXPORT void logOptions(void) const; + /// Internal function to get the sonar (only useful between parseArgs and connectSonars) + AREXPORT ArSonarMTX *getSonar(int sonarNumber); + + /// Internal function to replace the sonar (only useful between parseArgs and connectSonars) but not the sonar data + AREXPORT bool replaceSonar(ArSonarMTX *sonar, int sonarNumber); + +protected: +/// Class that holds information about the sonar data +class SonarData +{ + public: + SonarData (int number, ArSonarMTX *sonar) { + myNumber = number; + mySonar = sonar; + myConn = NULL; + myConnect = false; myConnectReallySet = false; + myPort = NULL; + myPortType = NULL; + myType = NULL; + myRemoteTcpPort = 0; myRemoteTcpPortReallySet = false; + myBaud = NULL; + myAutoConn = NULL; + } + virtual ~SonarData() {} + /// The number of this sonar + int myNumber; + /// The actual pointer to this sonar + ArSonarMTX *mySonar; + // our connection + ArDeviceConnection *myConn; + // if we want to connect the sonar + bool myConnect; + // if myConnect was really set + bool myConnectReallySet; + // the port we want to connect the sonar on + const char *myPort; + // the type of port we want to connect to the sonar on + const char *myPortType; + // sonar Type + const char *myType; + // wheather to auto conn + const char *myAutoConn; + // sonar tcp port if we're doing a remote host + int myRemoteTcpPort; + // if our remote sonar tcp port was really set + bool myRemoteTcpPortReallySet; + /// the baud we want to use + const char *myBaud; +}; + + /// Turns on the power for the specific board in the firmware + AREXPORT bool turnOnPower(SonarData *sonarData); + + std::map mySonars; + + /// Parses the sonar arguments + AREXPORT bool parseSonarArgs(ArArgumentParser *parser, + SonarData *sonarData); + /// Logs the sonar command line option help text. + AREXPORT void logSonarOptions(SonarData *sonardata, bool header = true, bool metaOpts = true) const; + // Sets the sonar parameters + bool internalConfigureSonar(SonarData *sonarData); + + std::string mySonarTypes; + + // our parser + ArArgumentParser *myParser; + bool myOwnParser; + // if we should autoparse args or toss errors + bool myAutoParseArgs; + bool myParsedArgs; + + ArRobot *myRobot; + ArRobotConnector *myRobotConnector; + + // variables to hold if we're logging or not + bool mySonarLogPacketsReceived; + bool mySonarLogPacketsSent; + + ArLog::LogLevel myInfoLogLevel; + + ArRetFunctor1 *myTurnOnPowerOutputCB; + ArRetFunctor1 *myTurnOffPowerOutputCB; + + ArRetFunctorC myParseArgsCB; + ArConstFunctorC myLogOptionsCB; +}; + +#endif // ARLASERCONNECTOR_H diff --git a/Legacy/Aria/include/ArSonarDevice.h b/Legacy/Aria/include/ArSonarDevice.h new file mode 100644 index 0000000..1acba06 --- /dev/null +++ b/Legacy/Aria/include/ArSonarDevice.h @@ -0,0 +1,94 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARSONARDEVICE_H +#define ARSONARDEVICE_H + +#include "ariaTypedefs.h" +#include "ArRangeDevice.h" +#include "ArFunctor.h" + +#include "ArRobot.h" + +/// Keep track of recent sonar readings from a robot as an ArRangeDevice +/** + This class is for keeping a sonar history, which you may use for obstacle + avoidance, display, etc. + Simply use ArRobot::addRangeDevice() (or ArSonarDevice::setRobot()) + to attach an ArSonarDevice object to an ArRobot + robot object; ArSonarDevice will add a Sensor Interpretation task to the + ArRobot which will read new sonar readings each robot cycle and add + them to its sonar history. + + (Note that sonar range readings are from the surface of the sonar transducer disc, + not from the center of the robot.) + + @ingroup ImportantClasses + @ingroup DeviceClasses +*/ +class ArSonarDevice : public ArRangeDevice +{ +public: + /// Constructor + AREXPORT ArSonarDevice(size_t currentBufferSize = 24, + size_t cumulativeBufferSize = 64, + const char * name = "sonar"); + /// Destructor + AREXPORT virtual ~ArSonarDevice(); + /// Grabs the new readings from the robot and adds them to the buffers + /// (Primarily for internal use.) + AREXPORT void processReadings(void); + + /// Sets the robot pointer, also attaches its process function to the + /// robot as a Sensor Interpretation task. + AREXPORT virtual void setRobot(ArRobot *robot); + + /// Adds sonar readings to the current and cumulative buffers + /// Overrides the ArRangeDevice default action. + /// (This method is primarily for internal use.) + AREXPORT virtual void addReading(double x, double y); + + /// Sets a callback which if it returns true will ignore the reading + AREXPORT void setIgnoreReadingCB(ArRetFunctor1 *ignoreReadingCB); + + /// Gets the callback which if it returns true will ignore the reading + AREXPORT ArRetFunctor1 *getIgnoreReadingCB(void) + { return myIgnoreReadingCB; } + + /** @deprecated + * @sa ArRangeDevice::setMaxDistToKeepCumulative() + */ + AREXPORT void setCumulativeMaxRange(double range) + { setMaxDistToKeepCumulative(range); } +protected: + ArFunctorC myProcessCB; + double myFilterNearDist; // we throw out cumulative readings this close to current one + double myFilterFarDist; // throw out cumulative readings beyond this far from robot + + ArRetFunctor1 *myIgnoreReadingCB; +}; + + +#endif // ARSONARDEVICE_H diff --git a/Legacy/Aria/include/ArSonarMTX.h b/Legacy/Aria/include/ArSonarMTX.h new file mode 100644 index 0000000..5e64fcd --- /dev/null +++ b/Legacy/Aria/include/ArSonarMTX.h @@ -0,0 +1,565 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARSONARMTX_H +#define ARSONARMTX_H + +#include "ariaTypedefs.h" +#include "ArRangeDevice.h" +#include "ArFunctor.h" +#include "ArRobot.h" +#include "ArRobotPacket.h" + + + +// Packets are in the format of +// 2 bytes header (0xfa 0xfb) +// 1 byte length +// 1 byte command +// xx bytes command specific / args +// 2 bytes checksum +// +// Alive packet +// request - 0xfa 0xfb 0x03 0x00 0x00 0x00 +// response - 0xfa 0xfb 0x03 0x00 0x00 0x00 +// +// Start Scan packet +// request - 0xfa 0xfb 0x03 0x01 0x00 0x01 +// reading - 0xfa 0xfb 0x07 0x01 0x0b 0x00 0xff 0xff 0x02 0xf5 +// +// Stop Scan packet +// request - 0xfa 0xfb 0x03 0x02 0x00 0x02 +// +// Reset packet +// request - 0xfa 0xfb 0x03 0x03 0x00 0x03 +// +// Get Number of Transducers (12 here) +// request - 0xfa 0xfb 0x03 0x11 0x00 0x11 +// response - 0xfa 0xfb 0x04 0x11 0x0c 0x11 0x0c +// +// Get Echo Sample Size packet (also called max range) +// request - 0xfa 0xfb 0x04 0x14 0x00 0x14 0x00 +// response - 0xfa 0xfb 0x06 0x14 0x01 0x00 0x01 0x14 0x01 +// note: byte 5 (0x01) is transducer # (starts at 0) +// note: bytes 6 & 7 are value +// +// Get Gain packet +// request - 0xfa 0xfb 0x04 0x17 0x00 0x17 0x00 +// response - 0xfa 0xfb 0x05 0x17 0x00 0x05 0x17 0x04 +// note: byte 5 (0x01) is transducer # (starts at 0) +// note: bytes 6 is gain +// +// Get Mask +// request - 0xfa 0xfb 0x03 0x12 0x00 0x12 +// response - 0xfa 0xfb 0x05 0x12 0xff 0x0f 0x12 0xf0 +// +// Get Number of Thresholds +// request - 0xfa 0xfb 0x03 0x18 0x00 0x18 +// response - 0xfa 0xfb 0x04 0x18 0x03 0x18 0x03 +// +// Get Sonar Delay +// request - 0xfa 0xfb 0x03 0x13 0x00 0x13 +// response - 0xfa 0xfb 0x04 0x13 0x01 0x13 0x01 +// +// Get Thresholds +// request - 0xfa 0xfb 0x04 0x19 0x00 0x19 0x00 +// response - 0xfa 0xfb 0x0a 0x19 0x00 0xb8 0x0b 0xdc 0x05 0xd0 0x07 0x7d 0x17 +// note: byte 5 (0x00) is transducer # +// +// Get Version +// request - 0xfa 0xfb 0x03 0x10 0x00 0x10 +// response - 0xfa 0xfb 0x04 0x10 0x01 0x10 0x01 +// +// Set Echo Sample Size (also set max range) +// request - 0xfa 0xfb 0x06 0x24 0x00 0x02 0x00 0x26 0x00 +// note: byte 5 (0x00) is transducer # +// note: there is no response - use get echo sample size to test +// +// Set Gain +// request - 0xfa 0xfb 0x05 0x27 0x00 0x05 0x27 0x05 +// note: byte 5 (0x00) is transducer #, gain is byte 6 +// note: there is no response - use get gain to test +// +// Set Mask +// request - 0xfa 0xfb 0x05 0x22 0xc0 0x81 0x22 0x41 +// note: byte 5 & 6 are the masks +// note: there is no response - use get mask test +// +// Set Sonar Delay +// request - 0xfa 0xfb 0x04 0x23 0xd9 0x23 0xd9 +// note: there is no response - use get sonar delay to test +// +// Set Thresholds +// request - 0xfa 0xfb 0x0a 0x29 0x00 0x38 0xae 0x06 0xaf 0xc9 0x63 0x31 0xc0 +// note: byte 5 is transducer number +// note: there is no response - use get thresholds to test +// + + +/// Receives sonar data from an MTX robot +/// Use ArSonarConnector to establish the connection and create and initiate the ArSonarMTX thread. +/// @since 2.8.0 +class ArSonarMTX : public ArASyncTask +{ +public: + /// Constructor + AREXPORT ArSonarMTX( + int sonarBoardNum = 0, + const char * name = "MTXSonar", ArDeviceConnection *conn = NULL, + ArRobot *robot = NULL); + /// Destructor + AREXPORT virtual ~ArSonarMTX(); + + /// Sets the robot pointer, also attaches its process function to the + /// robot as a Sensor Interpretation task. + AREXPORT virtual void setRobot(ArRobot *robot); + + AREXPORT int getBoardNum(void) + { return myBoardNum; } + + /// Sets the device this instance receives packets from + AREXPORT void setDeviceConnection(ArDeviceConnection *conn); + /// Gets the device this instance receives packets from + AREXPORT ArDeviceConnection *getDeviceConnection(void); + + /// Very Internal call that gets the packet sender, shouldn't be used + ArRobotPacketSender *getPacketSender(void) + { return mySender; } + /// Very Internal call that gets the packet sender, shouldn't be used + ArRobotPacketReceiver *getPacketReceiver(void) + { return myReceiver; } + + AREXPORT virtual bool blockingConnect(bool sendTracking, bool recvTracking); + /// Connect used for debug replay + AREXPORT virtual bool fakeConnect(); + AREXPORT virtual bool disconnect(void); + AREXPORT virtual bool isConnected(void) { return myIsConnected; } + AREXPORT virtual bool isTryingToConnect (void) + { + if (myStartConnect) + return true; + else if (myTryingToConnect) + return true; + else + return false; + } + /// Logs the information about the sensor + AREXPORT void log(void); + + /// Lock this device + AREXPORT virtual int lockDevice() { return(myDeviceMutex.lock());} + /// Try to lock this device + AREXPORT virtual int tryLockDevice() {return(myDeviceMutex.tryLock());} + /// Unlock this device + AREXPORT virtual int unlockDevice() {return(myDeviceMutex.unlock());} + + AREXPORT virtual const char *getName(void) const; + + AREXPORT virtual const char *getNameWithBoard(void) const; + + AREXPORT void setInfoLogLevel(ArLog::LogLevel infoLogLevel) + { myInfoLogLevel = infoLogLevel; } + + /// Gets the default port type for the sonar + const char *getDefaultPortType(void) { return myDefaultPortType.c_str(); } + + /// Gets the default port type for the sonar + const char *getDefaultTcpPort(void) { return myDefaultTcpPort.c_str(); } + + /// Sets the numter of seconds without a response until connection assumed lost + AREXPORT virtual void setConnectionTimeoutSeconds(double seconds) + { ArLog::log(ArLog::Normal, + "%s::setConnectionTimeoutSeconds: Setting timeout to %g secs", + getName(), seconds); + myLastReading.setToNow(); myTimeoutSeconds = seconds; } + /// Gets the number of seconds without a response until connection assumed lost + AREXPORT virtual double getConnectionTimeoutSeconds(void) + {return myTimeoutSeconds; } + /// check for lost connections + AREXPORT bool checkLostConnection(void); + /// disconnect + AREXPORT void disconnectOnError(void); + /// Gets the time data was last receieved + ArTime getLastReadingTime(void) { return myLastReading; } + /// Gets the number of sonar readings received in the last second + AREXPORT int getReadingCount(void); + // Function called in sensorInterp to indicate that a + // reading was received + AREXPORT virtual void internalGotReading(void); + + AREXPORT bool sendAlive(); + AREXPORT bool sendReset(); + AREXPORT bool sendStart(); + AREXPORT bool sendStop(); + AREXPORT bool sendGetTransducerCount(); + AREXPORT bool sendGetGain(unsigned char transducerNumber); + AREXPORT bool sendSetGain(unsigned char transducerNumber, unsigned char gain); + AREXPORT bool sendGetMaxRange(unsigned char transducerNumber); + AREXPORT bool sendSetMaxRange(unsigned char transducerNumber, int echoSampleSize); + AREXPORT bool sendGetThresholds(unsigned char transducerNumber); + AREXPORT bool sendSetThresholds(unsigned char transducerNumber, int thres); + AREXPORT bool sendGetNumThresholdRanges(); + /* + AREXPORT bool sendGetNoiseDelta(unsigned char transducerNumber); + AREXPORT bool sendSetNoiseDelta(unsigned char transducerNumber, int noiseDelta); + */ + AREXPORT bool sendGetDelay(); + AREXPORT bool sendSetDelay(unsigned char delay); + AREXPORT bool sendSetMask(unsigned char maskLsb, unsigned char maskMsb); + AREXPORT bool sendGetMask(); + AREXPORT bool validateTransducers(); + AREXPORT bool validateGain(); + AREXPORT bool validateDelay(); + AREXPORT bool validateThresholds(); + AREXPORT bool validateMaxRange(); + /* + AREXPORT bool validateNoiseDelta(); + */ + AREXPORT bool validateNumThresholdRanges(); + AREXPORT bool requestFirmwareVersion(); + AREXPORT bool queryFirmwareVersion(); + + /// Adds a callback for when disconnection happens because of an error + void addDisconnectOnErrorCB(ArFunctor *functor, + int position = 51) + { myDisconnectOnErrorCBList.addCallback(functor, position); } + + /// Removes a callback for when disconnection happens because of an error + void remDisconnectOnErrorCB(ArFunctor *functor) + { myDisconnectOnErrorCBList.remCallback(functor); } + + /// Number of Transducers from board query + int getNumTransducers(void) const + { return myNumTransducers; } + /// Number of Configured Transducers + int getNumConfiguredTransducers(void) const + { return myNumConfiguredTransducers; } + /// Board Delay + int getBoardDelay(void) const + { return myBoardDelay; } + /// + int getBoardGain(void) const + { return myBoardGain; } + /// + /* + int getBoardNoiseDelta(void) const + { return myBoardNoiseDelta; } + */ + /// + int getBoardDetectionThreshold(void) const + { return myBoardDetectionThreshold; } + /// + int getBoardMaxRange(void) const + { return myBoardMaxRange; } + + bool getBoardUseForAutonomousDriving(void) const + { return myBoardUseForAutonomousDriving; } + + /// + int getUnitMapping(int unit) const + { + std::map >::const_iterator iter = + mySonarMap.find(unit); + if (iter == mySonarMap.end()) + return -1; + else { + std::mapunitMap = iter->second; + return unitMap[SONAR_MAPPING]; + } } + + /// + int getUnitX(int unit) const + { + std::map >::const_iterator iter = + mySonarMap.find(unit); + if (iter == mySonarMap.end()) + return -1; + else { + std::mapunitMap = iter->second; + return unitMap[SONAR_X]; + } } + + /// + int getUnitY(int unit) const + { + std::map >::const_iterator iter = + mySonarMap.find(unit); + if (iter == mySonarMap.end()) + return -1; + else { + std::mapunitMap = iter->second; + return unitMap[SONAR_Y]; + } } + + /// + int getUnitTh(int unit) const + { + std::map >::const_iterator iter = + mySonarMap.find(unit); + if (iter == mySonarMap.end()) + return -1; + else { + std::mapunitMap = iter->second; + return unitMap[SONAR_TH]; + } } + + /// + int getUnitGain(int unit) const + { + std::map >::const_iterator iter = + mySonarMap.find(unit); + if (iter == mySonarMap.end()) + return -1; + else { + std::mapunitMap = iter->second; + return unitMap[SONAR_GAIN]; + } } + + /// + int getUnitDetectionThres(int unit) const + { + std::map >::const_iterator iter = + mySonarMap.find(unit); + if (iter == mySonarMap.end()) + return -1; + else { + std::mapunitMap = iter->second; + return unitMap[SONAR_DETECTION_THRES]; + } } + + /// + /* + int getUnitNoiseDelta(int unit) const + { + std::map >::const_iterator iter = + mySonarMap.find(unit); + if (iter == mySonarMap.end()) + return -1; + else { + std::mapunitMap = iter->second; + return unitMap[SONAR_NOISE_DELTA]; + } } + */ +#if 0 + /// + int getUnitThresClose(int unit) const + { + std::map >::const_iterator iter = + mySonarMap.find(unit); + if (iter == mySonarMap.end()) + return -1; + else { + std::mapunitMap = iter->second; + return unitMap[SONAR_THRES_CLOSE]; + } } + + /// + int getUnitThresMed(int unit) const + { + std::map >::const_iterator iter = + mySonarMap.find(unit); + if (iter == mySonarMap.end()) + return -1; + else { + std::mapunitMap = iter->second; + return unitMap[SONAR_THRES_MED]; + } } + + /// + int getUnitThresFar(int unit) const + { + std::map >::const_iterator iter = + mySonarMap.find(unit); + if (iter == mySonarMap.end()) + return -1; + else { + std::mapunitMap = iter->second; + return unitMap[SONAR_THRES_FAR]; + } } +#endif + /// + int getUnitLastReading(int unit) const + { + std::map >::const_iterator iter = + mySonarMap.find(unit); + if (iter == mySonarMap.end()) + return -1; + else { + std::mapunitMap = iter->second; + return unitMap[SONAR_LAST_READING]; + } } + + int getFirmwareVersion(void) const + { return myFirmwareVersion; } + + bool turnOnTransducers(); + + bool turnOffTransducers(); + + bool disableForAutonomousDriving(); + +enum Headers { + HEADER1=0xfa, + //HEADER2=0xfb + HEADER2=0xf5 + }; + + + +protected: + ArDeviceConnection *myConn; + + std::string myName; + char myNameWithBoard[100]; + std::string myDefaultPortType; + std::string myDefaultTcpPort; + + double myTimeoutSeconds; + bool myRobotRunningAndConnected; + + bool myTransducersAreOn; + + ArTime myLastReading; + + // packet count + time_t myTimeLastReading; + int myReadingCurrentCount; + int myReadingCount; + + ArCallbackList myDisconnectOnErrorCBList; + + ArRobot *myRobot; + ArFunctorC myProcessCB; + + AREXPORT virtual void sonarSetName(const char *name); + AREXPORT virtual void * runThread(void *arg); + + void sensorInterp(void); + void failedToConnect(void); + void clear(void); + bool myIsConnected; + bool myTryingToConnect; + bool myStartConnect; + + int myBoardNum; + int myNumTransducers; + int myNumConfiguredTransducers; + unsigned char myVersion; + //unsigned char mySonarDelay; + bool myWarnedAboutExtraSonar; + + unsigned int myBoardDelay; + unsigned int myBoardGain; + /* + unsigned int myBoardNoiseDelta; + */ + unsigned int myBoardDetectionThreshold; + unsigned int myBoardMaxRange; + + bool myBoardUseForAutonomousDriving; + + unsigned char myTransducerMaskLSB; + unsigned char myTransducerMaskMSB; + + unsigned char myAutonomousDrivingTransducerMaskLSB; + unsigned char myAutonomousDrivingTransducerMaskMSB; + + // first index is transducer reletive to this board + // second index is defined below + std::map > mySonarMap; + enum SonarInfo + { + SONAR_IS_CONFIGURED, + SONAR_MAPPING, + SONAR_X, + SONAR_Y, + SONAR_TH, + SONAR_GAIN, + /* + SONAR_NOISE_DELTA, + */ + SONAR_DETECTION_THRES, + SONAR_MAX_RANGE, + SONAR_USE_FOR_AUTONOMOUS_DRIVING, + SONAR_LAST_READING + }; + +enum Sizes { + maxTransducers=16 + }; + +enum Commands { + ALIVE=0x00, + START_SCAN=0x01, + STOP_SCAN=0x02, + RESET=0x03, + TAKE_SELF_ECHO=0x04, + GET_VERSION=0x10, + GET_NUM_TRANDUCERS=0x11, + GET_TRANSDUCER_MASK=0x12, + SET_TRANSDUCER_MASK=0x22, + GET_SONAR_DELAY=0x13, + SET_SONAR_DELAY=0x23, + GET_ECHO_SAMPLE_SIZE=0x14, + SET_ECHO_SAMPLE_SIZE=0x24, + GET_GAIN=0x17, + SET_GAIN=0x27, + NUM_THRESHOLD_RANGES=0x18, + GET_THRESHOLDS=0x19, + SET_THRESHOLDS=0x29, + GET_NOISE_DELTA=0x1A, + SET_NOISE_DELTA=0x2A + }; + + bool mySendTracking; + bool myRecvTracking; + + ArLog::LogLevel myLogLevel; + + //ArSonarMTXPacketReceiver myReceiver; + ArRobotPacketReceiver *myReceiver; + ArRobotPacketSender *mySender; + + ArMutex myPacketsMutex; + ArMutex myDataMutex; + ArMutex myDeviceMutex; + + ArLog::LogLevel myInfoLogLevel; + + //std::list myPackets; + std::list myPackets; + + int myFirmwareVersion; + + ArTime myPrevSensorIntTime; + + ArFunctorC mySensorInterpTask; + ArRetFunctorC myAriaExitCB; + +}; + + + +#endif // ARSONARDEVICE_H diff --git a/Legacy/Aria/include/ArSonyPTZ.h b/Legacy/Aria/include/ArSonyPTZ.h new file mode 100644 index 0000000..2ec62d2 --- /dev/null +++ b/Legacy/Aria/include/ArSonyPTZ.h @@ -0,0 +1,124 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARSONYPTZ_H +#define ARSONYPTZ_H + +#include "ariaTypedefs.h" +#include "ArBasePacket.h" +#include "ArPTZ.h" + +/// A class for for making commands to send to the sony +/** There are only two functioning ways to put things into this packet, you + MUST use thse, if you use anything else your commands won't work. You + must use uByteToBuf and byte2ToBuf. +*/ +class ArSonyPacket: public ArBasePacket +{ +public: + /// Constructor + AREXPORT ArSonyPacket(ArTypes::UByte2 bufferSize = 15); + AREXPORT virtual ~ArSonyPacket(); + + AREXPORT virtual void uByteToBuf(ArTypes::UByte val); + AREXPORT virtual void byte2ToBuf(ArTypes::Byte2 val); + /// This is a new function, read the details before you try to use it + AREXPORT void byte2ToBufAtPos(ArTypes::Byte2 val, ArTypes::UByte2 pose); +}; + +class ArRobot; + +/// A class to use the sony pan tilt zoom unit + +class ArSonyPTZ : public ArPTZ +{ +public: + AREXPORT ArSonyPTZ(ArRobot *robot); + AREXPORT virtual ~ArSonyPTZ(); + + AREXPORT virtual bool init(void); + AREXPORT virtual const char *getTypeName() { return "sony"; } +protected: + AREXPORT virtual bool pan_i(double degrees); + AREXPORT virtual bool panRel_i(double degrees); + AREXPORT virtual bool tilt_i(double degrees); + AREXPORT virtual bool tiltRel_i(double degrees); + AREXPORT virtual bool panTilt_i(double degreesPan, double degreesTilt); + AREXPORT virtual bool panTiltRel_i(double degreesPan, double degreesTilt); +public: + AREXPORT virtual bool canZoom(void) const { return true; } + AREXPORT virtual bool zoom(int zoomValue); + AREXPORT virtual bool zoomRel(int zoomValue); +protected: + AREXPORT virtual double getPan_i(void) const { return myPan; } + AREXPORT virtual double getTilt_i(void) const { return myTilt; } +public: + AREXPORT virtual int getZoom(void) const { return myZoom; } + + + AREXPORT virtual bool canGetFOV(void) { return true; } + /// Gets the field of view at maximum zoom + AREXPORT virtual double getFOVAtMaxZoom(void) { return 4.4; } + /// Gets the field of view at minimum zoom + AREXPORT virtual double getFOVAtMinZoom(void) { return 48.8; } + + AREXPORT bool backLightingOn(void); + AREXPORT bool backLightingOff(void); + //AREXPORT bool packetHandler(ArRobotPacket *packet); + /* unused? + enum { + MAX_PAN = 95, ///< maximum degrees the unit can pan (either direction) + MAX_TILT = 25, ///< maximum degrees the unit can tilt (either direction) + MIN_ZOOM = 0, ///< minimum value for zoom + MAX_ZOOM = 1023 ///< maximum value for zoom + }; + */ + + /// called automatically by Aria::init() + ///@since 2.7.6 + ///@internal +#ifndef SWIG + static void registerPTZType(); +#endif + +protected: + void initializePackets(void); + ArRobot *myRobot; + double myPan; + double myTilt; + int myZoom; + double myDegToTilt; + double myDegToPan; + ArSonyPacket myPacket; + ArSonyPacket myZoomPacket; + ArSonyPacket myPanTiltPacket; + + ///@since 2.7.6 + static ArPTZ* create(size_t index, ArPTZParams params, ArArgumentParser *parser, ArRobot *robot); + ///@since 2.7.6 + static ArPTZConnector::GlobalPTZCreateFunc ourCreateFunc; +}; + +#endif // ARSONYPTZ_H diff --git a/Legacy/Aria/include/ArSoundPlayer.h b/Legacy/Aria/include/ArSoundPlayer.h new file mode 100644 index 0000000..ebea788 --- /dev/null +++ b/Legacy/Aria/include/ArSoundPlayer.h @@ -0,0 +1,123 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ + +#ifndef _ARSOUNDPLAYER_H_ +#define _ARSOUNDPLAYER_H_ + + +#include "ArFunctor.h" + + + +/** + * @brief This class provides a cross-platform interface for playing short sound samples. + * (Currently implemented for Windows and Linux). + * @sa For I/O and network transfer of encoded audio, see the ArNetAudio library. + * @sa ArSoundsQueue + * + * @note Uses an external program to play WAV files on Linux. If an environment + * variable named PLAY_WAV is set, that program is used, otherwise, 'play' from + * the 'sox' toolset is used. PLAY_WAV must contain one word (the command; no arguments) + * A call to playWavFile() will return immediately after + * 'play' has finished, even though Linux may still be playing back the sound data. In general, + * this kind of thing is a problem, especially with speech recognition immediately after playing + * a sound. Ideally, we should be able to truly block until the sound has finished playback. + * Alas, it is not an ideal world. Another potential pitfall due to the use of + * an external program invocation: the program you call must not attempt to + * issue any output. 'play' from the 'sox' toolset automatically supresses + * normal output if it isn't called from an interactive terminal, but it may + * still issue some error messages, which will cause it to hang indefinately. + * + * The volume (level) of audio output from a robot is determined by two things: + * the computer sound device mixer, and also the amplifier which drives the + * speakers. The computer's mixer can be adjusted through the operating system: + * on Linux, you can use the 'aumix' program to adjust the Master and PCM + * levels. On Windows, use the Windows mixer program. If on Linux, ArSoundPlayer also + * prodives the setVolume() method, which adjusts the volume of the sound before + * it is played. + * + @ingroup UtilityClasses + */ +class ArSoundPlayer +{ + public: + /** Play a WAV (Windows RIFF) file + * @note Uses an external program to play WAV files on Linux. If an environment + * variable named PLAY_WAV is set, that program is used, otherwise, 'play' from + * the 'sox' toolset is used. See detailed note in the overview for this + * cass. + * @param filename Name of the file to play + * @param params ignored + */ + AREXPORT static bool playWavFile(const char* filename, const char* params); + + AREXPORT static bool playWavFile(const char* filename) { return playWavFile(filename, NULL); } + + /** Play a file in some native file format for the compilation platform. */ + AREXPORT static bool playNativeFile(const char* filename, const char* params); + + /** Cancel (interrupt) any current sound or file playback. */ + AREXPORT static void stopPlaying(); + + /** Return the static functor for playWavFile */ + AREXPORT static ArRetFunctor2 *getPlayWavFileCallback(); + + /** Return the static functor for stopPlaying(). */ + AREXPORT static ArFunctor* getStopPlayingCallback(); + + /** Play raw uncompressed PCM16 sound data. The format of this data is + * numSamples samples of two bytes each. Each byte pair is a signed little endian + * integer. + * The sound will be played back at 16kHz, monaurally. + * @return false on error, true on success. + */ + AREXPORT static bool playSoundPCM16(char* data, int numSamples); + + /** Set a volume adjustment applied to all sounds right before playing. + (So this adjusts the volume in addition to, not instead of, the + computer audio mixer). + Any value less than or equal to 0 is no volume i.e. muted or no output. + @linuxonly + */ + AREXPORT static void setVolume(double v); + + /** + Set volume as a "percent" of normal, where 100% is normal or natural + volume, 50% is increased by 50%, -50% is decreased by 50%, etc. (-100.0% is + no volume, or mute.) + @linuxonly + */ + AREXPORT static void setVolumePercent(double pct); + +protected: + static int ourPlayChildPID; ///< Only used on Linux. + static ArGlobalRetFunctor2 ourPlayWavFileCB; + static ArGlobalFunctor ourStopPlayingCB; + static double ourVolume; +}; + + +#endif // _ARSOUNDPLAYER_H_ diff --git a/Legacy/Aria/include/ArSoundsQueue.h b/Legacy/Aria/include/ArSoundsQueue.h new file mode 100644 index 0000000..17a65e0 --- /dev/null +++ b/Legacy/Aria/include/ArSoundsQueue.h @@ -0,0 +1,557 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ + +#ifndef ARSOUNDSQUEUE_H +#define ARSOUNDSQUEUE_H + + +#include "ariaTypedefs.h" +#include "ArASyncTask.h" +#include "ArCondition.h" +#include "ArFunctor.h" +#include "ArSpeech.h" +#include +#include +#include + +/** + * @brief This class manages a queue of items to play as WAV files or as text to + * speak using a speech synthesizer. + * + * The actual playback of sound and speech is done through callbacks + * (which you can supply in the constructor or afterwards). + * Some callbacks you can use are provided by classes like ArSoundPlayer (for sound file + * playback) and ArFestival (from the ArSpeechSynth_Festival library) and ArCepstral + * (from the ArSpeechSynth_Cepstral librrary) for speech synthesis. + * + * Add sound files to the queue with play(), and text to speak with + * speak(). Use runAsync() to run + * the processing thread in the background, or run() to run synchronously in the + * current thread. + * + * + * @sa ArSoundPlayer + * @sa @ref soundsQueueExample.cpp + * + @ingroup UtilityClasses + */ + +class ArSoundsQueue: public ArASyncTask +{ +public: + + /** Opaque identifier for the type of an item in the sound queue. Not used + * during processing, but may be used to search for items in the queue. */ + enum ItemType { SPEECH, SOUND_FILE, SOUND_DATA, OTHER }; + + /** Callback for playing a queue item. First argument is the "data", second is + * item type-specific "parameters". Return true to continue processing more + * callbacks in a list, false to cancel processing. + */ + typedef ArRetFunctor2 PlayItemFunctor; + typedef ArFunctor InterruptItemFunctor; + + /** Callback types for determining whether to commence playing an item, + * or skipping it. + */ + typedef ArRetFunctor PlaybackConditionFunctor; + + /** A sound item in the queue, with callbacks for dealing with the + * item and the data to pass to those callbacks. + */ + class Item { + public: + std::string data; + ItemType type; + std::string params; + int priority; + std::list interruptCallbacks; + std::list playCallbacks; + std::list doneCallbacks; + std::list playbackConditionCallbacks; + + AREXPORT Item(); + AREXPORT Item(std::string _data, ItemType _type, std::string _params = "", int priority = 0); + AREXPORT Item(std::string _data, ItemType _type, std::string _params, int priority, std::list callbacks); + + AREXPORT Item(const ArSoundsQueue::Item& toCopy); + + /** Note: does not compare priority! */ + bool operator==(const Item& other) const + { + return (other.type == type && other.params == params && other.data == data); + } + + /** Called by sound queue to play this item by calling play callbacks. */ + void play(); + + /** Called by sound queue to interrupt this item by calling interrupt + * callbacks. */ + void interrupt(); + + /** Called by sound queue thread after playing this item by calling done + * callbacks. */ + void done(); + }; + + + AREXPORT ArSoundsQueue(); + + /** @deprecated + * @see addInitCallback() + * @see setSpeakCallback() + * @see setInterruptSpeechCallback() + * @see setPlayFileCallback + * @see setInterruptFileCallback + */ + AREXPORT ArSoundsQueue(ArRetFunctor *speakInitCB, + PlayItemFunctor *speakCB = 0, + InterruptItemFunctor *interruptSpeechCB = 0, + ArRetFunctor *playInitCB = 0, + PlayItemFunctor *playFileCB = 0, + InterruptItemFunctor *interruptFileCB = 0); + + /** Set default speech and WAV file callbacks for use + * by the convenience methods speak() and play(). + * Omit the last three arguments to use + * callbacks into ArSoundPlayer. + */ + AREXPORT ArSoundsQueue(ArSpeechSynth* speechSynthesizer, + ArRetFunctor *playInitCB = 0, + PlayItemFunctor *playFileCB = 0, + InterruptItemFunctor *interruptFileCB = 0); + + AREXPORT virtual ~ArSoundsQueue(); + + /** Add a callback to be called when the sound queue begins to run in its + * thread. (For example, the speech synthesizers must be initialized in + * the same thread as they are used.) + */ + AREXPORT void addInitCallback(ArRetFunctor *cb) { + myInitCallbacks.push_back(cb); + } + + /** @deprecated */ + AREXPORT void setSpeakInitCallback(ArRetFunctor *cb) { + addInitCallback(cb); + } + + /** Add (a copy of) the given item to the queue. */ + AREXPORT void addItem(ArSoundsQueue::Item item); + + /** Create a new queue item with the given data and add to the queue. */ + AREXPORT void addItem(ItemType type, const char* data, std::list callbacks, int priority = 0, const char* params = 0); + + /** Return true if all initialization callbacks have completed, false + * otherwise. + */ + AREXPORT bool isInitialized() + { + return myInitialized; + } + + /** @deprecated + * @see isPlaying() + */ + AREXPORT bool isSpeakingOrPlaying(void) { return (myPlayingSomething); } + + /// Returns true if an item is currently being played. + AREXPORT bool isPlaying() { return myPlayingSomething; } + + + /** @deprecated + * @return true if any queue item is being played. + * @see isPlaying() + */ + AREXPORT bool isSpeaking() { return myPlayingSomething; } + + + /// Begin processing the sounds queue synchronously (in this thread; does not return) + AREXPORT void run(void) { runInThisThread(); } + + /// Begin processing the sounds queue in a background thread + AREXPORT void runAsync(void) { create(false); } + + /** Temporarily stop processing the sounds queue. (Any currently playing sound + or speech utterance will finish. The sound device may remain open.) + */ + AREXPORT void pause(); + + /// Resume processing the sounds queue + AREXPORT void resume() ; + + /** @return true if the queue is paused */ + AREXPORT bool isPaused(); + + /// If sound is currently being played or speech is being spoken, interrupt it. (but continue processing the queue). SoundFinished callbacks will not be called. + AREXPORT void interrupt(); + + /** Empty the queue. If a sound is currently playing, it will not be interrupted. + QueueEmpty callbacks will be called. SoundFinished callbacks will not be + called. + */ + AREXPORT void clearQueue(); + + /** End the processing thread. + * This function is deprecated. Use stopRunning() instead. + * @deprecated + This shuts down the sound queue completely. To + temporarily stop the queue processing, use pause(). To interrupt the + currently playing sound, use interrupt(). + */ + AREXPORT void stop() ; + + /// Create and return a new a functor for pause(), which other modules can use to pause this sounds + /// queue. + AREXPORT ArFunctor* getPauseCallback() + { + return new ArFunctorC(this, &ArSoundsQueue::pause); + } + + /// Create and return a new functor for resume(), which other modules can use to resume this + /// sounds queue. + AREXPORT ArFunctor* getResumeCallback() + { + return new ArFunctorC(this, &ArSoundsQueue::resume); + } + + + /// Get the current size of the speech/sound playback queue. + AREXPORT size_t getCurrentQueueSize() + { + size_t size; + lock(); + size = myQueue.size(); + unlock(); + return size; + } + + /** Add a callback functor to be invoked when playback of one sound or speech utterance starts. */ + AREXPORT void addSoundStartedCallback(ArFunctor* f) + { + myStartPlaybackCBList.push_back(f); + } + + /** Remove a callback functor to be invoked when playback one sound or speech utterance starts. */ + AREXPORT void remSoundStartedCallback(ArFunctor* f) + { + myStartPlaybackCBList.remove(f); + } + + /** Add a callback functor to be invoked when plackback of one sound or speech + * utterance finishes */ + AREXPORT void addSoundFinishedCallback(ArFunctor* f) + { + myEndPlaybackCBList.push_back(f); + } + + /** Remove a callback functor to be invoked when plackback of one sound or + * speech utterance finishes. */ + AREXPORT void remSoundFinishedCallback(ArFunctor* f) + { + myEndPlaybackCBList.remove(f); + } + + /** Add a callback functor to be invoked when playback of one sound or speech utterance starts. */ + AREXPORT void addSoundItemStartedCallback( + ArFunctor1 *f) + { + myStartItemPlaybackCBList.push_back(f); + } + + /** Remove a callback functor to be invoked when playback one sound or speech utterance starts. */ + AREXPORT void remSoundItemStartedCallback( + ArFunctor1 *f) + { + myStartItemPlaybackCBList.remove(f); + } + + /** Add a callback functor to be invoked when plackback of one sound or speech + * utterance finishes */ + AREXPORT void addSoundItemFinishedCallback( + ArFunctor1 *f) + { + myEndItemPlaybackCBList.push_back(f); + } + + /** Remove a callback functor to be invoked when plackback of one sound or + * speech utterance finishes. */ + AREXPORT void remSoundItemFinishedCallback( + ArFunctor1 *f) + { + myEndItemPlaybackCBList.remove(f); + } + + /** Add a callback functor to be invoked when a the sound queue becomes + * non-empty, that is, when a block of sounds/speech utterances begins. + */ + AREXPORT void addQueueNonemptyCallback(ArFunctor* f) + { + myQueueNonemptyCallbacks.push_back(f); + } + + /** Remove a functor added by addQueueNonemptyCallback(). */ + AREXPORT void remQueueNonemptyCallback(ArFunctor* f) + { + myQueueNonemptyCallbacks.remove(f); + } + + /** Add a callback functor to be invoked when the sound queue becomes empty + * and the last sound has finished playing, + * that is, when a block of sounds/speech utterances ends. This will not + * be called when the sound queue first begins running. + */ + AREXPORT void addQueueEmptyCallback(ArFunctor* f) + { + myQueueEmptyCallbacks.push_back(f); + } + + /** Remove a functor added by addQueueEmptyCallback() */ + AREXPORT void remQueueEmptyCallback(ArFunctor* f) + { + myQueueEmptyCallbacks.remove(f); + } + + + + /** Find items waiting in the queue. This is mainly useful in finding + * speech text. + * @param item Item to search for. + * @return A set of positions in the queue. 1 indicates the next sound that will + * play, followed by 2, etc. + * @note You have a potential race condition if an item is removed from the queue + * after this method returns, but before you on the information returned. + * For best results, pause the sound queue while using this information. + */ + AREXPORT std::set findPendingItems(const char* item); + + /** Remove pending items with the given data and type. */ + AREXPORT void removePendingItems(const char* item, ItemType type); + + /** Remove pending items with the given data. */ + AREXPORT void removePendingItems(const char* data); + + /** Remove pending items with a priority less than that given. */ + AREXPORT void removePendingItems(int priority); + + /** Remove pending items with priority less the given priority and with the given type. */ + AREXPORT void removePendingItems(int priority, ItemType type); + + /** Remove pending items with the given type. */ + AREXPORT void removePendingItems(ItemType type); + + /** Remove pending and current items with a priority less than that given. */ + AREXPORT void removeItems(int priority); + + /** Removes pending and current items with the same data and type as the given item **/ + AREXPORT void removeItems(Item item); + + AREXPORT std::string nextItem(ItemType type); + AREXPORT std::string nextItem(int priority); + AREXPORT std::string nextItem(ItemType type, int priority); + + /// Convenience methods for special speech synthesis and WAV file queue items: + //@{ + + /** + * As a convenience, you may set a "default" speech synthesis callback, + * and then simply use the speak() method to add a speech item to the queue + * with those callbacks. + * @sa Item + */ + AREXPORT void setSpeakCallback(PlayItemFunctor *cb) { + myDefaultSpeakCB = cb; + } + + /** Set the "default" callback to interrupt a current speech utterance, used + * by speak() + * @sa Item + */ + AREXPORT void setInterruptSpeechCallback(InterruptItemFunctor *cb) { + myDefaultInterruptSpeechCB = cb; + } + + /** As a convenience, you may set a "default" WAV file playback callback, + * and then simply use the play() method to add the file to the queue with + * this callback. + * @sa Item + */ + AREXPORT void setPlayFileCallback(PlayItemFunctor *cb) { + myDefaultPlayFileCB = cb; + } + + /** @deprecated use setPlayFileCallback() */ + AREXPORT void setPlayWavFileCallback(PlayItemFunctor* cb) { + setPlayFileCallback(cb); + } + + /** Set the "default" callback to interrupt current wav file playback, for use + * by the play() convenience method. + * @sa Item + */ + AREXPORT void setInterruptFileCallback(InterruptItemFunctor *cb) { + myDefaultInterruptFileCB = cb; + } + + /** @deprecated use setInterruptFileCallback() */ + AREXPORT void setInterruptWavFileCallback(InterruptItemFunctor* cb) { + setInterruptFileCallback(cb); + } + + + /** Add text string item to the queue for speech synthesis. The text will be + * sent to the "speak" callback, if set, otherwise the SynthesiseToSound and + * PlaySynthesizedSound callbacks are used, if set. + */ + AREXPORT void speak(const char *str); + + /** Add a sound file to the queue for default sound file playback. */ + AREXPORT void play(const char *filename); + +#if !(defined(WIN32) && defined(_MANAGED)) && !defined(SWIG) + + /** Add a formatted text string (like printf) to the queue configured for default speech + * synthesis. When reached in the queue while running, the text will be + * sent to the "speak" callback, if set, otherwise, the "SythesizeToSound" and + * "PlaySynthesizedSound" callbacks will be used (if they are set.) + * + * @param fmt Format string. + * @param ... Arguments to format into the format string. + */ + AREXPORT void speakf(const char *fmt, ...); + + + /** Speak with alternate voice. */ + AREXPORT void speakWithVoice(const char* voice, const char* fmt, ...); + + /** Speak with alternate priority. */ + AREXPORT void speakWithPriority(int priority, const char* fmt, ...); + + /** Add a sound file to the queue for default sound file playback. + * + * @param filename_fmt Format string for determining the filename of the WAV + * file, same as printf(). + * @param ... If given, arguments to format into the format string. + */ + AREXPORT void playf(const char *filename_fmt, ...); + +#endif // MS Managed C++ or SWIG + + /** Return an item set up for speech with previously set default speech + * callbacks. + * @param speech Text to speak (optional) + * @see setSpeechCallback() + * @see addItem() + */ + AREXPORT ArSoundsQueue::Item createDefaultSpeechItem(const char* speech = 0); + + /** Return an item set up for sound file playback with previously set default + * play callbacks. + * @param filename Filename to set (optional) + * @see setPlayFileCallback() + * @see addItem() + */ + AREXPORT ArSoundsQueue::Item createDefaultFileItem(const char* filename = 0); + + //@} + + /** Set a playback condition functor used for default speech and sound file + * items. Set to NULL to clear. */ + AREXPORT void setDefaultPlayConditionCB(PlaybackConditionFunctor* f) { + myDefaultPlayConditionCB = f; + } + + /// main function for thread + /** @internal */ + AREXPORT virtual void *runThread(void *arg); + +protected: + bool myInitialized; + std::list myQueue; + ArMutex myQueueMutex; + void lock() { + myQueueMutex.lock(); + } + void unlock() { + myQueueMutex.unlock(); + } + bool tryLock() { + return myQueueMutex.tryLock(); + } + + /// Functors to invoke when we start running in our thread + std::list< ArRetFunctor* > myInitCallbacks; + + bool myPlayingSomething; + Item myLastItem; ///< The current or most recent item played. + + /// Used by speak() and play() convenience methods: + //@{ + PlayItemFunctor *myDefaultSpeakCB; + InterruptItemFunctor *myDefaultInterruptSpeechCB; + PlayItemFunctor *myDefaultPlayFileCB; + InterruptItemFunctor *myDefaultInterruptFileCB; + //@} + + int myPauseRequestCount; ///< Semaphore for doing pausing and resuming of the queue + ArCondition myPausedCondition; ///< Condition variable used by the thread to pause + + /// Functors to invoke during queue processing + //@{ + std::list myStartPlaybackCBList; + std::list myEndPlaybackCBList; + std::list *> myStartItemPlaybackCBList; + std::list *> myEndItemPlaybackCBList; + std::list myQueueNonemptyCallbacks; + std::list myQueueEmptyCallbacks; + //@} + + PlaybackConditionFunctor* myDefaultPlayConditionCB; ///< Used when creating default configured speech and sound file items + + /// Invoke each functor in a list + void invokeCallbacks(const std::list& lst); + + /// Invoke each functor in a list, but stop if any of them return false. + void invokeCallbacks(const std::list*>& lst); + + /** push item onto queue + * @sa addItem() + */ + //@{ + void pushQueueItem(Item item); + void pushQueueItem_NoLock(Item item); + //@} + + /** Pop item from queue and return it */ + //@{ + Item popQueueItem(); + Item popQueueItem_NoLock(); + //@} + +}; + +#endif + diff --git a/Legacy/Aria/include/ArSpeech.h b/Legacy/Aria/include/ArSpeech.h new file mode 100644 index 0000000..f299e5f --- /dev/null +++ b/Legacy/Aria/include/ArSpeech.h @@ -0,0 +1,166 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +/* $Id: ArSpeech.h,v 1.15 2007-08-27 21:48:33 reed Exp $ */ + +#ifndef ARSPEECH_H +#define ARSPEECH_H + +#include "ariaTypedefs.h" +#include "ArFunctor.h" +#include "ArConfig.h" +#include +#include + + +/** @brief Abstract interface to speech synthesis. + * + * This class defines the abstract interface for speech synthesizers + * used with Aria. + * Implementations are provided in the separate ArSpeechSynth_Cepstral and + * ArSpeechSynth_Festival libraries. + * This class provides a common-denominator + * interface. Implementations (especially ArCepstral) may support more + * features, or behave differently; refer to their documentation for more + * information. + * + * This class registers one parameter with the global ArConfig object in the + * "Speech Synthesis" section: The parameter is named "voice" and sets the voice + * used for speech synthesis, if multiple voices is supported and the + * new voice can be loaded. + */ + +class ArSpeechSynth +{ +public: + + /** Don't forget to call this from derived classes. */ + AREXPORT ArSpeechSynth(); + + AREXPORT virtual ~ArSpeechSynth(); + + + /** Perform synthesizer initialization, if necessary. You must call + * this method. + * + * (Subclass implementations should call this method *after* initializing their + * speech engine.) + */ + AREXPORT virtual bool init(); + + /** Use the given ArConfig object to read parameters such as voice, speaking + * rate, volume. + */ + AREXPORT virtual void addToConfig(ArConfig *config); + + /** Speaks the given text. + * @param str The text to speak. + * @param voiceParams Voice selection criteria expression + * (implementation-specific) + * @param audioOutputCB If not NULL, send synthesized audio data to this + * callback (may be called several times). Otherwise, play using default + * AudioCallback, or directly out the speakers + * @param sampleRate if given, temporarily use this sample rate for this + * speech, then restore. If 0, use current sample rate. + */ + AREXPORT virtual bool speak(const char *str, const char* voiceParams, ArRetFunctor2* audioOutputCB, unsigned short sampleRate = 0) = 0; + + /** Speaks the given text. + * @param str The text to speak. + * @param voiceParams Voice selection criteria expression + * (implementation-specific) + */ + AREXPORT virtual bool speak(const char *str, const char* voiceParams = NULL); + + /** Speaks the given string, using current voice and output settings, + * taking varargs and a format string (like printf) + */ + AREXPORT virtual bool speakf(const char* fmt, ...) = 0; + + /** If any speech is currently ongoing, interrupt it. + */ + AREXPORT virtual void interrupt() = 0; + + /** @return a functor for init() to use with ArSoundsQueue */ + AREXPORT ArRetFunctorC* getInitCallback(); + + /** @return a functor for speak() to use with ArSoundsQueue */ + AREXPORT ArRetFunctor2C* getSpeakCallback(void) ; + + + /** @return a functor for interrupt() */ + AREXPORT ArFunctorC* getInterruptCallback(); + + + /** Instead of playing synthesized audio using the synthesizer's internal + * audio playback, call the given callback when a chunk of audio has + * been synthesized. Audio is passed to the callback in the first parameter + * as signed 16-bit samples (PCM16). The sample rate is 16kHz but may be + * changed with setAudioSampleRate(). The second parameter is the number + * of samples. The return value from the callback is ignored. + */ + AREXPORT void setAudioCallback(ArRetFunctor2* cb); + + + /** Change audio sample rate (Hz). Normal rate is 16000 Hz. + * Suggested values are 8000, 16000, or 44400 + */ + AREXPORT virtual void setAudioSampleRate(int rate) = 0; + + AREXPORT virtual int getAudioSampleRate() = 0; + + /** Lock, if neccesary */ + AREXPORT virtual void lock() { } + /** Unlock, if neccesary */ + AREXPORT virtual void unlock() { } + + /** Set the current voice by name. + * Replaces fully any previous required voice criteria. + * @sa getVoiceNames + */ + AREXPORT virtual bool setVoice(const char* name) = 0; + + /** Get name of current voice, if set with setVoice (else returns NULL) */ + AREXPORT virtual const char* getCurrentVoiceName() = 0; + + /** Return a list of available voice names, if possible. */ + AREXPORT virtual std::list getVoiceNames() = 0; + +protected: + ArRetFunctor2C mySpeakCB; + ArRetFunctorC myInitCB; + ArFunctorC myInterruptCB; + ArRetFunctor2 *myAudioPlaybackCB; ///< If set, send audio to this callback instead of playing it directly +private: + ArRetFunctorC myProcessConfigCB; + char myConfigVoice[32]; + bool processConfig(); + void addVoiceConfigParam(ArConfig *config); + +}; + + + +#endif diff --git a/Legacy/Aria/include/ArStringInfoGroup.h b/Legacy/Aria/include/ArStringInfoGroup.h new file mode 100644 index 0000000..1ffb0bf --- /dev/null +++ b/Legacy/Aria/include/ArStringInfoGroup.h @@ -0,0 +1,99 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARSTRINGINFOGROUP_H +#define ARSTRINGINFOGROUP_H + +#include "ariaUtil.h" +#include "ArMutex.h" +#include +#include +#include + +/** + This class takes callbacks from different classes that want this + string information and then lets you just add the information here + instead of to each individual class. + + @ingroup OptionalClasses + **/ +class ArStringInfoGroup +{ +public: + /// Constructor + AREXPORT ArStringInfoGroup(); + /// Destructor + AREXPORT virtual ~ArStringInfoGroup(); + /// Adds a string to the list in the raw format + AREXPORT bool addString(const char *name, ArTypes::UByte2 maxLen, + ArFunctor2 *functor); + + /// Adds an int to the list in the helped way + AREXPORT bool addStringInt(const char *name, ArTypes::UByte2 maxLen, + ArRetFunctor *functor, + const char *format = "%d"); + + /// Adds a double to the list in the helped way + AREXPORT bool addStringDouble(const char *name, ArTypes::UByte2 maxLen, + ArRetFunctor *functor, + const char *format = "%g"); + + /// Adds a bool to the list in the helped way + AREXPORT bool addStringBool(const char *name, ArTypes::UByte2 maxLen, + ArRetFunctor *functor, + const char *format = "%s"); + + /// Adds a string to the list in the helped way + AREXPORT bool addStringString(const char *name, ArTypes::UByte2 maxLen, + ArRetFunctor *functor, + const char *format = "%s"); + + /// Adds an int to the list in the helped way + AREXPORT bool addStringUnsignedLong(const char *name, + ArTypes::UByte2 maxLen, + ArRetFunctor *functor, + const char *format = "%lu"); + + /// Adds an int to the list in the helped way + AREXPORT bool addStringLong(const char *name, + ArTypes::UByte2 maxLen, + ArRetFunctor *functor, + const char *format = "%ld"); + + /// This is the function to add a callback to be called by addString + AREXPORT void addAddStringCallback( + ArFunctor3 *> *functor, + ArListPos::Pos position = ArListPos::LAST); + +protected: + ArMutex myDataMutex; + std::set myAddedStrings; + std::list *> *> myAddStringCBList; +}; + + +#endif // ARSTRINGINFOHELPER_H diff --git a/Legacy/Aria/include/ArSyncLoop.h b/Legacy/Aria/include/ArSyncLoop.h new file mode 100644 index 0000000..71fb0f2 --- /dev/null +++ b/Legacy/Aria/include/ArSyncLoop.h @@ -0,0 +1,61 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARSYNCLOOP_H +#define ARSYNCLOOP_H + + +#include "ariaTypedefs.h" +#include "ArASyncTask.h" +#include "ArSyncTask.h" + + +class ArRobot; + + +class ArSyncLoop : public ArASyncTask +{ +public: + + AREXPORT ArSyncLoop(); + AREXPORT virtual ~ArSyncLoop(); + + AREXPORT void setRobot(ArRobot *robot); + + AREXPORT void stopRunIfNotConnected(bool stopRun); + AREXPORT virtual void * runThread(void *arg); + + AREXPORT virtual const char *getThreadActivity(void); + + +protected: + bool myStopRunIfNotConnected; + ArRobot *myRobot; + bool myInRun; + +}; + + +#endif // ARSYNCLOOP_H diff --git a/Legacy/Aria/include/ArSyncTask.h b/Legacy/Aria/include/ArSyncTask.h new file mode 100644 index 0000000..59d32da --- /dev/null +++ b/Legacy/Aria/include/ArSyncTask.h @@ -0,0 +1,164 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARSYNCTASK_H +#define ARSYNCTASK_H + +#include +#include +#include "ariaTypedefs.h" +#include "ArFunctor.h" +#include "ArTaskState.h" + +/// Class used internally to manage the tasks that are called every cycle +/** + This is used internally, no user should normally have to create one, but + serious developers may want to use the members. Most users will be able to + add user tasks via the ArRobot class. + + The way it works is that each instance is a node in a tree. The only node + that should ever be created with a new is the top one. The run and print + functions both call the run/print on themselves, then on all of their + children, going from lowest numbered position to highest numbered, lower + going first. There are no hard limits to the position, it can be any + integer. ARIA uses the convention of 0 to 100, when you add things of + your own you should leave room to add in between. Also you can add things + with the same position, the only effect this has is that the first addition + will show up first in the run or print. + + After the top one is created, every other task should be created with + either addNewBranch() or addNewLeaf(). Each node can either be a branch node + or a list node. The list (a multimap) of branches/nodes is ordered + by the position passed in to the add function. addNewBranch() adds a new + branch node to the instance it is called on, with the given name and + position. addNewLeaf() adds a new leaf node to the instance it is called on, + with the given name and position, and also with the ArFunctor given, this + functor will be called when the leaf is run. Either add creates the new + instance and puts it in the list of branches/nodes in the approriate spot. + + The tree takes care of all of its own memory management and list management, + the "add" functions put into the list and creates the memory, conversely + if you delete an ArSyncTask (which is the correct way to get rid of one) + it will remove itself from its parents list. + + If you want to add something to the tree the proper way to do it is to get + the pointer to the root of the tree (ie with ArRobot::getSyncProcRoot) and + then to use find on the root to find the branch you want to travel down, + then continue this until you find the node you want to add to. Once there + just call addNewBranch or addNewLeaf and you're done. + + The state of a task can be stored in the target of a given ArTaskState::State pointer, + or if NULL than ArSyncTask will use its own member variable. + + @internal +*/ + +class ArSyncTask +{ +public: + /// Constructor, shouldn't ever do a new on anything besides the root node + AREXPORT ArSyncTask(const char *name, ArFunctor * functor = NULL, + ArTaskState::State *state = NULL, + ArSyncTask * parent = NULL); + /// Destructor + AREXPORT virtual ~ArSyncTask(); + + /// Runs the node, which runs all children of this node as well + AREXPORT void run(void); + /// Prints the node, which prints all the children of this node as well + AREXPORT void log(int depth = 0); + + /// Gets the state of the task + AREXPORT ArTaskState::State getState(void); + /// Sets the state of the task + AREXPORT void setState(ArTaskState::State state); + + /// Finds the task in the instances list of children, by name + AREXPORT ArSyncTask *findNonRecursive(const char *name); + /// Finds the task in the instances list of children, by functor + AREXPORT ArSyncTask *findNonRecursive(ArFunctor *functor); + + /// Finds the task recursively down the tree by name + AREXPORT ArSyncTask *find(const char *name); + /// Finds the task recursively down the tree by functor + AREXPORT ArSyncTask *find(ArFunctor *functor); + + /// Returns what this is running, if anything (recurses) + AREXPORT ArSyncTask *getRunning(void); + + /// Adds a new branch to this instance + AREXPORT void addNewBranch(const char *nameOfNew, int position, + ArTaskState::State *state = NULL); + /// Adds a new leaf to this instance + AREXPORT void addNewLeaf(const char *nameOfNew, int position, + ArFunctor *functor, + ArTaskState::State *state = NULL); + + /// Gets the name of this task + AREXPORT std::string getName(void); + + /// Gets the functor this instance runs, if there is one + AREXPORT ArFunctor *getFunctor(void); + + /// Sets the functor called to get the cycle warning time (should only be used from the robot) + AREXPORT void setWarningTimeCB( + ArRetFunctor *functor); + /// Gets the functor called to get the cycle warning time (should only be used from the robot) + AREXPORT ArRetFunctor *getWarningTimeCB(void); + + /// Sets the functor called to check if there should be a time warning this cycle (should only be used from the robot) + AREXPORT void setNoTimeWarningCB( + ArRetFunctor *functor); + /// Gets the functor called to check if there should be a time warning this cycle (should only be used from the robot) + AREXPORT ArRetFunctor *getNoTimeWarningCB(void); + + // removes this task from the map + AREXPORT void remove(ArSyncTask * proc); + + // returns whether this node is deleting or not + AREXPORT bool isDeleting(void); +protected: + std::multimap myMultiMap; + ArTaskState::State *myStatePointer; + ArTaskState::State myState; + ArFunctor *myFunctor; + std::string myName; + ArSyncTask *myParent; + bool myIsDeleting; + ArRetFunctor *myWarningTimeCB; + ArRetFunctor *myNoTimeWarningCB; + // variables for introspection + bool myRunning; + // this is just a pointer to what we're invoking so we can know later + ArSyncTask *myInvokingOtherFunctor; +}; + + + +#endif + + + + diff --git a/Legacy/Aria/include/ArSystemStatus.h b/Legacy/Aria/include/ArSystemStatus.h new file mode 100644 index 0000000..395ce0b --- /dev/null +++ b/Legacy/Aria/include/ArSystemStatus.h @@ -0,0 +1,186 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ + +#ifndef ARSYSTEMSTATUS_H +#define ARSYSTEMSTATUS_H + +#include "ariaTypedefs.h" +#include "ArFunctor.h" +#include "ariaUtil.h" +#include "ArMutex.h" +#include + +class ArSystemStatusRefreshThread; + +/** @brief Utility to get statistics about the host operating system + * (CPU usage, wireless link data, etc). + * + * Normally, calling any accessor to read a value will query the operating + * system to get the most recent value. However, if you will be accessing + * data very frequently and want those calls to be faster, you can start + * a thread by calling startPeriodicUpdate() which will periodically query + * new values from the operating system and cache them for accessors to + * return. + * + * This class is only implemented for Linux; on Windows you will get invalid + * information. + * @todo Add a function and functor that formats uptime like "X years, + * X months, X days, X hours, X min, X sec." (omitting 0 values). + + @ingroup UtilityClasses + */ +class ArSystemStatus { +public: + + /** Create a new thread which periodically invalidates cached data, + * causing it to be recalculated when next accessed. Starting + * this thread is optional; start it if you + * will be accessing the data frequently, so that is doesn't need to + * be re-read and re-calculated on each access. If you will only be + * accessing the data occasionally, you do not need to start the update + * thread, it will be updated each time you read a value. + */ + AREXPORT static void startPeriodicUpdate(int refreshFrequency = 5000, ArLog::LogLevel logLevel = ArLog::Verbose); + + /** Stop periodic update thread. Henceforth any access of data will + * cause it to be re-read and recalculated. */ + AREXPORT static void stopPeriodicUpdate(); + + /** @deprecated use startPeriodicUpdate() which has a better name. */ + AREXPORT static void runRefreshThread(int refreshFrequency = 5000) { + startPeriodicUpdate(refreshFrequency); + } + + /** Get CPU work to idle ratio since last refresh. + * This is a value ranging from (0 .. 1) X (Num. CPUs). (Therefore + * if you have two CPUs, the maximum value will be 2.0, or 200%.) + * This value is calculated as the percentage + * of time the CPU spent doing work (not in "idle" state) since the + * previous calculation. + * @return CPU usage value, or -1 if unable to determine + */ + AREXPORT static double getCPU(); + + /** Get CPU usage as percentage since last refresh. This is a value ranging from + * (0..100) X (Num. CPUs). (Therefore if you have two CPUs, the maximum value + * will be 200%). + * @sa getCPU() + * @return CPU usage as percentage, or -1 if not able to determine + */ + AREXPORT static double getCPUPercent(); + + /// Get CPU percentage in a string + AREXPORT static std::string getCPUPercentAsString(); + + /// Get total system uptime (seconds) + AREXPORT static unsigned long getUptime(); + + /// Get program's uptime (seconds) + AREXPORT static unsigned long getProgramUptime(); + + /// Get total system uptime (hours) + AREXPORT static double getUptimeHours(); + + /// Get total system uptime in a string (hours) + AREXPORT static std::string getUptimeHoursAsString(); + + /** @return Pointer to a functor which can be used to retrieve the current CPU percentage */ + AREXPORT static ArRetFunctor* getCPUPercentFunctor(); + + /** @return Pointer to a functor which can be used to retrieve the current uptime (hours) */ + AREXPORT static ArRetFunctor* getUptimeHoursFunctor(); + + /** @return Pointer to a functor which can be used to retrieve the current uptime (hours) */ + AREXPORT static ArRetFunctor* getUptimeFunctor(); + + /** @return Pointer to a functor which can be used to retrieve the current uptime (hours) */ + AREXPORT static ArRetFunctor* getProgramUptimeFunctor(); + + + + /** Get wireless network general link quality heuristic (for first configured + * wireless device). */ + AREXPORT static int getWirelessLinkQuality(); + + /** Get wireless netork signal level (for first configured + * wireless device). */ + AREXPORT static int getWirelessLinkSignal(); + + /** Get wireless network noise level (for first configured + * wireless device). */ + AREXPORT static int getWirelessLinkNoise(); + + /** Get wireless network total discarded packets (for first configured + * wireless device). */ + AREXPORT static int getWirelessDiscardedPackets(); + + /** Get wireless network packets discarded because of a conflict with another + * network (for first configured + * wireless device). */ + AREXPORT static int getWirelessDiscardedPacketsBecauseNetConflict(); + + + AREXPORT static ArRetFunctor* getWirelessLinkQualityFunctor(); + AREXPORT static ArRetFunctor* getWirelessLinkNoiseFunctor(); + AREXPORT static ArRetFunctor* getWirelessLinkSignalFunctor(); + + /** @internal */ + AREXPORT static void invalidate(); + + /** @deprecated Calling this function is no longer neccesary. */ + AREXPORT static void refresh() { } +private: + + + static ArMutex ourCPUMutex; + static double ourCPU; + static unsigned long ourUptime; + static unsigned long ourFirstUptime; + static unsigned long ourLastCPUTime; + static ArTime ourLastCPURefreshTime; + static ArGlobalRetFunctor ourGetCPUPercentCallback; + static ArGlobalRetFunctor ourGetUptimeHoursCallback; + static ArGlobalRetFunctor ourGetUptimeCallback; + static ArGlobalRetFunctor ourGetProgramUptimeCallback; + + static ArMutex ourWirelessMutex; + static int ourLinkQuality, ourLinkSignal, ourLinkNoise, + ourDiscardedTotal, ourDiscardedDecrypt, ourDiscardedConflict; + static ArGlobalRetFunctor ourGetWirelessLinkQualityCallback; + static ArGlobalRetFunctor ourGetWirelessLinkNoiseCallback; + static ArGlobalRetFunctor ourGetWirelessLinkSignalCallback; + + static void refreshCPU(); ///< Refresh CPU, if neccesary + static void refreshWireless(); ///< Refresh Wireless stats, if neccesary + + + static ArSystemStatusRefreshThread* ourPeriodicUpdateThread; + static bool ourShouldRefreshWireless; + static bool ourShouldRefreshCPU; + +}; + +#endif diff --git a/Legacy/Aria/include/ArTCM2.h b/Legacy/Aria/include/ArTCM2.h new file mode 100644 index 0000000..d144c61 --- /dev/null +++ b/Legacy/Aria/include/ArTCM2.h @@ -0,0 +1,252 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARTCM2_H +#define ARTCM2_H + +#include "ariaUtil.h" +#include "ArFunctor.h" +#include "ArRobot.h" + + +#ifdef WIN32 +#define ARTCM2_DEFAULT_SERIAL_PORT "COM4" +#else +#define ARTCM2_DEFAULT_SERIAL_PORT "/dev/ttyS3" +#endif + + +/** Interface to the PNI TCM 2, TCM 2.5, and TCM 2.6 3-axis compass (magnetometer) that can sense absolute heading, as well as pitch, roll, and includes a temperature sensor. + * + * See subclasses and ArCompassConnector for more information, as well as + * your robot manuals. PNI's TCM manual is also available for download at the + * MobileRobots support website, documentation section. + * + * This is an abstract interface. To create a compass interface object, + * instantiate a subclass or use ArCompassConnector. + + @ingroup OptionalClasses + @ingroup DeviceClasses + * + * @note The compass returns a heading relative to magnetic north, which varies + * depending on your location in the Earth's magnetic field (declination also + * varies slowly over time as the Earth's magnetic field changes). To find true + * north, you must apply an offset, or declination. For example, on + * June 1, 2007, the magnetic declination of MobileRobots' location + * of Amherst, NH, USA was 15 1/6 degrees West, so a value of approx. + * -15.166666 would have to be applied. You can look up declination values for + * various locations on Earth at + * http://www.ngdc.noaa.gov/seg/geomag/jsp/Declination.jsp + */ +class ArTCM2 +{ +public: + + AREXPORT ArTCM2(); + virtual ~ArTCM2() {} + + /** If a connection/initialization procedure is required, perform it, and + return true on success, false on failure. Otherwise, just return true. + */ + AREXPORT virtual bool connect(); + + /** If a connection/initialization procedure is required, perform it, wait + * until data is recieved from the compass, and + return true on success, false on failure. Otherwise, just return true. + */ + AREXPORT virtual bool blockingConnect(unsigned long connectTimeout = 5000); + + + /// Get the compass heading (-180, 180] degrees + double getHeading(void) const { return myHeading; } + bool haveHeading() const { return myHaveHeading; } + + /** Get the compass heading (-180, 180] degrees + * @deprecated Use getHeading() + */ + double getCompass(void) const { return getHeading(); } + + /// Get the pitch (-180,180] degrees. + double getPitch(void) const { return myPitch; } + bool havePitch() const { return myHavePitch; } + + /// Get the roll (-180,180] degrees. + double getRoll(void) const { return myRoll; } + bool haveRoll() const { return myHaveRoll; } + + /// Get the magnetic field X component (See TCM2 Manual) + double getXMagnetic(void) const { return myXMag; } + bool haveXMagnetic() const { return myHaveXMag; } + + /// Get the magnetic field Y component (See TCM2 Manual) + double getYMagnetic(void) const { return myYMag; } + bool haveYMagnetic() const { return myHaveYMag; } + + /// Get the magnetic field Z component (See TCM2 Manual) + double getZMagnetic(void) const { return myZMag; } + bool haveZMagnetic() const { return myHaveZMag; } + + /// Get the temperature (degrees C) + double getTemperature(void) const { return myTemperature; } + bool haveTemperature() const { return myHaveTemperature; } + + // Get last error code (see TCM manual) recieved. 0 means no error recieved. + int getError(void) const { return myError; } + + /// Get the calibration H score (See TCM Manual) + double getCalibrationH(void) const { return myCalibrationH; } + bool haveCalibrationH() const { return myHaveCalibrationH; } + + /// Get the calibration V score (See TCM Manual) + double getCalibrationV(void) const { return myCalibrationV; } + bool haveCalibrationV() const { return myHaveCalibrationV; } + + /// Get the calibration M score (See TCM Manual) + double getCalibrationM(void) const { return myCalibrationM; } + bool haveCalibrationM() const { return myHaveCalibrationM; } + + /// Turn sending of data off (Compass remains powered on, this is not its not low power standby mode) + virtual void commandOff(void) = 0; + + /// Get one reading from the compass + virtual void commandOnePacket(void) = 0; + + /// Start the compass sending a continuous stream of readings at its fastest rate + virtual void commandContinuousPackets(void) = 0; + + /// Start user calibration + virtual void commandUserCalibration(void) = 0; + + /// Start auto calibration + virtual void commandAutoCalibration(void) = 0; + + /// Stop calibration + virtual void commandStopCalibration(void) = 0; + + /// Command to do a soft reset of the compass + virtual void commandSoftReset(void) = 0; + + /// Command to just send compass heading data + virtual void commandJustCompass(void) = 0; + + /// Gets the number of readings recieved in the last second + int getPacCount(void) { + if(myTimeLastPacket == time(NULL)) return myPacCount; + if(myTimeLastPacket == time(NULL) - 1) return myPacCurrentCount; + return 0; + } + + // Add a callback to be invoked when a new heading is recieved + void addHeadingDataCallback(ArFunctor1 *f) { + myHeadingDataCallbacks.push_back(f); + } + + +protected: + double myHeading; + double myPitch; + double myRoll; + double myXMag; + double myYMag; + double myZMag; + double myTemperature; + int myError; + double myCalibrationH; + double myCalibrationV; + double myCalibrationM; + + bool myHaveHeading; + bool myHavePitch; + bool myHaveRoll; + bool myHaveXMag; + bool myHaveYMag; + bool myHaveZMag; + bool myHaveTemperature; + bool myHaveCalibrationH; + bool myHaveCalibrationV; + bool myHaveCalibrationM; + + std::list< ArFunctor1* > myHeadingDataCallbacks; + + // packet count + time_t myTimeLastPacket; + int myPacCurrentCount; + int myPacCount; + + void incrementPacketCount() { + if (myTimeLastPacket != time(NULL)) + { + myTimeLastPacket = time(NULL); + myPacCount = myPacCurrentCount; + myPacCurrentCount = 0; + } + myPacCurrentCount++; + } + + + // call the heading data callbacks + void invokeHeadingDataCallbacks(double heading) { + for(std::list*>::iterator i = myHeadingDataCallbacks.begin(); i != myHeadingDataCallbacks.end(); ++i) + if(*i) (*i)->invoke(heading); + } + +}; + + +/** Use this class to create an instance of a TCM2 subclass + * and connect to the device based on program command line options. + * This allows the user of a program to select a different kind + * of compass configuration (for example, if the compass is connected + * to a computer serial port, use ArTCMCompassDirect instead of + * the normal ArTCMCompassRobot.) + * + * The following command-line arguments are checked: + * @verbinclude ArCompassConnector_options + */ +class ArCompassConnector +{ +protected: + ArArgumentParser *myArgParser; + ArRetFunctorC myParseArgsCallback; + ArFunctorC myLogArgsCallback; + typedef enum { + Robot, + SerialTCM, + None + } DeviceType; + DeviceType myDeviceType; + const char *mySerialPort; + AREXPORT bool parseArgs(); + ArFunctor *mySerialTCMReadFunctor; + ArRobot *myRobot; + AREXPORT void logOptions(); +public: + AREXPORT ArCompassConnector(ArArgumentParser *argParser); + AREXPORT ~ArCompassConnector(); + AREXPORT ArTCM2 *create(ArRobot *robot); + AREXPORT bool connect(ArTCM2*) const; +}; + +#endif // ARTCM2_H diff --git a/Legacy/Aria/include/ArTCMCompassDirect.h b/Legacy/Aria/include/ArTCMCompassDirect.h new file mode 100644 index 0000000..2f5297c --- /dev/null +++ b/Legacy/Aria/include/ArTCMCompassDirect.h @@ -0,0 +1,119 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ + +#ifndef ARTCMCOMPASSDIRECT_H +#define ARTCMCOMPASSDIRECT_H + + +#include "ariaTypedefs.h" +#include "ariaUtil.h" +#include "ArDeviceConnection.h" +#include "ArTCM2.h" +#include "ArNMEAParser.h" + + +/** @brief Talk to a compass directly over a computer serial port + * + * This class configures and recieves compass heading data from a TCM2 or TCM2.5 compass + * directly over a computer serial port, rather than via tha robot. + * This class cannot recieve pitch, roll or temperature data from the compass. + * On all Pioneer robots, the TCM compass (as originally installed by + * MobileRobots) is connected to the robot microcontroller, so if you + * have a Pioneer with this configuration, you should instead use the + * ArTCMCompassRobot class. Only use this class if you + * have connected the compass to the computer serial port. + * + * You can create an instance of this class directly, or using an + * ArCompassConnector object and giving the "-compassType serialtcm" program + * argument. + * + * If you create your own ArTCMCompassDirect object, you must call the read() + * method periodically (ideally at the same rate the compass sends data, + * approx. 8 hz by default) to read and parse incoming data. You can use an + * ArRobot callback to do this, for example: + * @code + * ArRetFunctor1C compassReadFunc(myCompass, &ArTCMCompassDirect::read, 10); + * myRobot->addSensorInterpTask("ArTCMCompassDirect read", 200, &compassReadFunc); + * @endcode + * + * If you use ArCompassConnector, however, it will automatically do this. + * + */ +class ArTCMCompassDirect : public virtual ArTCM2 +{ +private: + ArDeviceConnection *myDeviceConnection; + bool myCreatedOwnDeviceConnection; + const char *mySerialPortName; + ArNMEAParser myNMEAParser; + bool sendTCMCommand(const char *str, ...); + ArFunctor1C myHCHDMHandler; + void handleHCHDM(ArNMEAParser::Message); +public: + AREXPORT ArTCMCompassDirect(ArDeviceConnection *devCon); + AREXPORT ArTCMCompassDirect(const char *serialPortName = ARTCM2_DEFAULT_SERIAL_PORT); + AREXPORT ~ArTCMCompassDirect(); + + /** Open device connection if not yet open and send commands to configure compass. */ + AREXPORT virtual bool connect(); + AREXPORT virtual bool blockingConnect(unsigned long connectTimeout = 5000); + + + /** Send commands to begin calibrating */ + AREXPORT virtual void commandAutoCalibration(); + AREXPORT virtual void commandUserCalibration(); + AREXPORT virtual void commandStopCalibration(); + + /** Send commands to start/stop sending data. */ + //@{ + AREXPORT virtual void commandContinuousPackets(); + AREXPORT virtual void commandOnePacket(); + AREXPORT virtual void commandOff(); + //@} + + /** Not implemented yet. @todo */ + AREXPORT virtual void commandSoftReset() { /* TODO */ } + + /** Same as commandContinuousPackets() in this implementation. */ + AREXPORT virtual void commandJustCompass() { commandContinuousPackets(); } + + /** Read all available data, store, and call callbacks if any were added. + * unsigned int msWait If 0, wait indefinately for new data. Otherwise, wait + * a maximum of this many milliseconds for data to arrive. + * @return A value > 0 if messages were recieved from the compass, 0 if no + * data was recieved, and a value < 0 on error reading from the compass. + * */ + AREXPORT int read(unsigned int msWait = 1); + + AREXPORT void setDeviceConnection(ArDeviceConnection *devCon) { myDeviceConnection = devCon; } + AREXPORT ArDeviceConnection *getDeviceConnetion() { return myDeviceConnection; } + + +}; + +#endif + + diff --git a/Legacy/Aria/include/ArTCMCompassRobot.h b/Legacy/Aria/include/ArTCMCompassRobot.h new file mode 100644 index 0000000..fc58616 --- /dev/null +++ b/Legacy/Aria/include/ArTCMCompassRobot.h @@ -0,0 +1,67 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARTCMCOMPASSROBOT_H +#define ARTCMCOMPASSROBOT_H + +#include "ariaUtil.h" +#include "ArCommands.h" +#include "ArFunctor.h" +#include "ArRobot.h" +#include "ArTCM2.h" + +/** Interface to a TCM 2/2.5/2.6 3-axis compass through the robot microcontroller. + * When a Pioneer robot is equipped with a TCM compass, it is typically connected + * to the robot microcontroller, which returns compass information in + * compass data packets upon request (set compass mode/type to 2 or 3 in + * firmware configuration; mode 1 (data in SIP) is not supported by ARIA). This class communicates + * with the robot microcontroller to configure the compass and recieve data + * from it. + * +*/ +class ArTCMCompassRobot : public virtual ArTCM2 +{ +public: + + AREXPORT ArTCMCompassRobot(ArRobot *robot); + AREXPORT virtual ~ArTCMCompassRobot(); + + virtual void commandOff(void) { myRobot->comInt(ArCommands::TCM2, 0); } + virtual void commandJustCompass(void) { myRobot->comInt(ArCommands::TCM2, 1); } + virtual void commandOnePacket(void) { myRobot->comInt(ArCommands::TCM2, 2); } + virtual void commandContinuousPackets(void) { myRobot->comInt(ArCommands::TCM2, 3); } + virtual void commandUserCalibration(void) { myRobot->comInt(ArCommands::TCM2, 4); } + virtual void commandAutoCalibration(void) { myRobot->comInt(ArCommands::TCM2, 5); } + virtual void commandStopCalibration(void) { myRobot->comInt(ArCommands::TCM2, 6); } + virtual void commandSoftReset(void) { myRobot->comInt(ArCommands::TCM2, 7); } + +private: + ArRobot *myRobot; + ArRetFunctor1C myPacketHandlerCB; + bool packetHandler(ArRobotPacket *packet); +}; + + +#endif diff --git a/Legacy/Aria/include/ArTaskState.h b/Legacy/Aria/include/ArTaskState.h new file mode 100644 index 0000000..54b943c --- /dev/null +++ b/Legacy/Aria/include/ArTaskState.h @@ -0,0 +1,54 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARTASKSTATE_H +#define ARTASKSTATE_H + +/// Class with the different states a task can be in +/** + These are the defined states, if the state is anything other than is + defined here that is annotated (not running) the process will be run. + No one should have any of their own states less than the USER_START + state. People's own states should start at USER_START or at + USER_START plus a constant (so they can have different sets of states). +*/ +class ArTaskState +{ +public: + enum State + { + INIT = 0, ///< Initialized (running) + RESUME, ///< Resumed after being suspended (running) + ACTIVE, ///< Active (running) + SUSPEND, ///< Suspended (not running) + SUCCESS, ///< Succeeded and done (not running) + FAILURE, ///< Failed and done (not running) + USER_START = 20 ///< This is where the user states should start (they will all be run) + }; + +}; + + +#endif diff --git a/Legacy/Aria/include/ArTcpConnection.h b/Legacy/Aria/include/ArTcpConnection.h new file mode 100644 index 0000000..682ea16 --- /dev/null +++ b/Legacy/Aria/include/ArTcpConnection.h @@ -0,0 +1,96 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARTCPCONNECTION_H +#define ARTCPCONNECTION_H + +#include "ArDeviceConnection.h" +#include + +#include "ariaTypedefs.h" +#include "ArSocket.h" + +/// For connecting to a device through a TCP network socket +/// @ingroup UtilityClasses +class ArTcpConnection: public ArDeviceConnection +{ + public: + /// Constructor + AREXPORT ArTcpConnection(); + /// Destructor also closes connection + AREXPORT virtual ~ArTcpConnection(); + + /// Opens a connection to the given host and port + AREXPORT int open(const char * host = NULL, int port = 8101); + + AREXPORT void setPort(const char *host = NULL, int port = 8101); + AREXPORT virtual bool openSimple(void); + AREXPORT virtual int getStatus(void); + AREXPORT virtual bool close(void); + AREXPORT virtual int read(const char *data, unsigned int size, + unsigned int msWait = 0); + AREXPORT virtual int write(const char *data, unsigned int size); + AREXPORT virtual const char * getOpenMessage(int messageNumber); + AREXPORT virtual ArTime getTimeRead(int index); + AREXPORT virtual bool isTimeStamping(void); + + /// Gets the name of the host connected to + AREXPORT std::string getHost(void); + /// Gets the number of the port connected to + AREXPORT int getPort(void); + + /// Internal function used by open and openSimple + AREXPORT int internalOpen(void); + + /// Sets the tcp connection to use this socket instead of its own + AREXPORT void setSocket(ArSocket *socket); + /// Gets the socket this tcp connection is using + AREXPORT ArSocket *getSocket(void); + /// Sets the status of the device, ONLY use this if you're playing + /// with setSocket and know what you're doing + AREXPORT void setStatus(int status); + + enum Open { + OPEN_NET_FAIL = 1, ///< Some critical part of the network isn't working + OPEN_BAD_HOST, ///< Could not find the host + OPEN_NO_ROUTE, ///< Know where the host is, but can't get to it + OPEN_CON_REFUSED ///< Got to the host but it didn't allow a connection + }; + + + +protected: + void buildStrMap(void); + + ArStrMap myStrMap; + bool myOwnSocket; + ArSocket *mySocket; + int myStatus; + + std::string myHostName; + int myPortNum; +}; + +#endif //ARTCPCONNECTION_H diff --git a/Legacy/Aria/include/ArThread.h b/Legacy/Aria/include/ArThread.h new file mode 100644 index 0000000..b02a52e --- /dev/null +++ b/Legacy/Aria/include/ArThread.h @@ -0,0 +1,270 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARTHREAD_H +#define ARTHREAD_H + + +#include +#if !defined(WIN32) || defined(MINGW) +#include +#endif +#include "ariaTypedefs.h" +#include "ArMutex.h" +#include "ArFunctor.h" +#include "ArLog.h" + +#ifdef MINGW +#include +#else +#include +#endif + +/// POSIX/WIN32 thread wrapper class. +/** + create() will create the thread. That thread will run the given Functor. + + A thread can either be in a detached state or a joinable state. If the + thread is in a detached state, that thread can not be join()'ed upon. The + thread will simply run until the program exits, or its function exits. + A joinable thread means that another thread and call join() upon it. If + this function is called, the caller will block until the thread exits + its function. This gives a way to synchronize upon the lifespan of threads. + + Calling cancel() will cancel the thread. + + The static function self() will return a thread + + @sa ArASyncTask which provides a different approach with a simpler interface. + +*/ +class ArThread +{ +public: + +#if defined(WIN32) && !defined(MINGW) + typedef DWORD ThreadType; +#else + typedef pthread_t ThreadType; +#endif + +// pthread_t on Linux happens to be an integer or pointer that can be used in a map. On other platforms, pthread_t may be a struct or similar, and this is true on MINGW, so store them differently. Use the access methods that follow to access the map. +#ifdef MINGW + typedef std::vector< std::pair > MapType; +#else + typedef std::map MapType; +#endif + +protected: + static ArThread* findThreadInMap(ThreadType t); + static void removeThreadFromMap(ThreadType t); + static void addThreadToMap(ThreadType pt, ArThread *at); + +public: + typedef enum { + STATUS_FAILED=1, ///< Failed to create the thread + STATUS_NORESOURCE, ///< Not enough system resources to create the thread + STATUS_NO_SUCH_THREAD, ///< The thread can no longer be found + STATUS_INVALID, ///< Thread is detached or another thread is joining on it + STATUS_JOIN_SELF, ///< Thread is your own thread. Can't join on self. + STATUS_ALREADY_DETATCHED ///< Thread is already detatched + } Status; + + /// Constructor + AREXPORT ArThread(bool blockAllSignals=true); + /// Constructor - starts the thread + AREXPORT ArThread(ThreadType thread, bool joinable, + bool blockAllSignals=true); + /// Constructor - starts the thread + AREXPORT ArThread(ArFunctor *func, bool joinable=true, + bool blockAllSignals=true); + /// Destructor + AREXPORT virtual ~ArThread(); + + /// Initialize the internal book keeping structures + AREXPORT static void init(void); + /// Returns the instance of your own thread (the current one) + AREXPORT static ArThread * self(void); + /// Returns the os self of the current thread + AREXPORT static ThreadType osSelf(void); + /// Stop all threads + AREXPORT static void stopAll(); + /// Cancel all threads + AREXPORT static void cancelAll(void); + /// Join on all threads + AREXPORT static void joinAll(void); + + /// Shuts down and deletes the last remaining thread; call after joinAll + AREXPORT static void shutdown(); + + /// Yield the processor to another thread + AREXPORT static void yieldProcessor(void); + /// Gets the logging level for thread information + static ArLog::LogLevel getLogLevel(void) { return ourLogLevel; } + /// Sets the logging level for thread information + static void setLogLevel(ArLog::LogLevel level) { ourLogLevel = level; } + + /// Create and start the thread + AREXPORT virtual int create(ArFunctor *func, bool joinable=true, + bool lowerPriority=true); + /// Stop the thread + virtual void stopRunning(void) {myRunning=false;} + /// Join on the thread + AREXPORT virtual int join(void **ret=NULL); + /// Detatch the thread so it cant be joined + AREXPORT virtual int detach(void); + /// Cancel the thread + AREXPORT virtual void cancel(void); + + /// Get the running status of the thread + virtual bool getRunning(void) const {return(myRunning);} + /// Get the running status of the thread, locking around the variable + virtual bool getRunningWithLock(void) + { bool running; lock(); running = myRunning; unlock(); return running; } + /// Get the joinable status of the thread + virtual bool getJoinable(void) const {return(myJoinable);} + /// Get the underlying thread type + virtual const ThreadType * getThread(void) const {return(&myThread);} + /// Get the underlying os thread type + virtual ThreadType getOSThread(void) const {return(myThread);} + /// Get the functor that the thread runs + virtual ArFunctor * getFunc(void) const {return(myFunc);} + + /// Set the running value on the thread + virtual void setRunning(bool running) {myRunning=running;} + +#ifndef SWIG + /** Lock the thread instance + @swigomit + */ + int lock(void) {return(myMutex.lock());} + /** Try to lock the thread instance without blocking + @swigomit + */ + int tryLock(void) {return(myMutex.tryLock());} + /** Unlock the thread instance + @swigomit + */ + int unlock(void) {return(myMutex.unlock());} +#endif + + /// Do we block all process signals at startup? + bool getBlockAllSignals(void) {return(myBlockAllSignals);} + + /// Gets the name of the thread + virtual const char *getThreadName(void) { return myName.c_str(); } + + /// Sets the name of the thread + AREXPORT virtual void setThreadName(const char *name); + + /// Gets a string that describes what the thread is doing NULL if it + /// doesn't know + virtual const char *getThreadActivity(void) { return NULL; } + + /// Marks the thread as started and logs useful debugging information. + /** + If you call this function in your functor (ie runThread) it'll + then call some things for logging (to make debugging easier) + This method should be called before the main thread loop begins. + **/ + AREXPORT virtual void threadStarted(void); + + /// Marks the thread as finished and logs useful debugging information. + /** + This method should be called after the main thread loop ends. It + enables the creator of the thread to determine that the thread has + actually been completed and can be deleted. + **/ + AREXPORT virtual void threadFinished(void); + + /// Returns whether the thread has been started. + /** + * This is dependent on the thread implementation calling the + * threadStarted() method. + **/ + AREXPORT virtual bool isThreadStarted() const; + + /// Returns whether the thread has been completed and can be deleted. + /** + * This is dependent on the thread implementation calling the + * threadFinished() method. + **/ + AREXPORT virtual bool isThreadFinished() const; + + + /// Logs the information about this thread + AREXPORT virtual void logThreadInfo(void); + +#ifndef WIN32 + pid_t getPID(void) { return myPID; } + pid_t getTID(void) { return myTID; } +#endif + + /// Gets the name of the this thread + AREXPORT static const char *getThisThreadName(void); + /// Get the underlying thread type of this thread + AREXPORT static const ThreadType * getThisThread(void); + /// Get the underlying os thread type of this thread + AREXPORT static ThreadType getThisOSThread(void); + +protected: + static ArMutex ourThreadsMutex; + static MapType ourThreads; +#if defined(WIN32) && !defined(MINGW) + static std::map ourThreadHandles; +#endif + AREXPORT static ArLog::LogLevel ourLogLevel; + + AREXPORT virtual int doJoin(void **ret=NULL); + + std::string myName; + + ArMutex myMutex; + /// State variable to denote when the thread should continue or exit + bool myRunning; + bool myJoinable; + bool myBlockAllSignals; + + bool myStarted; + bool myFinished; + + ArStrMap myStrMap; + ArFunctor *myFunc; + ThreadType myThread; +#if defined(WIN32) && !defined(MINGW) + HANDLE myThreadHandle; +#endif + + +#if !defined(WIN32) || defined(MINGW) + pid_t myPID; + pid_t myTID; +#endif + + static std::string ourUnknownThreadName; +}; + + +#endif // ARTHREAD_H diff --git a/Legacy/Aria/include/ArTransform.h b/Legacy/Aria/include/ArTransform.h new file mode 100644 index 0000000..cc9034f --- /dev/null +++ b/Legacy/Aria/include/ArTransform.h @@ -0,0 +1,156 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARTRANSFORM_H +#define ARTRANSFORM_H + +#include "ariaTypedefs.h" +#include "ariaUtil.h" + +/// Perform transforms between different coordinates +/** @ingroup UtilityClasses +*/ +class ArTransform +{ +public: + /// Constructor + ArTransform() + { + myX = 0; + myY = 0; + myTh = 0; + myCos = ArMath::cos(myTh); + mySin = ArMath::sin(myTh); + } + /// Constructor, Sets the transform so points in this coord system + /// transform to abs world coords + + ArTransform(ArPose pose) + { + setTransform(pose); + } + /// Constructor, sets the transform so that pose1 will be + /// transformed to pose2 + ArTransform(ArPose pose1, ArPose pose2) + { + setTransform(pose1, pose2); + } + /// Destructor + virtual ~ArTransform() {} + + /// Take the source pose and run the transform on it to put it into abs + /// coordinates + /** + @param source the parameter to transform + @return the source transformed into absolute coordinates + */ + ArPose doTransform(ArPose source) + { + ArPose ret; + ret.setX(myX + myCos * source.getX() + mySin * source.getY()); + ret.setY(myY + myCos * source.getY() - mySin * source.getX()); + ret.setTh(ArMath::addAngle(source.getTh(),myTh)); + return ret; + } + /// Take the source pose and run the transform on it to put it into abs + /// coordinates + /** + @param source the parameter to transform + @return the source transformed into absolute coordinates + */ + ArPoseWithTime doTransform(ArPoseWithTime source) + { + ArPoseWithTime ret; + ret.setX(myX + myCos * source.getX() + mySin * source.getY()); + ret.setY(myY + myCos * source.getY() - mySin * source.getX()); + ret.setTh(ArMath::addAngle(source.getTh(),myTh)); + ret.setTime(source.getTime()); + return ret; + } + + /// Take the source pose and run the inverse transform on it, taking it from + /// abs coords to local + /** + The source and result can be the same + @param source the parameter to transform + @return the source transformed from absolute into local coords + */ + ArPose doInvTransform(ArPose source) + { + ArPose ret; + double tx = source.getX() - myX; + double ty = source.getY() - myY; + ret.setX(myCos * tx - mySin * ty); + ret.setY(myCos * ty + mySin * tx); + ret.setTh(ArMath::subAngle(source.getTh(),myTh)); + return ret; + } + + /// Take the source pose and run the inverse transform on it, taking it from + /// abs coords to local + /** + The source and result can be the same + @param source the parameter to transform + @return the source transformed from absolute into local coords + */ + ArPoseWithTime doInvTransform(ArPoseWithTime source) + { + ArPoseWithTime ret; + double tx = source.getX() - myX; + double ty = source.getY() - myY; + ret.setX(myCos * tx - mySin * ty); + ret.setY(myCos * ty + mySin * tx); + ret.setTh(ArMath::subAngle(source.getTh(),myTh)); + ret.setTime(source.getTime()); + return ret; + } + + + /// Take a std::list of sensor readings and do the transform on it + AREXPORT void doTransform(std::list *poseList); + /// Take a std::list of sensor readings and do the transform on it + AREXPORT void doTransform(std::list *poseList); + /// Sets the transform so points in this coord system transform to abs world coords + AREXPORT void setTransform(ArPose pose); + /// Sets the transform so that pose1 will be transformed to pose2 + AREXPORT void setTransform(ArPose pose1, ArPose pose2); + /// Gets the transform x value (mm) + double getX() { return myX; } + /// Gets the transform y value (mm) + double getY() { return myY; } + /// Gets the transform angle value (degrees) + double getTh() { return myTh; } + /// Internal function for setting the transform from low level data not poses + AREXPORT void setTransformLowLevel(double x, double y, double th); +protected: + double myX; + double myY; + double myTh; + double myCos; + double mySin; +}; + + +#endif // ARTRANSFORM_H diff --git a/Legacy/Aria/include/ArTrimbleGPS.h b/Legacy/Aria/include/ArTrimbleGPS.h new file mode 100644 index 0000000..ecf49b2 --- /dev/null +++ b/Legacy/Aria/include/ArTrimbleGPS.h @@ -0,0 +1,88 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ + +#ifndef ARTRIMBLEGPS_H +#define ARTRIMBLEGPS_H + + +#include "ariaTypedefs.h" +#include "ArFunctor.h" +#include "ariaUtil.h" +#include "ArGPS.h" +#include "ArDeviceConnection.h" +#include "ArMutex.h" + +#include + +class ArTrimbleAuxDeviceConnection; + +/** @brief GPS subclass to support the Trimble AgGPS and other Trimble GPS devices. + * + * This subclass extends ArGPS to send initialization commands specific + * to Trimble GPS devices, and to handle the PTNLAG001 message which + * is specific to the Trimble GPS (this message contains data received + * from an auxilliary device connected to the GPS; ArTrimbleGPS + * simply parses its contents as a new NMEA message; i.e. data received + * by the Trimble is assumed to be NMEA messages that it forwards + * via the PTNLAG001 message.) + * + * @note You must also configure the ports using + * the Trimble AgRemote program + * (http://www.trimble.com/support_trl.asp?pt=AgRemote&Nav=Collection-1545). + * Enable the following messages on whichever + * GPS port the computer is connected to: GPRMC, GPGGA, GPGSA, GPGSV, GPGST, + * GPMSS, and set input (I) protocol to TSIP 38k baud, and output + * protocol (O) to NMEA 38k baud. + * This configuration is done by MobileRobots when shipping a Trimble AgGPS + * but you may need to do this if the GPS loses its configuration or after + * changing any other settings (Note that AgRemote resets the port settings each time + * it connects, so you must reset them each time before exiting AgRemote!) + * + * @since 2.6.0 + */ +class ArTrimbleGPS : public virtual ArGPS { +private: + ArFunctor1C myAuxDataHandler; + void handlePTNLAG001(ArNMEAParser::Message message); +public: + AREXPORT ArTrimbleGPS(); + AREXPORT virtual ~ArTrimbleGPS(); + + /** Send a TSIP command to the Trimble GPS. + * See the TSIP Reference guide for details. + * Note, the data must be 66 characters or less. + */ + AREXPORT bool sendTSIPCommand(char command, const char *data, size_t dataLen); + +protected: + AREXPORT virtual bool initDevice(); + +}; + + +#endif + + diff --git a/Legacy/Aria/include/ArUrg.h b/Legacy/Aria/include/ArUrg.h new file mode 100644 index 0000000..f6caf29 --- /dev/null +++ b/Legacy/Aria/include/ArUrg.h @@ -0,0 +1,127 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARURG_H +#define ARURG_H + +#include "ariaTypedefs.h" +#include "ArLaser.h" +#include "ArDeviceConnection.h" + +/** Hokuyo Urg laser range device. + * Connects using the Urg's serial port connector (not USB). + * Supports URG-04LX using SCIP 1.1 protocol only. See ArLaserConnector for instructions on + * using lasers in a program. + @sa ArUrg_2_0 + @sa ArLaserConnector + @sa ArLaser + * @since 2.7.0 + */ +class ArUrg : public ArLaser +{ +public: + /// Constructor + AREXPORT ArUrg(int laserNumber, + const char *name = "urg"); + /// Destructor + AREXPORT ~ArUrg(); + AREXPORT virtual bool blockingConnect(void); + AREXPORT virtual bool asyncConnect(void); + AREXPORT virtual bool disconnect(void); + AREXPORT virtual bool isConnected(void) { return myIsConnected; } + AREXPORT virtual bool isTryingToConnect(void) + { + if (myStartConnect) + return true; + else if (myTryingToConnect) + return true; + else + return false; + } + + /// Logs the information about the sensor + AREXPORT void log(void); +protected: + /// Sets the parameters that control what data you get from the urg + AREXPORT bool setParams( + double startingDegrees = -135, double endingDegrees = 135, + double incrementDegrees = 1, bool flipped = false); + /// Sets the parameters that control what data you get from the urg + AREXPORT bool setParamsBySteps( + int startingStep = 0, int endingStep = 768, int clusterCount = 3, + bool flipped = false); + AREXPORT virtual void * runThread(void *arg); + /// internal call to write a string to the urg + bool writeLine(const char *str); + /// internal call to read a string from the urg + bool readLine(char *buf, unsigned int size, unsigned int msWait); + + /// internal call to write a command and get the response back into the buf + bool sendCommandAndRecvStatus( + const char *command, const char *commandDesc, + char *status, unsigned int size, unsigned int msWait); + + void sensorInterp(void); + AREXPORT virtual void setRobot(ArRobot *robot); + AREXPORT virtual bool laserCheckParams(void); + AREXPORT virtual void laserSetName(const char *name); + + void failedToConnect(void); + ArMutex myReadingMutex; + ArMutex myDataMutex; + + ArTime myReadingRequested; + std::string myReading; + + int myStartingStep; + int myEndingStep; + int myClusterCount; + bool myFlipped; + char myRequestString[1024]; + double myClusterMiddleAngle; + + bool internalConnect(void); + + bool internalGetReading(void); + + void clear(void); + bool myIsConnected; + bool myTryingToConnect; + bool myStartConnect; + + std::string myVendor; + std::string myProduct; + std::string myFirmwareVersion; + std::string myProtocolVersion; + std::string mySerialNumber; + std::string myStat; + + bool myLogMore; + + ArFunctorC mySensorInterpTask; + ArRetFunctorC myAriaExitCB; +}; + +#endif // ARURG_H diff --git a/Legacy/Aria/include/ArUrg_2_0.h b/Legacy/Aria/include/ArUrg_2_0.h new file mode 100644 index 0000000..17e26bf --- /dev/null +++ b/Legacy/Aria/include/ArUrg_2_0.h @@ -0,0 +1,152 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARURG_2_0_H +#define ARURG_2_0_H + +#include "ariaTypedefs.h" +#include "ArLaser.h" +#include "ArDeviceConnection.h" + +/** + Hokuyo URG laser range device (SCIP 2.0). + + Connects using the Urg's serial port connector or USB. Note that + if the max range is 4095 or less it'll use 2 bytes per range + reading, and if the max range is more than that it'll use 3 bytes + per range reading. + + Supports (probably) any URG using SCIP 2.0 protocol (use ArUrg aka + 'urg' for SCIP 1.1 instead). + + See ArLaserConnector for instructions on configuring and using lasers. + + See http://robots.mobilerobots.com/wiki/Hokuyo_URG for more information and links to downloads from Hokuyo including the USB Windows driver. + + @sa ArUrg + @sa ArLaserConnector + @sa ArLaser + */ +class ArUrg_2_0 : public ArLaser +{ +public: + /// Constructor + AREXPORT ArUrg_2_0(int laserNumber, + const char *name = "urg2.0"); + /// Destructor + AREXPORT ~ArUrg_2_0(); + AREXPORT virtual bool blockingConnect(void); + AREXPORT virtual bool asyncConnect(void); + AREXPORT virtual bool disconnect(void); + AREXPORT virtual bool isConnected(void) { return myIsConnected; } + AREXPORT virtual bool isTryingToConnect(void) + { + if (myStartConnect) + return true; + else if (myTryingToConnect) + return true; + else + return false; + } + + /// Logs the information about the sensor + AREXPORT void log(void); +protected: + /// Sets the parameters that control what data you get from the urg + AREXPORT bool setParams( + double startingDegrees = -135, double endingDegrees = 135, + double incrementDegrees = 1, bool flipped = false); + /// Sets the parameters that control what data you get from the urg + AREXPORT bool setParamsBySteps( + int startingStep = 0, int endingStep = 768, int clusterCount = 3, + bool flipped = false); + AREXPORT virtual void * runThread(void *arg); + /// internal call to write a string to the urg + bool writeLine(const char *str); + /// internal call to read a string from the urg + bool readLine(char *buf, unsigned int size, unsigned int msWait, + bool noChecksum, bool stripLastSemicolon, + ArTime *firstByte = NULL); + + /// internal call to write a command and get the response back into the buf + bool sendCommandAndRecvStatus( + const char *command, const char *commandDesc, + char *status, unsigned int size, unsigned int msWait); + + void sensorInterp(void); + AREXPORT virtual void setRobot(ArRobot *robot); + AREXPORT virtual bool laserCheckParams(void); + AREXPORT virtual void laserSetName(const char *name); + + void failedToConnect(void); + ArMutex myReadingMutex; + ArMutex myDataMutex; + + ArTime myReadingRequested; + std::string myReading; + + int myStartingStep; + int myEndingStep; + int myClusterCount; + bool myFlipped; + char myRequestString[1024]; + double myClusterMiddleAngle; + + bool internalConnect(void); + + bool internalGetReading(void); + + void clear(void); + bool myIsConnected; + bool myTryingToConnect; + bool myStartConnect; + + std::string myVendor; + std::string myProduct; + std::string myFirmwareVersion; + std::string myProtocolVersion; + std::string mySerialNumber; + std::string myStat; + + std::string myModel; + int myDMin; + int myDMax; + int myARes; + int myAMin; + int myAMax; + int myAFront; + int myScan; + + double myStepSize; + double myStepFirst; + bool myUseThreeDataBytes; + + bool myLogMore; + + ArFunctorC mySensorInterpTask; + ArRetFunctorC myAriaExitCB; +}; + +#endif // ARURG_2_0_H diff --git a/Legacy/Aria/include/ArVCC4.h b/Legacy/Aria/include/ArVCC4.h new file mode 100644 index 0000000..4a46cda --- /dev/null +++ b/Legacy/Aria/include/ArVCC4.h @@ -0,0 +1,599 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARVCC4_H +#define ARVCC4_H + +#include "ariaTypedefs.h" +#include "ArBasePacket.h" +#include "ArPTZ.h" +#include "ariaUtil.h" +#include "ArCommands.h" +#include "ArSerialConnection.h" + +// maximum number of bytes expected for a response from the camera +#define MAX_RESPONSE_BYTES 14 + +// the state timeout when using bidirectional communication +// This is big because it may have to wait for a power on or +// power off command to complete, which take ~4 seconds. +#define BIDIRECTIONAL_TIMEOUT 5000 + +// The number of ms to wait for a timeout for unidirectional communication. +// This is how long the usertask will wait before assuming that the camera +// has processed the last command. +#define UNIDIRECTIONAL_TIMEOUT 300 + +// how often to request position information from the camera if using +// bidirectional communication (in ms) +#define AUTO_UPDATE_TIME 2000 + +// accuracy of camera movements. This sets how different the current +// position and the desired position must be in order for a command to be +// sent to the camera. +#define TOLERANCE .1 + +/** @class ArVCC4 + * Control the pan, tilt, and zoom mechanisms of the Canon VC-C4 and VC-C50i cameras. + * + * An ArVCC4 object can be used to control the pan, tilt, zoom and some + * other aspects of the Canon VC-C4 camera. Since the camera is + * typically connected to the robot microcontroller's auxilliary serial + * port, and also uses ArRobot task cycle callbacks, a connected and + * running ArRobot object is required. + * + * Communication with the camera can operate in two modes or directions. + * In unidirectional mode(COMM_UNIDIRECTIONAL), + * ArVCC4 simply sends commands to the camera, and waits for + * some time to allow the camera to process it. However, it will have + * no way of verifying that a command was successfully received by the + * cameral. In bidirectional mode (COMM_BIDIRECTIONAL), ArVCC4 waits for a + * response from the camera. Bidirectinal mode requires that the CTS + * line (pin 2 on the VISCA port) be connected. + * When you create an ArVCC4 object, you can request a specific mode, + * or you can specify COMM_UNKNOWN, and ArVCC4 will switch into + * bidirectional mode if it receives any responses from the camera. + * + * Programmer's manuals for the VC-C45 and VC-C50i, detailing the + * communications protocol (including commands not implemented by ArVCC4), + * as well as user manuals containing specifications and hardware information, + * are available at http://robots.mobilerobots.com. + * ArVCC4 sends commands to the camera using the ArVCC4Packet class to construct the command, and + * using either the ArRobot pointer or an internal ArDeviceConnection, + * depending on whether the camera is connected to the robot + * microcontroller's auxilliary serial port (the usual connection method for + * most robots) or a computer serial port. + * + +\section VCC4CommandDetails Command-Response details: + +This camera has a reponse mechanism, whereby each packet sent to the camera generates an answer within 300ms. For the most part, the answer consists of a 6-byte packet which has an error-status within it. Some commands generate longer packets. Receiving the error status is helpful in that you know that the camera will or will not execute the command. However, it doesn't tell you when the command is completed. + +In order for the the reponses to work, the CTS line on the camera must be high. This is pin 2 on the visca port. If your camera is not wired in such a fashion, then no answers will be sent to the computer, and the computer will not know whether or not the last packet was processed correctly. Because of this, systems operating without the answer feature will need to run with delays between sending packets. Otherwise, packets will be ignored, but you will have no way of knowing that. To achieve this, there are two types of communication modes that this class will operate under - COMM_UNIDIRECTIONAL or COMM_BIDIRECTIONAL. The default is COMM_UNKNOWN, in which it will use bidirectional commuication if a response is received. + +To handle the states and packet processing, this class runs as a user-task, different than the other pan/tilt devices. Because of this, it must have a valid robot connection and a valid serial connection if using a computer serial port. Note that the computer port must be set independently of this class. The aux port can be selected via setAuxPort from the ArPTZ class. + +\section VCC4UnitConversions Unit Conversions: + +The camera's pan and tilt commands work on a number of units equal to (degrees / 0.1125). The panTilt function always rounds the conversion closer to zero, so that a magnitude greater than the allowable range of movement is not sent to the camera. + + +\section VCC4C50iFeatures C50i features: + +NEW - There is now limited support for the night-mode version of the C50i. To enable night-mode support, pass the camera type in with the constructor. Night-mode consists of two parts - a phsyical IR-cutoff filter, and IR LEDs. The cutoff filter must be enabled first, then turn on the IR LEDs. + +This camera has a digital zoom as well as the optical one. There is an additional function for handling the digital. There is also limited support for the auto-focus mechanism, which may need to be elaborated on for better night-vision. In addition to the focus, there are also gain and backlight adjustments that can be made, but are not yet implemented in this class. +*/ + +/// Used by the ArVCC4 class +class ArVCC4Commands +{ +public: + enum Command { + DELIM = 0x00, /// myTaskCB; + + // the actual task to be added as a usertask + void camTask(void); + + // true when a response has been received from the camera, but has + // not yet been acted on by the state machine + bool myResponseReceived; + + bool myWaitingOnStop; + bool myWaitingOnPacket; + + // the state of the state machine + State myState; + State myPreviousState; + State myNextState; + + // used to switch between states in the state machine + void switchState(State state, int delayTime = 0); + + // the max time before a state times out, and the time for a packet response + // to timeout. The difference being that a packet reponse can be received + // immediately, but it could say that the camera is busy, meaning the state + // has not yet completed + int myStateTimeout; + int myPacketTimeout; + + // request a packet from the microcontroller of size num bytes. + // most camera responses are 6 bytes, so just use the default + void requestBytes(int num = 6); + + // the buffer to store the incoming packet data in + unsigned char myPacketBuf[50]; + int myPacketBufLen; + + // how many bytes we're still expecting to receive from the controller + int myBytesLeft; + + // these all send commands to the camera. + bool sendPanTilt(void); + bool sendZoom(void); + bool sendPanSlew(void); + bool sendTiltSlew(void); + bool sendPower(void); + bool sendHaltPanTilt(void); + bool sendHaltZoom(void); + bool sendRealPanTiltRequest(void); + bool sendRealZoomRequest(void); + bool sendDigitalZoom(void); + bool sendFocus(void); + + // this is currently not used because it doesn't work right + bool sendProductNameRequest(void); + + // the camera type is used to specify VC-C4 vs. C50i + CameraType myCameraType; + bool myRequestProductName; + + bool sendLEDControlMode(void); + bool sendCameraNameRequest(void); + int myDesiredLEDControlMode; + + bool sendIRFilterControl(void); + bool sendIRLEDControl(void); + bool myIRLEDsEnabled; + bool myDesiredIRLEDsMode; + bool myIRFilterModeEnabled; + bool myDesiredIRFilterMode; + + // These should only be used by the state machine to initialize the + // camera for the first time + bool setDefaultRange(void); + bool setControlMode(void); + bool sendInit(void); + + // process the packet data for a camera response that has accurate + // pan/tilt positional information in it, and the product name + void processGetPanTiltResponse(void); + void processGetZoomResponse(void); + void processGetProductNameResponse(void); + + // true if autoupdating of camera's position should be used + bool myAutoUpdate; + + // cycle for stepping through various autoupdate resquests from the camera + int myAutoUpdateCycle; + + // returns true if there is no reponse to a packet within the timeout + // or also if the state times out. The argument will overrid the default + // timeout periods + bool timeout(int mSec = 0); + + // internal reperesenstation of pan, tilt, and zoom positions + double myPan; + double myTilt; + int myZoom; + int myDigitalZoom; + int myFocusMode; + + // used to store the returned positional values when requesting the true + // position from the camera + double myPanResponse; + double myTiltResponse; + int myZoomResponse; + + // the returned product name + char myProductNameResponse[4]; + + // the positions that were last sent to the camera. These are needed + // because the desired positions can change between time a command is + // sent and before it succeeds. + double myPanSent; + double myTiltSent; + int myZoomSent; + double myPanSlewSent; + double myTiltSlewSent; + + // internal representation of pan and tilt slew + double myPanSlew; + double myTiltSlew; + + // where the user has requested the camera move to + double myPanDesired; + double myTiltDesired; + int myZoomDesired; + int myDigitalZoomDesired; + int myFocusModeDesired; + + // the pan an tilt slew that the user requested + double myPanSlewDesired; + double myTiltSlewDesired; + + // internal mirror of camera power state, and whether it's be initted + bool myPowerState; + bool myCameraIsInitted; + + // whether the user wants the camera on or off, or initialized + bool myPowerStateDesired; + bool myInitRequested; + + // whether the user has requested to halt movement + bool myHaltZoomRequested; + bool myHaltPanTiltRequested; + + // whether the camera has been initialized since instance inception + bool myCameraHasBeenInitted; + + // true if the user has requested to update the camera's postion + // from the data returned from the camera + bool myRealPanTiltRequested; + bool myRealZoomRequested; + + // the error state from the last packet received + unsigned int myError; + + // our FOV numbers (these should change if we use the digital zoom) + double myFOVAtMaxZoom; + double myFOVAtMinZoom; + + // run through the list or error callbacks + void throwError(); + + // the list of error callbacks to step through when a error occurs + std::list myErrorCBList; + + /// Used by ArPTZConnector to create an ArVCC4 object based on robot parameters and program options. + /// @since 2.7.6 + /// @internal + static ArPTZ* create(size_t index, ArPTZParams params, ArArgumentParser *parser, ArRobot *robot); + /// Used by ArPTZConnector to create an ArVCC4 object based on robot parameters and program options. + /// @since 2.7.6 + /// @internal + static ArPTZConnector::GlobalPTZCreateFunc ourCreateFunc; +public: +#ifndef SWIG + static void registerPTZType(); ///<@internal Called by Aria::init() toregister this class with ArPTZConnector for vcc4 and vcc50i PTZ types. @since 2.7.6 +#endif +}; + +#endif // ARVCC4_H + diff --git a/Legacy/Aria/include/ArVersalogicIO.h b/Legacy/Aria/include/ArVersalogicIO.h new file mode 100644 index 0000000..fe1421b --- /dev/null +++ b/Legacy/Aria/include/ArVersalogicIO.h @@ -0,0 +1,150 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARVERSALOGICIO_H +#define ARVERSALOGICIO_H + +//#ifndef SWIG + +#include "ariaTypedefs.h" +#include "ArRobot.h" + +/** @brief Interface to integrated digital and analog I/O interfaces on Versalogic VSBC8 and EBX-12 Cobra computers (digital IO on 2nd * gen. PatrolBot) + + This class is a basic set of calls to use the Linux device driver, amrio, + which reads and writes data to VersaLogic's Opto22 and analog interfaces. + The amrio driver must be built into the Linux kernel or its + module loaded. Contact MobileRobots for information about obtaining this + driver. + It currently supports the Versalogic VSBC-8d, VSBC-8k, and EBX12 (Cobra) motherboards. + + The digital portion of the Opto22 consists of two banks of 8 pins on the VSBC8 + and four banks of 8 pins on the EBX12. Each bank can be set as either inputs + or outputs. The banks are zero-indexed, so bank0 is the first one. + + The analog inputs require a separate chip. There are 8 inputs, only + one of which can be read at a time. It currently returns a value between + 0 and 4096 or a decimal value in the range of 0-5V. The constructor will attempt + an analog conversion, and if it fails will assume that the chip is not present + and will disable the analog function. + + See the motherboard manual for information about physical connections and specifications of the analog input and Opto22 digital IO. + Computer motherboard manuals are available at http://robots.mobilerobots.com/docs . + + The SPECIAL_CONTROL_REGISTER contains a few bits of information, the one of + importance at the moment is the CPU_OVERTEMPERATURE bit, which will be set + high if the CPU temp is over the warning temp as set in the BIOS. Bitwise + AND the special_control_register output with 0x20 to find the temperature + bit. + + The destructor closes the device, so just delete the ArVersalogicIO instance + to close the device. + + @ingroup OptionalClasses + @ingroup DeviceClasses + + @notwindows +*/ + +class ArVersalogicIO +{ +public: + + enum Direction + { + DIGITAL_INPUT, + DIGITAL_OUTPUT + }; + + /// Constructor + AREXPORT ArVersalogicIO(const char * dev = "/dev/amrio"); + /// Destructor + AREXPORT virtual ~ArVersalogicIO(void); + + /// tries to close the device. Returns false if operation failed + AREXPORT bool closeIO(void); + + /// returns true if the device is opened and operational + AREXPORT bool isEnabled(void) { return myEnabled; } + + /// returns true if analog values are supported + AREXPORT bool isAnalogSupported(void) { return myAnalogEnabled; } + + /// Take an analog reading from a port number from 0-7. + /// This returns a conversion of the bits to a decimal value, + /// currently assumed to be in the 0-5V range + AREXPORT bool getAnalogValue(int port, double *val); + + /// Take an analog reading from a port number from 0-7. + /// This returns the actual reading from the chip, which is 12-bits + AREXPORT bool getAnalogValueRaw(int port, int *val); + + /// returns the direction (input or output) for the given bank + AREXPORT Direction getDigitalBankDirection(int bank); + + /// set direction for a particular digital I/O bank + AREXPORT bool setDigitalBankDirection(int bank, Direction dir); + + /// get the current value of the digital inputs on a certain bank + AREXPORT bool getDigitalBankInputs(int bank, unsigned char *val); + + /// get the current value of the digital outputs bits on a certain bank + AREXPORT bool getDigitalBankOutputs(int bank, unsigned char *val); + + /// set the value of the digital outputs bits + AREXPORT bool setDigitalBankOutputs(int bank, unsigned char val); + + /// gets the special register of the motherboard. + AREXPORT bool getSpecialControlRegister(unsigned char *val); + + /// lock the amrio device instance + AREXPORT int lock(void){ return(myMutex.lock()); } + /// unlock the amrio device instance + AREXPORT int unlock(void){ return(myMutex.unlock()); } + + /// Try to lock the device instance without blocking + AREXPORT int tryLock() {return(myMutex.tryLock());} + +protected: + + static ArMutex myMutex; + int myFD; + + bool myEnabled; + bool myAnalogEnabled; + + int myNumBanks; + + unsigned char myDigitalBank0; + unsigned char myDigitalBank1; + unsigned char myDigitalBank2; + unsigned char myDigitalBank3; + + ArRetFunctorC myDisconnectCB; +}; + +//#endif // SWIG + +#endif // ARVERSALOGICIO_H diff --git a/Legacy/Aria/include/ArZippable.h b/Legacy/Aria/include/ArZippable.h new file mode 100644 index 0000000..6d4a805 --- /dev/null +++ b/Legacy/Aria/include/ArZippable.h @@ -0,0 +1,205 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ + +#ifndef ARZIPPABLE_H +#define ARZIPPABLE_H + +#include "ariaTypedefs.h" + + +/// Interface to access and modify a specified zip file. +/** + * ArZippable is an abstract base class that defines the methods to add + * and extract files from a zip file. + * + * An ArZippable is expected to be used in a rather "atomic" manner. It can + * be opened in one of two modes (ZIP_MODE or UNZIP_MODE), and the available + * operations are subsequently restricted based on the mode: + *
    + *
  • ZIP_MODE: addAll() and addFile()
  • + *
  • UNZIP_MODE: getMemberInfoList(), extractAll(), and extractFile()
  • + *
+ * After the files are added to or extracted from the zip file, it should be + * close()'ed. + * +**/ +class ArZippable +{ +public: + + // TODO Mutex for multithreaded access? + + // TODO Add more values and allow this to be configured? + enum { + CASE_INSENSITIVE = 2 + }; + + /// Constructor + AREXPORT ArZippable() + {} + + /// Destructor + AREXPORT virtual ~ArZippable() + {} + + /// Returns the complete file path name of the zip file + AREXPORT virtual const char *getFilePathName() const = 0; + + /// Modes in which the zip file may be opened + enum ModeType { + ZIP_MODE, //< Mode for zipping, i.e. adding files to the zip file + UNZIP_MODE //< Mode for unzipping, i.e. extracting files from the zip file + }; + + + /// Opens the zip file in the specified mode + /** + * @param mode the ModeType in which the file should be opened + * @return bool true if the zip file was successfully opened in the specified + * mode; false, otherwise. + **/ + AREXPORT virtual bool open(ModeType mode) = 0; + + /// Closes the zip file + AREXPORT virtual void close() = 0; + + /// Determines whether the zip file exists (according to the file path name) + /** + * @return bool true if the file exists and can be read; false, otherwise + **/ + AREXPORT virtual bool exists() const = 0; + + + /// Determines whether the zip file contains the specified member name + /** + * @param memberName the char * name of the member to be found + * @return bool true if the zip file contains the specified member; false + * otherwise + **/ + AREXPORT virtual bool contains(const char *memberName) = 0; + + + // TODO: Perhaps add a callback to be invoked when isOverwrite is false and + // an overwrite condition is detected + + /// Extracts all of the files from the zip file. + /** + * The zip file must have been opened in UNZIP_MODE. + * + * @param destDir the char * name of the directory into which the extracted + * files are to be placed + * @param isOverwrite a bool set to true if an extracted file should overwrite + * an existing file of the same name in the destination directory; false if + * it should be skipped + * @param password an optional char * password to be applied to the extraction + * @return bool set to true if all files were successfully extracted (or + * correctly skipped); false if an error occurred + **/ + AREXPORT virtual bool extractAll(const char *destDir, + bool isOverwrite, + const char *password = NULL) = 0; + + /// Extracts the specified file from the zip file. + /** + * The zip file must have been opened in UNZIP_MODE. + * + * @param memberName the char * name of the file that should be extracted + * @param destDir the char * name of the directory into which the extracted + * files are to be placed + * @param isOverwrite a bool set to true if an extracted file should overwrite + * an existing file of the same name in the destination directory; false if + * it should be skipped + * @param destFileName an optional char * name of the destination file to be + * written; if NULL, then memberName is used + * @param password an optional char * password to be applied to the extraction + * @return bool set to true if the file was successfully extracted (or + * correctly skipped); false if an error occurred + **/ + AREXPORT virtual bool extractFile(const char *memberName, + const char *destDir, + bool isOverwrite, + const char *destFileName = NULL, + const char *password = NULL) = 0; + + + /// Adds all of the files in the specified directory to the zip file. + /** + * The zip file must have been opened in ZIP_MODE. + * + * @param sourceDir the char * name of the directory from which the files + * are to be added + * @param isIncludeSubDirs a bool set to true if all files in all subdirectories + * should also be added to the zip file; false otherwise + * @param isOverwrite a bool set to true if a file to be added should overwrite + * an existing zip file member of the same name; false if it should be skipped + * @param password an optional char * password to be applied to the addition + * @param flush an optional int indication of how the zip file should be flushed + * when writing (for error recovery); implementation dependent + * @return bool set to true if all files were successfully added (or + * correctly skipped); false if an error occurred + **/ + AREXPORT virtual bool addAll(const char *sourceDir, + bool isIncludeSubDirs, + bool isOverwrite, + const char *password = NULL, + int flush = 0) = 0; + + /// Adds the specified file to the zip file. + /** + * The zip file must have been opened in ZIP_MODE. + * + * @param memberName the char * name of the member to be added in the zip file + * @param isOverwrite a bool set to true if a file to be added should overwrite + * an existing zip file member of the same name; false if it should be skipped + * @param sourceFileName the char * name of the file to be added + * @param password an optional char * password to be applied to the addition + * @param flush an optional int indication of how the zip file should be flushed + * when writing (for error recovery); implementation dependent + * @return bool set to true if all files were successfully added (or + * correctly skipped); false if an error occurred + **/ + AREXPORT virtual bool addFile(const char *memberName, + bool isOverwrite, + const char *sourceFileName, + const char *password, + int flush = 0) = 0; + + +private: + + /// Disabled copy constructor + ArZippable( const ArZippable & ); + /// Disabled assignment operator. + ArZippable &operator=( const ArZippable & ); + +protected: + + +}; // end class ArZippable + + +#endif // ARZIPPABLE_H + diff --git a/Legacy/Aria/include/Aria.h b/Legacy/Aria/include/Aria.h new file mode 100644 index 0000000..7ebeab7 --- /dev/null +++ b/Legacy/Aria/include/Aria.h @@ -0,0 +1,159 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARIA_H +#define ARIA_H + +#include "ariaOSDef.h" +#include "ariaTypedefs.h" +#include "ArSerialConnection.h" +#include "ArTcpConnection.h" +#include "ArSimpleConnector.h" +#include "ArLogFileConnection.h" +#include "ArLog.h" +#include "ArRobotPacket.h" +#include "ArRobotPacketSender.h" +#include "ArRobotPacketReceiver.h" +#include "ArRobotConfigPacketReader.h" +#include "ArRobotTypes.h" +#include "ariaUtil.h" +#include "ArArgumentBuilder.h" +#include "ArArgumentParser.h" +#include "ArFileParser.h" +#include "ArConfig.h" +#include "ArConfigArg.h" +#include "ArConfigGroup.h" +#include "ArRobot.h" +#include "ArCommands.h" +#include "ArJoyHandler.h" +#include "ArSyncTask.h" +#include "ArTaskState.h" +#include "ariaInternal.h" +#include "ArSonarDevice.h" +#include "ArPriorityResolver.h" +#include "ArAction.h" +#include "ArActionGroup.h" +#include "ArActionGroups.h" +#include "ArActionDeceleratingLimiter.h" +#include "ArActionLimiterForwards.h" +#include "ArActionLimiterBackwards.h" +#include "ArActionLimiterTableSensor.h" +#include "ArActionBumpers.h" +#include "ArActionIRs.h" +#include "ArActionStallRecover.h" +#include "ArActionAvoidFront.h" +#include "ArActionAvoidSide.h" +#include "ArActionConstantVelocity.h" +#include "ArActionInput.h" +#include "ArActionRobotJoydrive.h" +#include "ArActionJoydrive.h" +#include "ArActionKeydrive.h" +#include "ArActionTriangleDriveTo.h" +#include "ArActionTurn.h" +#include "ArActionRatioInput.h" +#include "ArActionStop.h" +#include "ArActionGoto.h" +#include "ArModule.h" +#include "ArModuleLoader.h" +#include "ArRecurrentTask.h" +#include "ArInterpolation.h" +#include "ArGripper.h" +#include "ArSonyPTZ.h" +#include "ArRVisionPTZ.h" +#include "ArAMPTU.h" +#include "ArP2Arm.h" +#include "ArACTS.h" +#include "ArSick.h" +#include "ArLaserLogger.h" +#include "ArIrrfDevice.h" +#include "ArKeyHandler.h" +#include "ArDPPTU.h" +#include "ArVCC4.h" +#include "ArMode.h" +#include "ArModes.h" +#include "ArNetServer.h" +#include "ArSignalHandler.h" +#include "ArAnalogGyro.h" +#include "ArMapInterface.h" +#include "ArMapObject.h" +#include "ArMap.h" +#include "ArLineFinder.h" +#include "ArBumpers.h" +#include "ArIRs.h" +#include "ArDrawingData.h" +#include "ArForbiddenRangeDevice.h" +#include "ArTCM2.h" +#if !defined(WIN32) && !defined(SWIGWIN) +#include "ArVersalogicIO.h" +#include "ArMTXIO.h" +#endif +#include "ArActionGotoStraight.h" +#include "ArDataLogger.h" +#include "ArRobotJoyHandler.h" +#include "ArRatioInputKeydrive.h" +#include "ArRatioInputJoydrive.h" +#include "ArRatioInputRobotJoydrive.h" +#include "ArActionMovementParameters.h" +#include "ArSoundPlayer.h" +#include "ArSoundsQueue.h" +#include "ArCameraCollection.h" +#include "ArCameraCommands.h" +#include "ArStringInfoGroup.h" +#include "ArSonarAutoDisabler.h" +#include "ArActionDriveDistance.h" +#include "ArLaserReflectorDevice.h" +#include "ArRobotConfig.h" +#include "ArTCMCompassRobot.h" +#include "ArTCMCompassDirect.h" +#include "ArLaserFilter.h" +#include "ArUrg.h" +#include "ArSpeech.h" +#include "ArGPS.h" +#include "ArTrimbleGPS.h" +#include "ArNovatelGPS.h" +#include "ArGPSCoords.h" +#include "ArLaser.h" +#include "ArRobotConnector.h" +#include "ArLaserConnector.h" +#include "ArSonarConnector.h" +#include "ArBatteryConnector.h" +#include "ArLCDConnector.h" +#include "ArSonarMTX.h" +#include "ArBatteryMTX.h" +#include "ArLCDMTX.h" +#include "ArSimulatedLaser.h" +#include "ArExitErrorSource.h" +#include "ArActionLimiterRot.h" +#include "ArRobotBatteryPacketReader.h" +#include "ArLMS1XX.h" +#include "ArUrg_2_0.h" +#include "ArActionMovementParametersDebugging.h" +#include "ArZippable.h" +#include "ArS3Series.h" +#include "ArSZSeries.h" +#include "ArRobotPacketReaderThread.h" +#include "ArHasFileName.h" + +#endif // ARIA_H diff --git a/Legacy/Aria/include/ariaInternal.h b/Legacy/Aria/include/ariaInternal.h new file mode 100644 index 0000000..b45fabc --- /dev/null +++ b/Legacy/Aria/include/ariaInternal.h @@ -0,0 +1,333 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARIAINTERNAL_H +#define ARIAINTERNAL_H + + +#include "ArMutex.h" +#include "ArFunctor.h" +#include "ArConfig.h" + +#ifndef ARINTERFACE +#include "ArStringInfoGroup.h" +class ArRobot; +class ArRobotJoyHandler; +class ArSonarMTX; +class ArBatteryMTX; +class ArLCDMTX; +#endif // ARINTERFACE + +class ArKeyHandler; +class ArJoyHandler; + + +/** Contains global initialization, deinitialization and other global functions + @ingroup ImportantClasses +*/ +class Aria +{ +public: + + typedef enum { + SIGHANDLE_SINGLE, ///< Setup signal handlers in a global, non-thread way + SIGHANDLE_THREAD, ///< Setup a dedicated signal handling thread + SIGHANDLE_NONE ///< Do no signal handling + } SigHandleMethod; + + /// Initialize Aria global data struture and perform OS-specific initialization, including adding OS signal handlers on Linux, initializing sockets library on Windows, etc. + AREXPORT static void init(SigHandleMethod method = SIGHANDLE_THREAD, + bool initSockets = true, + bool sigHandleExitNotShutdown = true); + + /// Performs OS-specific deinitialization, used by shutdown() and exit(). + AREXPORT static void uninit(); + + /// Adds a callback to call when Aria is initialized using init() + AREXPORT static void addInitCallBack(ArFunctor *cb, ArListPos::Pos position); + + /// Adds a callback to call when Aria is uninititialized using uninit() + AREXPORT static void addUninitCallBack(ArFunctor *cb, + ArListPos::Pos position); + + /// Shutdown all Aria processes/threads + AREXPORT static void shutdown(); + + /// Shutdown all Aria processes/threads, call exit callbacks, and exit the program + AREXPORT static void exit(int exitCode = 0); + + /// Sees if Aria is still running (mostly for the thread in main) + AREXPORT static bool getRunning(void); + + /// Sets the directory that ARIA resides in, to override default + AREXPORT static void setDirectory(const char * directory); + + /// Gets the directory that ARIA resides in + AREXPORT static const char *getDirectory(void); + + /// Parses the arguments for the program (calls all the callbacks added with addParseArgsCB()) + AREXPORT static bool parseArgs(void); + + /// Logs all the options for the program (Calls all the callbacks added with addLogOptionsCB()) + AREXPORT static void logOptions(void); + + /// Sets the key handler, so that other classes can find it using getKeyHandler() + AREXPORT static void setKeyHandler(ArKeyHandler *keyHandler); + + /// Gets a pointer to the global key handler, if one has been set with setKeyHandler() + AREXPORT static ArKeyHandler *getKeyHandler(void); + + /// Sets the joystick handler, so that other classes can find it using getJoyHandler() + AREXPORT static void setJoyHandler(ArJoyHandler *joyHandler); + + /// Get a pointer to the joystick handler if one has been set with setJoyHandler() + AREXPORT static ArJoyHandler *getJoyHandler(void); + + /// Adds a functor to by called before program exit by Aria::exit() + AREXPORT static void addExitCallback(ArFunctor *functor, int position = 50); + + /// Removes a functor to by called before program exit by Aria::exit() + AREXPORT static void remExitCallback(ArFunctor *functor); + + /// Sets the log level for the exit callbacks + AREXPORT static void setExitCallbacksLogLevel(ArLog::LogLevel level); + + /// Force an exit of all Aria processes/threads (the old way) + AREXPORT static void exitOld(int exitCode = 0); + + /// Internal, the callback for the signal handling + AREXPORT static void signalHandlerCB(int sig); + + /// Internal, calls the exit callbacks + AREXPORT static void callExitCallbacks(void); + + /// Adds a callback for when we parse arguments + AREXPORT static void addParseArgsCB(ArRetFunctor *functor, + int position = 50); + + /// Sets the log level for the parsing function + AREXPORT static void setParseArgLogLevel(ArLog::LogLevel level); + + /// Adds a callback for when we log options + AREXPORT static void addLogOptionsCB(ArFunctor *functor, int position = 50); + + /// Adds a type of deviceConnection for Aria to be able to create + AREXPORT static bool deviceConnectionAddCreator( + const char *deviceConnectionType, + ArRetFunctor3 *creator); + + + /// Gets a list of the possible deviceConnection types + AREXPORT static const char *deviceConnectionGetTypes(void); + + /// Gets a list of the possible deviceConnection types (for use in the config) + AREXPORT static const char *deviceConnectionGetChoices(void); + + /// Creates a deviceConnection of the given type + AREXPORT static ArDeviceConnection *deviceConnectionCreate( + const char *deviceConnectionType, const char *port, + const char *defaultInfo, + const char *prefix = "Aria::deviceConnectionCreate"); + +#ifndef ARINTERFACE + /// Sets the robot joystick handler, so that other classes can find it + AREXPORT static void setRobotJoyHandler(ArRobotJoyHandler *robotJoyHandler); + + /// Gets the robot joystick handler if one has been set + AREXPORT static ArRobotJoyHandler *getRobotJoyHandler(void); + + /// Gets the ArConfig for this program + AREXPORT static ArConfig *getConfig(void); + + /// Gets the ArStringInfoGroup for this program + AREXPORT static ArStringInfoGroup *getInfoGroup(void); + + /// Add a robot to the global list of robots + AREXPORT static void addRobot(ArRobot *robot); + + /// Remove a robot from the global list of robots + AREXPORT static void delRobot(ArRobot *robot); + + /// Finds a robot in the global list of robots, by name + AREXPORT static ArRobot *findRobot(char *name); + + /// Get a copy of the global robot list + AREXPORT static std::list * getRobotList(); + + /// Gets the maximum number of lasers to use + AREXPORT static int getMaxNumLasers(void); + + /// Sets the maximum number of lasers to use + AREXPORT static void setMaxNumLasers(int maxNumLasers); + + /// Gets the maximum number of sonars to use + AREXPORT static int getMaxNumSonarBoards(void); + + /// Sets the maximum number of sonars to use + AREXPORT static void setMaxNumSonarBoards(int maxNumSonarBoards); + + /// Gets the maximum number of batteris to use + AREXPORT static int getMaxNumBatteries(void); + + /// Sets the maximum number of batteries to use + AREXPORT static void setMaxNumBatteries(int maxNumBatteries); + + /// Gets the maximum number of lcds to use + AREXPORT static int getMaxNumLCDs(void); + + /// Sets the maximum number of batteries to use + AREXPORT static void setMaxNumLCDs(int maxNumLCDs); + + /// Creates a laser of the given type + AREXPORT static ArLaser *laserCreate( + const char *laserType, int laserNumber, + const char *prefix = "Aria::laserCreate"); + + /// Adds a type of laser for Aria to be able to create + AREXPORT static bool laserAddCreator( + const char *laserType, + ArRetFunctor2 *creator); + + /// Gets a list of the possible laser types + AREXPORT static const char *laserGetTypes(void); + + /// Gets a list of the possible laser types (for use in the config) + AREXPORT static const char *laserGetChoices(void); + + /// Creates a battery of the given type + AREXPORT static ArBatteryMTX *batteryCreate( + const char *batteryType, int batteryNumber, + const char *prefix = "Aria::batteryCreate"); + + /// Adds a type of battery for Aria to be able to create + AREXPORT static bool batteryAddCreator( + const char *batteryType, + ArRetFunctor2 *creator); + + /// Gets a list of the possible battery types + AREXPORT static const char *batteryGetTypes(void); + /// Gets a list of the possible battery types (for use in the config) + AREXPORT static const char *batteryGetChoices(void); + + /// Creates a lcd of the given type + AREXPORT static ArLCDMTX *lcdCreate( + const char *lcdType, int lcdNumber, + const char *prefix = "Aria::lcdCreate"); + + /// Adds a type of lcd for Aria to be able to create + AREXPORT static bool lcdAddCreator( + const char *lcdType, + ArRetFunctor2 *creator); + + /// Gets a list of the possible lcd types + AREXPORT static const char *lcdGetTypes(void); + /// Gets a list of the possible lcd types (for use in the config) + AREXPORT static const char *lcdGetChoices(void); + + /// Creates a sonar of the given type + AREXPORT static ArSonarMTX *sonarCreate( + const char *sonarType, int sonarNumber, + const char *prefix = "Aria::sonarCreate"); + + /// Adds a type of sonar for Aria to be able to create + AREXPORT static bool sonarAddCreator( + const char *sonarType, + ArRetFunctor2 *creator); + + /// Gets a list of the possible sonar types + AREXPORT static const char *sonarGetTypes(void); + /// Gets a list of the possible sonar types (for use in the config) + AREXPORT static const char *sonarGetChoices(void); + + /// Set maximum limit on video devices (used by ArVideo library) + AREXPORT static void setMaxNumVideoDevices(size_t n); + /// Get maximum limit on video devices (used by ArVideo library) + AREXPORT static size_t getMaxNumVideoDevices(); + + /// Set maximum limit on PTZ or PTU devices, used by ArPTZConnector. Call before connecting to PTZ devices with ArPTZConnector. + AREXPORT static void setMaxNumPTZs(size_t n); + /// Set maximum limit on PTZ or PTU devices, used by ArPTZConnector. + AREXPORT static size_t getMaxNumPTZs(); +#endif // ARINTERFACE + + /// Gets the identifier (for humans) used for this instance of Aria + AREXPORT static const char *getIdentifier(void); + /// Sets the identifier (for humans) used for this instance of Aria + AREXPORT static void setIdentifier(const char *identifier); + + +protected: + static bool ourInited; + static ArGlobalFunctor1 ourSignalHandlerCB; + static bool ourRunning; + static ArMutex ourShuttingDownMutex; + static bool ourShuttingDown; + static bool ourExiting; + static std::string ourDirectory; + static std::list ourInitCBs; + static std::list ourUninitCBs; + static ArKeyHandler *ourKeyHandler; + static ArJoyHandler *ourJoyHandler; +#ifndef ARINTERFACE + static std::list ourRobots; + static ArRobotJoyHandler *ourRobotJoyHandler; + static ArConfig ourConfig; + static ArStringInfoGroup ourInfoGroup; + static int ourMaxNumLasers; + static int ourMaxNumSonarBoards; + static int ourMaxNumBatteries; + static int ourMaxNumLCDs; + static std::map *, ArStrCaseCmpOp> ourLaserCreatorMap; + static std::string ourLaserTypes; + static std::string ourLaserChoices; + static std::map *, ArStrCaseCmpOp> ourBatteryCreatorMap; + static std::string ourBatteryTypes; + static std::string ourBatteryChoices; + static std::map *, ArStrCaseCmpOp> ourLCDCreatorMap; + static std::string ourLCDTypes; + static std::string ourLCDChoices; + static std::map *, ArStrCaseCmpOp> ourSonarCreatorMap; + static std::string ourSonarTypes; + static std::string ourSonarChoices; +#endif // ARINTERFACE + static ArMutex ourExitCallbacksMutex; + static std::multimap ourExitCallbacks; + static bool ourSigHandleExitNotShutdown; + static std::multimap *> ourParseArgCBs; + static ArLog::LogLevel ourParseArgsLogLevel; + static std::multimap ourLogOptionsCBs; + static ArLog::LogLevel ourExitCallbacksLogLevel; + static std::map *, ArStrCaseCmpOp> ourDeviceConnectionCreatorMap; + static std::string ourDeviceConnectionTypes; + static std::string ourDeviceConnectionChoices; + static std::string ourIdentifier; +#ifndef ARINTERFACE + static size_t ourMaxNumVideoDevices; + static size_t ourMaxNumPTZs; +#endif +}; + + +#endif // ARIAINTERNAL_H diff --git a/Legacy/Aria/include/ariaOSDef.h b/Legacy/Aria/include/ariaOSDef.h new file mode 100644 index 0000000..3feadc9 --- /dev/null +++ b/Legacy/Aria/include/ariaOSDef.h @@ -0,0 +1,78 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARIAOSDEF_H +#define ARIAOSDEF_H + +#if defined(_WIN32) && !defined(WIN32) +#define WIN32 _WIN32 +#endif + +#if defined(WIN32) && !defined(MINGW) + +//// +//// Windows - Massage the windows compiler into working +//// + +// Turn off warning of usage of 'this' in +// constructor chaining +#pragma warning(disable:4355) + +// Turn off warning about truncated identifiers which happens +// in debug builds of code using STL templatized stuff. +#pragma warning(disable:4786) + +// Turn off warning about 'benign macro redef'. +#pragma warning(disable:4142) + +// Turn off warning about loosing from the conversion to double. +#pragma warning(disable:4244) + +// Turn off warning about forcing value to bool 'true' or 'false'. +#pragma warning(disable:4800) + +// Turn off warning about using some standard C libraries that have been deprecated +// by MSVC. (e.g. they want you to use snprintf_s instead of snprintf, etc.) +#pragma warning(disable:4996) + +// Warning about "new behavior" in VC2008 that array elements are not automatically initialized +// (which is normal C++ behavior anyway and ARIA doesn't assume it) +#pragma warning(disable:4351) + + +#include "ariaTypedefs.h" + +// Compatibility functions to help windows out. +inline int strcasecmp(const char *s1, const char *s2) + {return _stricmp(s1, s2);} +inline int strncasecmp(const char *s1, const char *s2, size_t n) + {return _strnicmp(s1, s2, n);} + +#define snprintf _snprintf +#define vsnprintf _vsnprintf +#endif + + +#endif // ARIAOSDEF_H diff --git a/Legacy/Aria/include/ariaTypedefs.h b/Legacy/Aria/include/ariaTypedefs.h new file mode 100644 index 0000000..a174669 --- /dev/null +++ b/Legacy/Aria/include/ariaTypedefs.h @@ -0,0 +1,95 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#ifndef ARTYPEDEFS_H +#define ARTYPEDEFS_H + +#include +#include +#include +#include + +#ifdef WIN32 + + +#ifndef SWIG +#if !defined(ARIA_STATIC) && !defined(AREXPORT) && !defined(MINGW) +#define AREXPORT _declspec(dllimport) +#elif !defined(AREXPORT) // ARIA_STATIC +#define AREXPORT +#endif // ARIA_STATIC +#else +#define AREXPORT +#endif + +#include +#include + +#endif //WIN32L + + +#ifndef WIN32 + +#define AREXPORT +//// +//// Linux +//// + +#endif // linux + + +typedef std::map ArStrMap; + +/// has enum for position in list +class ArListPos +{ +public: + typedef enum { + FIRST = 1, ///< place item first in the list + LAST = 2 ///< place item last in the list + } Pos; +}; + +/// Contains platform independent sized variable types +class ArTypes +{ +public: + /// A single signed byte + typedef char Byte; + /// Two signed bytes + typedef short Byte2; + /// Four signed bytes + typedef int Byte4; + + /// A single unsigned byte + typedef unsigned char UByte; + /// Two unsigned bytes + typedef unsigned short UByte2; + /// Four unsigned bytes + typedef unsigned int UByte4; +}; + + +#endif diff --git a/Legacy/Aria/include/ariaUtil.h b/Legacy/Aria/include/ariaUtil.h new file mode 100644 index 0000000..91aeeba --- /dev/null +++ b/Legacy/Aria/include/ariaUtil.h @@ -0,0 +1,2357 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ + +#ifndef ARIAUTIL_H +#define ARIAUTIL_H + +#define _GNU_SOURCE 1 +#include +// #define _XOPEN_SOURCE 500 +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(_WIN32) || defined(WIN32) +#include +#include +#else +#include +#include +#include +#include +#include +#endif // ifndef win32 + +#include +#include "ariaTypedefs.h" +#include "ArLog.h" +#include "ArFunctor.h" +#include "ArArgumentParser.h" +//#include "ariaInternal.h" +#include "ariaOSDef.h" + +class ArLaser; +class ArBatteryMTX; +class ArLCDMTX; +class ArSonarMTX; +class ArDeviceConnection; + +#ifndef M_PI +#define M_PI 3.1415927 +#endif // of M_PI, windows has a function call instead of a define + +/// Contains various utility functions, including cross-platform wrappers around common system functions. +/** @ingroup UtilityClasses + @ingroup ImportantClasses +*/ +class ArUtil +{ +public: + /// Values for the bits from 0 to 16 + enum BITS { + BIT0 = 0x1, ///< value of BIT0 + BIT1 = 0x2, ///< value of BIT1 + BIT2 = 0x4, ///< value of BIT2 + BIT3 = 0x8, ///< value of BIT3 + BIT4 = 0x10, ///< value of BIT4 + BIT5 = 0x20, ///< value of BIT5 + BIT6 = 0x40, ///< value of BIT6 + BIT7 = 0x80, ///< value of BIT7 + BIT8 = 0x100, ///< value of BIT8 + BIT9 = 0x200, ///< value of BIT9 + BIT10 = 0x400, ///< value of BIT10 + BIT11 = 0x800, ///< value of BIT11 + BIT12 = 0x1000, ///< value of BIT12 + BIT13 = 0x2000, ///< value of BIT13 + BIT14 = 0x4000, ///< value of BIT14 + BIT15 = 0x8000, ///< value of BIT15 + }; + +#ifdef WIN32 + typedef int mode_t; +#endif + + /// Sleep for the given number of milliseconds + AREXPORT static void sleep(unsigned int ms); + + /// Get the time in milliseconds + AREXPORT static unsigned int getTime(void); + + /// Delete all members of a set. Does NOT empty the set. + /** + Assumes that T is an iterator that supports the operator*, operator!= + and operator++. The return is assumed to be a pointer to a class that + needs to be deleted. + */ + template static void deleteSet(T begin, T end) + { + for (; begin != end; ++begin) + { + delete (*begin); + } + } + + /// Delete all members of a set. Does NOT empty the set. + /** + Assumes that T is an iterator that supports the operator**, operator!= + and operator++. The return is assumed to be a pair. The second value of + the pair is assumed to be a pointer to a class that needs to be deleted. + */ + template static void deleteSetPairs(T begin, T end) + { + for (; begin != end; ++begin) + { + delete (*begin).second; + } + } + + /// Returns the minimum of the two values + static int findMin(int first, int second) + { if (first < second) return first; else return second; } + /// Returns the maximum of the two values + static int findMax(int first, int second) + { if (first > second) return first; else return second; } + + /// Returns the minimum of the two values + static double findMin(double first, double second) + { if (first < second) return first; else return second; } + /// Returns the maximum of the two values + static double findMax(double first, double second) + { if (first > second) return first; else return second; } + + /// OS-independent way of finding the size of a file. + AREXPORT static long sizeFile(const char *fileName); + + /// OS-independent way of finding the size of a file. + AREXPORT static long sizeFile(std::string fileName); + + /// OS-independent way of checking to see if a file exists and is readable. + AREXPORT static bool findFile(const char *fileName); + + // OS-independent way of stripping the directory from the fileName. + // commented out with std::string changes since this didn't seem worth fixing right now + //AREXPORT static bool stripDir(std::string fileIn, std::string &fileOut); + + // OS-independent way of stripping the fileName from the directory. + // commented out with std::string changes since this didn't seem worth fixing right now + //AREXPORT static bool stripFile(std::string fileIn, std::string &fileOut); + + /// Appends a slash to a path if there is not one there already + AREXPORT static void appendSlash(char *path, size_t pathLength); + + /// Appends a slash to the given string path if necessary. + AREXPORT static void appendSlash(std::string &path); + + /// Fix the slash orientation in file path string for windows or linux + AREXPORT static void fixSlashes(char *path, size_t pathLength); + + /// Fixes the slash orientation in the given file path string for the current platform + AREXPORT static void fixSlashes(std::string &path); + + /// Fix the slash orientation in file path string to be all forward + AREXPORT static void fixSlashesForward(char *path, size_t pathLength); + + /// Fix the slash orientation in file path string to be all backward + AREXPORT static void fixSlashesBackward(char *path, size_t pathLength); + + /// Returns the slash (i.e. separator) character for the current platform + AREXPORT static char getSlash(); + + /// Adds two directories, taking care of all slash issues + AREXPORT static void addDirectories(char *dest, size_t destLength, + const char *baseDir, + const char *insideDir); + + + + + /// Finds out if two strings are equal + AREXPORT static int strcmp(std::string str, std::string str2); + + /// Finds out if two strings are equal + AREXPORT static int strcmp(std::string str, const char *str2); + + /// Finds out if two strings are equal + AREXPORT static int strcmp(const char *str, std::string str2); + + /// Finds out if two strings are equal + AREXPORT static int strcmp(const char *str, const char *str2); + + /// Finds out if two strings are equal (ignoring case) + AREXPORT static int strcasecmp(std::string str, std::string str2); + + /// Finds out if two strings are equal (ignoring case) + AREXPORT static int strcasecmp(std::string str, const char *str2); + + /// Finds out if two strings are equal (ignoring case) + AREXPORT static int strcasecmp(const char *str, std::string str2); + + /// Finds out if two strings are equal (ignoring case) + AREXPORT static int strcasecmp(const char *str, const char *str2); + + /// Finds out if a string has a suffix + AREXPORT static bool strSuffixCmp(const char *str, const char *suffix); + + /// Finds out if a string has a suffix + AREXPORT static bool strSuffixCaseCmp(const char *str, const char *suffix); + + + /// Compares two strings (ignoring case and surrounding quotes) + /** + * This helper method is primarily used to ignore surrounding quotes + * when comparing ArArgumentBuilder args. + * @return int set to 0 if the two strings are equivalent, a negative + * number if str1 is "less than" str2, and a postive number if it is + * "greater than". + **/ + AREXPORT static int strcasequotecmp(const std::string &str1, + const std::string &str2); + + + /// Puts a \ before spaces in src, puts it into dest + AREXPORT static void escapeSpaces(char *dest, const char *src, + size_t maxLen); + + /// Strips out the quotes in the src buffer into the dest buffer + AREXPORT static bool stripQuotes(char *dest, const char *src,size_t destLen); + + /// Strips the quotes from the given string. + AREXPORT static bool stripQuotes(std::string *strToStrip); + + /// Lowers a string from src into dest, make sure there's enough space + AREXPORT static void lower(char *dest, const char *src, + size_t maxLen); + /// Returns true if this string is only alphanumeric (i.e. it contains only leters and numbers), false if it contains any non alphanumeric characters (punctuation, whitespace, control characters, etc.) + AREXPORT static bool isOnlyAlphaNumeric(const char *str); + + /// Returns true if this string is only numeric (i.e. it contains only numeric + //digits), or it's null, or false if it contains any non nonnumeric characters (alphabetic, punctuation, whitespace, control characters, etc.) + AREXPORT static bool isOnlyNumeric(const char *str); + + /// Returns true if the given string is null or of zero length, false otherwise + AREXPORT static bool isStrEmpty(const char *str); + + /// Determines whether the given text is contained in the given list of strings. + AREXPORT static bool isStrInList(const char *str, + const std::list &list, + bool isIgnoreCase = false); + + /// Returns the floating point number from the string representation of that number in @a nptr, or HUGE_VAL for "inf" or -HUGE_VAL for "-inf". + AREXPORT static double atof(const char *nptr); + + /// Converts an integer value into a string for true or false + AREXPORT static const char *convertBool(int val); + +#ifndef SWIG + /// Function for doing a printf style call to a functor + /** @swigomit */ + AREXPORT static void functorPrintf(ArFunctor1 *functor, + char *str, ...); +#endif + + /// Function for doing a fprintf to a file (here to make a functor for) + AREXPORT static void writeToFile(const char *str, FILE *file); + + /// Gets a string contained in an arbitrary file + AREXPORT static bool getStringFromFile(const char *fileName, + char *str, size_t strLen); + /** + These are for passing into getStringFromRegistry + **/ + enum REGKEY { + REGKEY_CLASSES_ROOT, ///< use HKEY_CLASSES_ROOT + REGKEY_CURRENT_CONFIG, ///< use HKEY_CURRENT_CONFIG + REGKEY_CURRENT_USER, ///< use HKEY_CURRENT_USER + REGKEY_LOCAL_MACHINE, ///< use HKEY_LOCAL_MACHINE + REGKEY_USERS ///< use HKEY_USERS + }; + + /// Returns a string from the Windows registry + AREXPORT static bool getStringFromRegistry(REGKEY root, + const char *key, + const char *value, + char *str, + int len); + + /// Returns a string from the Windows registry, searching each of the following registry root paths in order: REGKEY_CURRENT_USER, REGKEY_LOCAL_MACHINE + AREXPORT static bool findFirstStringInRegistry(const char* key, const char* value, char* str, int len) { + if(!getStringFromRegistry(REGKEY_CURRENT_USER, key, value, str, len)) + return getStringFromRegistry(REGKEY_LOCAL_MACHINE, key, value, str, len); + return true; + } + + AREXPORT static const char *COM1; ///< First serial port device name (value depends on compilation platform) + AREXPORT static const char *COM2; ///< Second serial port device name (value depends on compilation platform) + AREXPORT static const char *COM3; ///< Third serial port device name (value depends on compilation platform) + AREXPORT static const char *COM4; ///< Fourth serial port device name (value depends on compilation platform) + AREXPORT static const char *COM5; ///< Fifth serial port device name (value depends on compilation platform) + AREXPORT static const char *COM6; ///< Sixth serial port device name (value depends on compilation platform) + AREXPORT static const char *COM7; ///< Seventh serial port device name (value depends on compilation platform) + AREXPORT static const char *COM8; ///< Eighth serial port device name (value depends on compilation platform) + AREXPORT static const char *COM9; ///< Ninth serial port device name (value depends on compilation platform) + AREXPORT static const char *COM10; ///< Tenth serial port device name (value depends on compilation platform) + AREXPORT static const char *COM11; ///< Eleventh serial port device name (value depends on compilation platform) + AREXPORT static const char *COM12; ///< Twelth serial port device name (value depends on compilation platform) + AREXPORT static const char *COM13; ///< Thirteenth serial port device name (value depends on compilation platform) + AREXPORT static const char *COM14; ///< Fourteenth serial port device name (value depends on compilation platform) + AREXPORT static const char *COM15; ///< Fifteenth serial port device name (value depends on compilation platform) + AREXPORT static const char *COM16; ///< Sixteenth serial port device name (value depends on compilation platform) + + AREXPORT static const char *TRUESTRING; ///< "true" + AREXPORT static const char *FALSESTRING; ///< "false" + + /** Put the current year (GMT) in s (e.g. "2005"). + * @param s String buffer (allocated) to write year into + * @param len Size of @a s + */ + AREXPORT static void putCurrentYearInString(char* s, size_t len); + /** Put the current month (GMT) in s (e.g. "09" if September). + * @param s String buffer (allocated) to write month into + * @param len Size of @a s + */ + AREXPORT static void putCurrentMonthInString(char* s, size_t len); + /** Put the current day (GMT) of the month in s (e.g. "20"). + * @param s String buffer (allocated) to write day into + * @param len Size of @a s + */ + AREXPORT static void putCurrentDayInString(char* s, size_t len); + /** Put the current hour (GMT) in s (e.g. "13" for 1 o'clock PM). + * @param s String buffer (allocated) to write hour into + * @param len Size of @a s + */ + AREXPORT static void putCurrentHourInString(char* s, size_t len); + /** Put the current minute (GMT) in s (e.g. "05"). + * @param s String buffer (allocated) to write minutes into + * @param len Size of @a s + */ + AREXPORT static void putCurrentMinuteInString(char* s, size_t len); + /** Put the current second (GMT) in s (e.g. "59"). + * @param s String buffer (allocated) to write seconds into + * @param len Size of @a s + */ + AREXPORT static void putCurrentSecondInString(char* s, size_t len); + + + /// Parses the given time string (h:mm) and returns the corresponding time. + /** + * @param str the char * string to be parsed; in the 24-hour format h:mm + * @param ok an output bool * set to true if the time is successfully parsed; + * false, otherwise + * @param toToday true to find the time on the current day, false to find the time on 1/1/70 + * @return time_t if toToday is true then its the parsed time on the current day, if toToday is false then its the parsed time on 1/1/70 + * 1/1/70 + **/ + AREXPORT static time_t parseTime(const char *str, bool *ok = NULL, bool toToday = true); + + + /** Interface to native platform localtime() function. + * On Linux, this is equivalent to a call to localtime_r(@a timep, @a result) (which is threadsafe, including the returned pointer, since it uses a different time struct for each thread) + * On Windows, this is equivalent to a call to localtime(@a timep, @a result). In addition, a static mutex is used to make it threadsafe. + * + * @param timep Pointer to current time (Unix time_t; seconds since epoch) + * @param result The result of calling platform localtime function is copied into this struct, so it must have been allocated. + * @return false on error (e.g. invalid input), otherwise true. + * + * Example: + * @code + * struct tm t; + * ArUtil::localtime(time(NULL), &t); + * ArLog::log("Current month is %d.\n", t.tm_mon); + * @endcode + */ + AREXPORT static bool localtime(const time_t *timep, struct tm *result); + + + /** Call ArUtil::localtime(const time_t*, struct tm *) with the current time obtained by calling + * time(NULL). + * @return false on error (e.g. invalid input), otherwise true. + */ + AREXPORT static bool localtime(struct tm *result); + + // these aren't needed in windows since it ignores case anyhow +#ifndef WIN32 + /// this matches the case out of what file we want + AREXPORT static bool matchCase(const char *baseDir, const char *fileName, + char * result, size_t resultLen); +#endif + /// Pulls the directory out of a file name + AREXPORT static bool getDirectory(const char *fileName, + char * result, size_t resultLen); + /// Pulls the filename out of the file name + AREXPORT static bool getFileName(const char *fileName, + char * result, size_t resultLen); + + /// Sets the timestamp on the specified file + AREXPORT static bool changeFileTimestamp(const char *fileName, + time_t timestamp); + + /// Opens a file, defaulting it so that the file will close on exec + AREXPORT static FILE *fopen(const char *path, const char *mode, + bool closeOnExec = true); + /// Opens a file, defaulting it so that the file will close on exec + AREXPORT static int open(const char *pathname, int flags, + bool closeOnExec = true); + /// Opens a file, defaulting it so that the file will close on exec + AREXPORT static int open(const char *pathname, int flags, mode_t mode, + bool closeOnExec = true); + /// Opens a file, defaulting it so that the file will close on exec + AREXPORT static int creat(const char *pathname, mode_t mode, + bool closeOnExec = true); + /// Opens a pipe, defaulting it so that the file will close on exec + AREXPORT static FILE *popen(const char *command, const char *type, + bool closeOnExec = true); + + + /// Sets if the file descriptor will be closed on exec or not + AREXPORT static void setFileCloseOnExec(int fd, bool closeOnExec = true); + /// Sets if the file descriptor will be closed on exec or not + AREXPORT static void setFileCloseOnExec(FILE *file, bool closeOnExec = true); + + /** Return true if the value of @a f is not NaN and is not infinite (+/- INF) */ + AREXPORT static bool floatIsNormal(double f); + + /** Convert seconds to milliseconds */ + static double secToMSec(const double sec) { return sec * 1000.0; } + + /** Convert milliseconds to seconds */ + static double mSecToSec(const double msec) { return msec / 1000.0; } + + /** Convert meters to US feet */ + static double metersToFeet(const double m) { return m * 3.2808399; } + + /** Convert US feet to meters */ + static double feetToMeters(const double f) { return f / 3.2808399; } + + +protected: +//#ifndef WIN32 + /// this splits up a file name (it isn't exported since it'd crash with dlls) + static std::list splitFileName(const char *fileName); +//#endif + +private: + + /// The character used as a file separator on the current platform (i.e. Linux or Windows) + static const char SEPARATOR_CHAR; + /// The character used as a file separator on the current platform, in a string format + static const char *SEPARATOR_STRING; + /// The character used as a file separator on the other platforms (i.e. slash in opposite direction) + static const char OTHER_SEPARATOR_CHAR; + +#ifdef WIN32 + // Used on Windows to make ArUtil::localtime() function threadsafe + static ArMutex ourLocaltimeMutex; +#endif +}; + +/** Common math operations + @ingroup UtilityClasses +*/ +class ArMath +{ +private: + /* see ArMath::epsilon() */ + static const double ourEpsilon; + + // see getRandMax()) + static const long ourRandMax; + +public: + + /** @return a very small number which can be used for comparisons of floating + * point values, etc. */ + AREXPORT static double epsilon(); + + + /// This adds two angles together and fixes the result to [-180, 180] + /** + @param ang1 first angle + @param ang2 second angle, added to first + @return sum of the angles, in range [-180,180] + @see subAngle + @see fixAngle */ + static double addAngle(double ang1, double ang2) + { return fixAngle(ang1 + ang2); } + + /// This subtracts one angle from another and fixes the result to [-180,180] + /** + @param ang1 first angle + @param ang2 second angle, subtracted from first angle + @return resulting angle, in range [-180,180] + @see addAngle + @see fixAngle + */ + static double subAngle(double ang1, double ang2) + { return fixAngle(ang1 - ang2); } + + /// Takes an angle and returns the angle in range (-180,180] + /** + @param angle the angle to fix + @return the angle in range (-180,180] + @see addAngle + @see subAngle + */ + static double fixAngle(double angle) + { + if (angle >= 360) + angle = angle - 360.0 * (double)((int)angle / 360); + if (angle < -360) + angle = angle + 360.0 * (double)((int)angle / -360); + if (angle <= -180) + angle = + 180.0 + (angle + 180.0); + if (angle > 180) + angle = - 180.0 + (angle - 180.0); + return angle; + } + + /// Converts an angle in degrees to an angle in radians + /** + @param deg the angle in degrees + @return the angle in radians + @see radToDeg + */ + static double degToRad(double deg) { return deg * M_PI / 180.0; } + + /// Converts an angle in radians to an angle in degrees + /** + @param rad the angle in radians + @return the angle in degrees + @see degToRad + */ + static double radToDeg(double rad) { return rad * 180.0 / M_PI; } + + /// Finds the cos, from angles in degrees + /** + @param angle angle to find the cos of, in degrees + @return the cos of the angle + @see sin + */ + static double cos(double angle) { return ::cos(ArMath::degToRad(angle)); } + + /// Finds the sin, from angles in degrees + /** + @param angle angle to find the sin of, in degrees + @return the sin of the angle + @see cos + */ + static double sin(double angle) { return ::sin(ArMath::degToRad(angle)); } + + /// Finds the tan, from angles in degrees + /** + @param angle angle to find the tan of, in degrees + @return the tan of the angle + */ + static double tan(double angle) { return ::tan(ArMath::degToRad(angle)); } + + /// Finds the arctan of the given y/x pair + /** + @param y the y distance + @param x the x distance + @return the angle y and x form + */ + static double atan2(double y, double x) + { return ArMath::radToDeg(::atan2(y, x)); } + + /// Finds if one angle is between two other angles + static bool angleBetween(double angle, double startAngle, double endAngle) + { + angle = fixAngle(angle); + startAngle = fixAngle(startAngle); + endAngle = fixAngle(endAngle); + if ((startAngle < endAngle && angle > startAngle && angle < endAngle) || + (startAngle > endAngle && (angle > startAngle || angle < endAngle))) + return true; + else + return false; + } + + /// Finds the absolute value of a double + /** + @param val the number to find the absolute value of + @return the absolute value of the number + */ + static double fabs(double val) + { + if (val < 0.0) + return -val; + else + return val; + } + + /// Finds the closest integer to double given + /** + @param val the double to find the nearest integer to + @return the integer the value is nearest to (also caps it within + int bounds) + */ + static int roundInt(double val) + { + val += .49; + if (val > INT_MAX) + return (int) INT_MAX; + else if (val < INT_MIN) + return (int) INT_MIN; + else + return((int) floor(val)); + } + + /// Finds the closest short to double given + /** + @param val the double to find the nearest short to + @return the integer the value is nearest to (also caps it within + short bounds) + */ + static short roundShort(double val) + { + val += .49; + if (val > 32767) + return (short) 32767; + else if (val < -32768) + return (short) -32768; + else + return((short) floor(val)); + } + + + /// Rotates a point around 0 by degrees given + static void pointRotate(double *x, double *y, double th) + { + double cs, sn, xt, yt; + cs = cos(th); + sn = sin(th); + xt = *x; + yt = *y; + *x = cs*xt + sn*yt; + *y = cs*yt - sn*xt; + } + + /** Returns a random number between 0 and RAND_MAX on Windows, 2^31 on Linux + * (see ArUtil::getRandMax()). On Windows, rand() is used, on Linux, lrand48(). */ + static long random(void) + { +#ifdef WIN32 + return(rand()); +#else + return(lrand48()); +#endif + } + + /// Maximum of value returned by random() + AREXPORT static long getRandMax(); + + /** Returns a random number between @a m and @a n. On Windows, rand() is used, + * on Linux lrand48(). */ + AREXPORT static long randomInRange(long m, long n); + + /// Finds the distance between two coordinates + /** + @param x1 the first coords x position + @param y1 the first coords y position + @param x2 the second coords x position + @param y2 the second coords y position + @return the distance between (x1, y1) and (x2, y2) + **/ + static double distanceBetween(double x1, double y1, double x2, double y2) + { return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)); } + + /// Finds the squared distance between two coordinates + /** + use this only where speed really matters + @param x1 the first coords x position + @param y1 the first coords y position + @param x2 the second coords x position + @param y2 the second coords y position + @return the distance between (x1, y1) and (x2, y2) + **/ + static double squaredDistanceBetween(double x1, double y1, double x2, double y2) + { return (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2); } + + /** Base-2 logarithm */ + static double log2(double x) + { + return log10(x) / 0.3010303; // 0.301... is log10(2.0). + } + + /// Platform-independent call to determine whether the given double is not-a-number. + static bool isNan(double d) { +#ifdef WIN32 + return _isnan(d); +#else + return isnan(d); +#endif + } + + static bool isNan(float f) { +#ifdef WIN32 + return _isnan(f); +#else + return isnan(f); +#endif + } + + static bool isFinite(float f) { +#ifdef WIN32 + return _finite(f); +#else + return isfinite(f); +#endif + } + + static bool isFinite(double d) { +#ifdef WIN32 + return _finite(d); +#else + return isfinite(d); +#endif + } + + static bool compareFloats(double f1, double f2, double epsilon) + { + return (fabs(f2-f1) <= epsilon); + } + + static bool compareFloats(double f1, double f2) + { + return compareFloats(f1, f2, epsilon()); + } + + +}; // end class ArMath + +/// Represents an x, y position with an orientation +/** + This class represents a robot position with heading. The heading is + automatically adjusted to be in the range -180 to 180. It also defaults + to 0, and so does not need to be used. (This avoids having 2 types of + positions.) Everything in the class is inline so it should be fast. + + @ingroup UtilityClasses +*/ +class ArPose +{ +public: + + + /// Constructor, with optional initial values + /** + Sets the pose to the given values. The constructor can be called with no + parameters, with just x and y, or with x, y, and th. The given heading (th) + is automatically adjusted to be in the range -180 to 180. + + @param x the double to set the x position to, default of 0 + @param y the double to set the y position to, default of 0 + @param th the double value for the pose's heading (or th), default of 0 + */ + ArPose(double x = 0, double y = 0, double th = 0) : + myX(x), + myY(y), + myTh(ArMath::fixAngle(th)) + {} + + /// Copy Constructor + ArPose(const ArPose &pose) : + myX(pose.myX), myY(pose.myY), myTh(pose.myTh) {} + + /// Destructor + virtual ~ArPose() {} + /// Sets the position to the given values + /** + Sets the position with the given three values, but the theta does not + need to be given as it defaults to 0. + @param x the position to set the x position to + @param y the position to set the y position to + @param th the position to set the th position to, default of 0 + */ + virtual void setPose(double x, double y, double th = 0) + { setX(x); setY(y); setTh(th); } + /// Sets the position equal to the given position + /** @param position the position value this instance should be set to */ + virtual void setPose(ArPose position) + { + setX(position.getX()); + setY(position.getY()); + setTh(position.getTh()); + } + /// Sets the x position + void setX(double x) { myX = x; } + /// Sets the y position + void setY(double y) { myY = y; } + /// Sets the heading + void setTh(double th) { myTh = ArMath::fixAngle(th); } + /// Sets the heading, using radians + void setThRad(double th) { myTh = ArMath::fixAngle(ArMath::radToDeg(th)); } + /// Gets the x position + double getX(void) const { return myX; } + /// Gets the y position + double getY(void) const { return myY; } + /// Gets the heading + double getTh(void) const { return myTh; } + /// Gets the heading, in radians + double getThRad(void) const { return ArMath::degToRad(myTh); } + /// Gets the whole position in one function call + /** + Gets the whole position at once, by giving it 2 or 3 pointers to + doubles. If you give the function a null pointer for a value it won't + try to use the null pointer, so you can pass in a NULL if you don't + care about that value. Also note that th defaults to NULL so you can + use this with just x and y. + @param x a pointer to a double to set the x position to + @param y a pointer to a double to set the y position to + @param th a pointer to a double to set the heading to, defaults to NULL + */ + void getPose(double *x, double *y, double *th = NULL) const + { + if (x != NULL) + *x = myX; + if (y != NULL) + *y = myY; + if (th != NULL) + *th = myTh; + } + /// Finds the distance from this position to the given position + /** + @param position the position to find the distance to + @return the distance to the position from this instance + */ + virtual double findDistanceTo(ArPose position) const + { + return ArMath::distanceBetween(getX(), getY(), + position.getX(), + position.getY()); + } + + /// Finds the square distance from this position to the given position + /** + This is only here for speed, if you aren't doing this thousands + of times a second don't use this one use findDistanceTo + + @param position the position to find the distance to + @return the distance to the position from this instance + **/ + virtual double squaredFindDistanceTo(ArPose position) const + { + return ArMath::squaredDistanceBetween(getX(), getY(), + position.getX(), + position.getY()); + } + /// Finds the angle between this position and the given position + /** + @param position the position to find the angle to + @return the angle to the given position from this instance, in degrees + */ + virtual double findAngleTo(ArPose position) const + { + return ArMath::radToDeg(atan2(position.getY() - getY(), + position.getX() - getX())); + } + /// Logs the coordinates using ArLog + virtual void log(void) const + { ArLog::log(ArLog::Terse, "%.0f %.0f %.1f", myX, myY, myTh); } + + /// Add the other pose's X, Y and theta to this pose's X, Y, and theta (sum in theta will be normalized to (-180,180)), and return the result + virtual ArPose operator+(const ArPose& other) const + { + return ArPose( myX + other.getX(), + myY + other.getY(), + ArMath::fixAngle(myTh + other.getTh()) ); + } + + /// Substract the other pose's X, Y, and theta from this pose's X, Y, and theta (difference in theta will be normalized to (-180,180)), and return the result + + virtual ArPose operator-(const ArPose& other) const + { + return ArPose( myX - other.getX(), + myY - other.getY(), + ArMath::fixAngle(myTh - other.getTh()) ); + } + + /** Adds the given pose to this one. + * @swigomit + */ + ArPose & operator+= ( const ArPose & other) + { + myX += other.myX; + myY += other.myY; + myTh = ArMath::fixAngle(myTh + other.myTh); + return *this; + } + + /** Subtracts the given pose from this one. + * @swigomit + */ + ArPose & operator-= ( const ArPose & other) + { + myX -= other.myX; + myY -= other.myY; + myTh = ArMath::fixAngle(myTh - other.myTh); + return *this; + } + + /// Equality operator (for sets) + virtual bool operator==(const ArPose& other) const + { + return ((fabs(myX - other.myX) < ArMath::epsilon()) && + (fabs(myY - other.myY) < ArMath::epsilon()) && + (fabs(myTh - other.myTh) < ArMath::epsilon())); + } + + virtual bool operator!=(const ArPose& other) const + { + return ((fabs(myX - other.myX) > ArMath::epsilon()) || + (fabs(myY - other.myY) > ArMath::epsilon()) || + (fabs(myTh - other.myTh) > ArMath::epsilon())); + } + + /// Less than operator (for sets) + virtual bool operator<(const ArPose& other) const + { + + if (fabs(myX - other.myX) > ArMath::epsilon()) { + return myX < other.myX; + } + else if (fabs(myY - other.myY) > ArMath::epsilon()) { + return myY < other.myY; + } + else if (fabs(myTh - other.myTh) > ArMath::epsilon()) { + return myTh < other.myTh; + } + // Otherwise... x, y, and th are equal + return false; + + } // end operator < + + /// Finds the distance between two poses (static function, uses no + /// data from any instance and shouldn't be able to be called on an + /// instance) + /** + @param pose1 the first coords + @param pose2 the second coords + @return the distance between the poses + **/ + static double distanceBetween(ArPose pose1, ArPose pose2) + { return ArMath::distanceBetween(pose1.getX(), pose1.getY(), + pose2.getX(), pose2.getY()); } + + +protected: + + double myX; + double myY; + double myTh; +}; + + +/// A class for time readings and measuring durations +/** + This class is for timing durations or time between events. + The time values it stores are relative to an abritrary starting time; it + does not correspond to "real world" or "wall clock" time in any way, + so DON'T use this for keeping track of what time it is, + just for timestamps and relative timing (e.g. "this loop needs to sleep another 100 ms"). + + The recommended methods to use are setToNow() to reset the time, + mSecSince() to obtain the number of milliseconds elapsed since it was + last reset (or secSince() if you don't need millisecond precision), and + mSecSince(ArTime) or secSince(ArTime) to find the difference between + two ArTime objects. + + On systems where it is supported this will use a monotonic clock, + this is an ever increasing system that is not dependent on what + the time of day is set to. Normally for linux gettimeofday is + used, but if the time is changed forwards or backwards then bad + things can happen. Windows uses a time since bootup, which + functions the same as the monotonic clock anyways. You can use + ArTime::usingMonotonicClock() to see if this is being used. Note + that an ArTime will have had to have been set to for this to be a + good value... Aria::init does this however, so that should not be + an issue. It looks like the monotonic clocks won't work on linux + kernels before 2.6. + + @ingroup UtilityClasses +*/ + +class ArTime +{ +public: + /// Constructor. Time is initialized to the current time. + ArTime() { setToNow(); } + + /// Copy constructor + // + ArTime(const ArTime &other) : + mySec(other.mySec), + myMSec(other.myMSec) + {} + + /// Assignment operator + ArTime &operator=(const ArTime &other) + { + if (this != &other) { + mySec = other.mySec; + myMSec = other.myMSec; + } + return *this; + } + + // + /// Destructor + ~ArTime() {} + + /// Gets the number of milliseconds since the given timestamp to this one + long mSecSince(ArTime since) const + { + long long ret = mSecSinceLL(since); + if (ret > INT_MAX) + return INT_MAX; + if (ret < -INT_MAX) + return -INT_MAX; + return ret; + /* The old way that had problems with wrapping + long long timeSince, timeThis; + + timeSince = since.getSec() * 1000 + since.getMSec(); + timeThis = mySec * 1000 + myMSec; + return timeSince - timeThis; + */ + } + /// Gets the number of milliseconds since the given timestamp to this one + long long mSecSinceLL(ArTime since) const + { + long long timeSince, timeThis; + + timeSince = since.getSecLL() * 1000 + since.getMSecLL(); + timeThis = mySec * 1000 + myMSec; + return timeSince - timeThis; + } + /// Gets the number of seconds since the given timestamp to this one + long secSince(ArTime since) const + { + return mSecSince(since)/1000; + } + /// Gets the number of seconds since the given timestamp to this one + long long secSinceLL(ArTime since) const + { + return mSecSinceLL(since)/1000; + } + /// Finds the number of millisecs from when this timestamp is set to to now (the inverse of mSecSince()) + long mSecTo(void) const + { + ArTime now; + now.setToNow(); + return -mSecSince(now); + } + /// Finds the number of millisecs from when this timestamp is set to to now (the inverse of mSecSince()) + long long mSecToLL(void) const + { + ArTime now; + now.setToNow(); + return -mSecSinceLL(now); + } + /// Finds the number of seconds from when this timestamp is set to to now (the inverse of secSince()) + long secTo(void) const + { + return mSecTo()/1000; + } + /// Finds the number of seconds from when this timestamp is set to to now (the inverse of secSince()) + long long secToLL(void) const + { + return mSecToLL()/1000; + } + /// Finds the number of milliseconds from this timestamp to now + long mSecSince(void) const + { + ArTime now; + now.setToNow(); + return mSecSince(now); + } + /// Finds the number of milliseconds from this timestamp to now + long long mSecSinceLL(void) const + { + ArTime now; + now.setToNow(); + return mSecSinceLL(now); + } + /// Finds the number of seconds from when this timestamp was set to now + long secSince(void) const + { + return mSecSince()/1000; + } + /// Finds the number of seconds from when this timestamp was set to now + long long secSinceLL(void) const + { + return mSecSinceLL()/1000; + } + /// returns whether the given time is before this one or not + bool isBefore(ArTime testTime) const + { + if (mSecSince(testTime) < 0) + return true; + else + return false; + } + /// returns whether the given time is equal to this time or not + bool isAt(ArTime testTime) const + { + if (mSecSince(testTime) == 0) + return true; + else + return false; + } + /// returns whether the given time is after this one or not + bool isAfter(ArTime testTime) const + { + if (mSecSince(testTime) > 0) + return true; + else + return false; + } + /// Resets the time + AREXPORT void setToNow(void); + /// Add some milliseconds (can be negative) to this time + bool addMSec(long ms) + { + //unsigned long timeThis; + long long timeThis; + timeThis = mySec * 1000 + myMSec; + //if (ms < 0 && (unsigned)abs(ms) > timeThis) + if (ms < 0 && -ms > timeThis) + { + ArLog::log(ArLog::Terse, "ArTime::addMSec: tried to subtract too many milliseconds, would result in a negative time."); + mySec = 0; + myMSec = 0; + return false; + } + else + { + timeThis += ms; + mySec = timeThis / 1000; + myMSec = timeThis % 1000; + } + return true; + } // end method addMSec + + /// Add some milliseconds (can be negative) to this time + bool addMSecLL(long long ms) + { + //unsigned long timeThis; + long long timeThis; + timeThis = mySec * 1000 + myMSec; + //if (ms < 0 && (unsigned)abs(ms) > timeThis) + if (ms < 0 && -ms > timeThis) + { + ArLog::log(ArLog::Terse, "ArTime::addMSec: tried to subtract too many milliseconds, would result in a negative time."); + mySec = 0; + myMSec = 0; + return false; + } + else + { + timeThis += ms; + mySec = timeThis / 1000; + myMSec = timeThis % 1000; + } + return true; + } // end method addMSec + + + /// Sets the seconds value (since the arbitrary starting time) + void setSec(unsigned long sec) { mySec = sec; } + /// Sets the milliseconds value (occuring after the seconds value) + void setMSec(unsigned long msec) { myMSec = msec; } + /// Gets the seconds value (since the arbitrary starting time) + unsigned long getSec(void) const { return mySec; } + /// Gets the milliseconds value (occuring after the seconds value) + unsigned long getMSec(void) const { return myMSec; } + + /// Sets the seconds value (since the arbitrary starting time) + void setSecLL(unsigned long long sec) { mySec = sec; } + /// Sets the milliseconds value (occuring after the seconds value) + void setMSecLL(unsigned long long msec) { myMSec = msec; } + /// Gets the seconds value (since the arbitrary starting time) + unsigned long long getSecLL(void) const { return mySec; } + /// Gets the milliseconds value (occuring after the seconds value) + unsigned long long getMSecLL(void) const { return myMSec; } + /// Logs the time + void log(const char *prefix = NULL) const + { ArLog::log(ArLog::Terse, + "%sTime: %lld.%lld", + ((prefix != NULL) ? prefix : ""), + mySec, + myMSec); } + /// Gets if we're using a monotonic (ever increasing) clock + static bool usingMonotonicClock() + { +#if defined(_POSIX_TIMERS) && defined(_POSIX_MONOTONIC_CLOCK) + return ourMonotonicClock; +#endif +#ifdef WIN32 + return true; +#endif + return false; + } + + /// Equality operator (for sets) + bool operator==(const ArTime& other) const + { + return isAt(other); + } + + bool operator!=(const ArTime& other) const + { + return (!isAt(other)); + } + + // Less than operator for sets + bool operator<(const ArTime& other) const + { + return isBefore(other); + } // end operator < + +protected: + unsigned long long mySec; + unsigned long long myMSec; +#if defined(_POSIX_TIMERS) && defined(_POSIX_MONOTONIC_CLOCK) + static bool ourMonotonicClock; +#endif + +}; // end class ArTime + + + + +/// A subclass of ArPose that also stores a timestamp (ArTime) +/** + @ingroup UtilityClasses + */ +class ArPoseWithTime : public ArPose +{ +public: + ArPoseWithTime(double x = 0, double y = 0, double th = 0, + ArTime thisTime = ArTime()) : ArPose(x, y, th) + { myTime = thisTime; } + /// Copy Constructor + ArPoseWithTime(const ArPose &pose) : ArPose(pose) {} + virtual ~ArPoseWithTime() {} + void setTime(ArTime newTime) { myTime = newTime; } + void setTimeToNow(void) { myTime.setToNow(); } + ArTime getTime(void) const { return myTime; } +protected: + ArTime myTime; +}; + +/// A class for keeping track of if a complete revolution has been attained +/** + This class can be used to keep track of if a complete revolution has been + done, it is used by doing doing a clearQuadrants when you want to stat + the revolution. Then at each point doing an updateQuadrant with the current + heading of the robot. When didAllQuadrants returns true, then all the + quadrants have been done. + @ingroup UtilityClasses +*/ +class ArSectors +{ +public: + /// Constructor + ArSectors(int numSectors = 8) + { + mySectorSize = 360/numSectors; + mySectors = new int[numSectors]; + myNumSectors = numSectors; + clear(); + } + /// Destructor + virtual ~ArSectors() { delete mySectors; } + /// Clears all quadrants + void clear(void) + { + int i; + for (i = 0; i < myNumSectors; i++) + mySectors[i] = false; + } + /// Updates the appropriate quadrant for the given angle + void update(double angle) + { + int angleInt; + angleInt = ArMath::roundInt(ArMath::fixAngle(angle) + 180); + mySectors[angleInt / mySectorSize] = true; + } + /// Returns true if the all of the quadrants have been gone through + bool didAll(void) const + { + int i; + for (i = 0; i < myNumSectors; i++) + if (mySectors[i] == false) + return false; + return true; + } +protected: + int *mySectors; + int myNumSectors; + int mySectorSize; +}; + + + + +/// Represents geometry of a line in two-dimensional space. +/** + Note this the theoretical line, i.e. it goes infinitely. + For a line segment with endpoints, use ArLineSegment. + @sa ArLineSegment + @ingroup UtilityClasses +**/ +class ArLine +{ +public: + ///// Empty constructor + ArLine() {} + /// Constructor with parameters + ArLine(double a, double b, double c) { newParameters(a, b, c); } + /// Constructor with endpoints + ArLine(double x1, double y1, double x2, double y2) + { newParametersFromEndpoints(x1, y1, x2, y2); } + /// Destructor + virtual ~ArLine() {} + /// Sets the line parameters (make it not a segment) + void newParameters(double a, double b, double c) + { myA = a; myB = b; myC = c; } + /// Sets the line parameters from endpoints, but makes it not a segment + void newParametersFromEndpoints(double x1, double y1, double x2, double y2) + { myA = y1 - y2; myB = x2 - x1; myC = (y2 *x1) - (x2 * y1); } + /// Gets the A line parameter + double getA(void) const { return myA; } + /// Gets the B line parameter + double getB(void) const { return myB; } + /// Gets the C line parameter + double getC(void) const { return myC; } + /// finds the intersection of this line with another line + /** + @param line the line to check if it intersects with this line + @param pose if the lines intersect, the pose is set to the location + @return true if they intersect, false if they do not + **/ + bool intersects(const ArLine *line, ArPose *pose) const + { + double x, y; + double n; + n = (line->getB() * getA()) - (line->getA() * getB()); + // if this is 0 the lines are parallel + if (fabs(n) < .0000000000001) + { + return false; + } + // they weren't parallel so see where the intersection is + x = ((line->getC() * getB()) - (line->getB() * getC())) / n; + y = ((getC() * line->getA()) - (getA() * line->getC())) / n; + pose->setPose(x, y); + return true; + } + /// Makes the given line perpendicular to this one through the given pose + void makeLinePerp(const ArPose *pose, ArLine *line) const + { + line->newParameters(getB(), -getA(), + (getA() * pose->getY()) - (getB() * pose->getX())); + } + /// Calculate the distance from the given point to (its projection on) this line segment + /** + @param pose the the pose to find the perp point of + + @return if the pose does not intersect line it will return < 0 + if the pose intersects the segment it will return the distance to + the intersection + **/ + virtual double getPerpDist(const ArPose &pose) const + { + ArPose perpPose; + ArLine perpLine; + makeLinePerp(&pose, &perpLine); + if (!intersects(&perpLine, &perpPose)) + return -1; + return (perpPose.findDistanceTo(pose)); + } + /// Calculate the squared distance from the given point to (its projection on) this line segment + /** + @param pose the the pose to find the perp point of + + @return if the pose does not intersect line it will return < 0 + if the pose intersects the segment it will return the distance to + the intersection + **/ + virtual double getPerpSquaredDist(const ArPose &pose) const + { + ArPose perpPose; + ArLine perpLine; + makeLinePerp(&pose, &perpLine); + if (!intersects(&perpLine, &perpPose)) + return -1; + return (perpPose.squaredFindDistanceTo(pose)); + } + /// Determine the intersection point between this line segment, and a perpendicular line passing through the given pose (i.e. projects the given pose onto this line segment.) + /** + * If there is no intersection, false is returned. + @param pose The X and Y components of this pose object indicate the point to project onto this line segment. + @param perpPoint The X and Y components of this pose object are set to indicate the intersection point + @return true if an intersection was found and perpPoint was modified, false otherwise. + @swigomit + **/ + bool getPerpPoint(const ArPose &pose, ArPose *perpPoint) const + { + ArLine perpLine; + makeLinePerp(&pose, &perpLine); + return intersects(&perpLine, perpPoint); + } + + /// Equality operator + virtual bool operator==(const ArLine &other) const + { + + return ((fabs(myA - other.myA) <= ArMath::epsilon()) && + (fabs(myB - other.myB) <= ArMath::epsilon()) && + (fabs(myC - other.myC) <= ArMath::epsilon())); + } + /// Inequality operator + virtual bool operator!=(const ArLine &other) const + { + return ((fabs(myA - other.myA) > ArMath::epsilon()) || + (fabs(myB - other.myB) > ArMath::epsilon()) || + (fabs(myC - other.myC) > ArMath::epsilon())); + + } + +protected: + double myA, myB, myC; +}; + +/// Represents a line segment in two-dimensional space. +/** The segment is defined by the coordinates of each endpoint. + @ingroup UtilityClasses +*/ +class ArLineSegment +{ +public: +#ifndef SWIG + /** @swigomit */ + ArLineSegment() {} + /** @brief Constructor with endpoints + * @swigomit + */ + ArLineSegment(double x1, double y1, double x2, double y2) + { newEndPoints(x1, y1, x2, y2); } +#endif // SWIG + /// Constructor with endpoints as ArPose objects. Only X and Y components of the poses will be used. + ArLineSegment(ArPose pose1, ArPose pose2) + { newEndPoints(pose1.getX(), pose1.getY(), pose2.getX(), pose2.getY()); } + virtual ~ArLineSegment() {} + /// Set new end points for this line segment + void newEndPoints(double x1, double y1, double x2, double y2) + { + myX1 = x1; myY1 = y1; myX2 = x2; myY2 = y2; + myLine.newParametersFromEndpoints(myX1, myY1, myX2, myY2); + } + /// Set new end points for this line segment + void newEndPoints(const ArPose& pt1, const ArPose& pt2) + { + newEndPoints(pt1.getX(), pt1.getY(), pt2.getX(), pt2.getY()); + } + /// Get the first endpoint (X1, Y1) + ArPose getEndPoint1(void) const { return ArPose(myX1, myY1); } + /// Get the second endpoint of (X2, Y2) + ArPose getEndPoint2(void) const { return ArPose(myX2, myY2); } + /// Determine where a line intersects this line segment + /** + @param line Line to check for intersection against this line segment. + @param pose if the lines intersect, the X and Y components of this pose are set to the point of intersection. + @return true if they intersect, false if they do not + **/ + bool intersects(const ArLine *line, ArPose *pose) const + { + ArPose intersection; + // see if it intersects, then make sure its in the coords of this line + if (myLine.intersects(line, &intersection) && + linePointIsInSegment(&intersection)) + { + pose->setPose(intersection); + return true; + } + else + return false; + } + + /** @copydoc intersects(const ArLine *line, ArPose *pose) const */ + bool intersects(ArLineSegment *line, ArPose *pose) const + { + ArPose intersection; + // see if it intersects, then make sure its in the coords of this line + if (myLine.intersects(line->getLine(), &intersection) && + linePointIsInSegment(&intersection) && + line->linePointIsInSegment(&intersection)) + { + pose->setPose(intersection); + return true; + } + else + return false; + } +#ifndef SWIG + /// Determine the intersection point between this line segment, and a perpendicular line passing through the given pose (i.e. projects the given pose onto this line segment.) + /** + * If there is no intersection, false is returned. + @param pose The X and Y components of this pose object indicate the point to project onto this line segment. + @param perpPoint The X and Y components of this pose object are set to indicate the intersection point + @return true if an intersection was found and perpPoint was modified, false otherwise. + @swigomit + **/ + bool getPerpPoint(const ArPose &pose, ArPose *perpPoint) const + { + ArLine perpLine; + myLine.makeLinePerp(&pose, &perpLine); + return intersects(&perpLine, perpPoint); + } +#endif + /** @copydoc getPerpPoint(const ArPose&, ArPose*) + * (This version simply allows you to pass the first pose as a pointer, in + * time-critical situations where a full copy of the object would impact + * performance.) + */ + bool getPerpPoint(const ArPose *pose, ArPose *perpPoint) const + { + ArLine perpLine; + myLine.makeLinePerp(pose, &perpLine); + return intersects(&perpLine, perpPoint); + } + /// Calculate the distance from the given point to (its projection on) this line segment + /** + @param pose the the pose to find the perp point of + + @return if the pose does not intersect segment it will return < 0 + if the pose intersects the segment it will return the distance to + the intersection + **/ + virtual double getPerpDist(const ArPose &pose) const + { + ArPose perpPose; + ArLine perpLine; + myLine.makeLinePerp(&pose, &perpLine); + if (!intersects(&perpLine, &perpPose)) + return -1; + return (perpPose.findDistanceTo(pose)); + } + /// Calculate the squared distance from the given point to (its projection on) this line segment + /** + @param pose the the pose to find the perp point of + + @return if the pose does not intersect segment it will return < 0 + if the pose intersects the segment it will return the distance to + the intersection + **/ + virtual double getPerpSquaredDist(const ArPose &pose) const + { + ArPose perpPose; + ArLine perpLine; + myLine.makeLinePerp(&pose, &perpLine); + if (!intersects(&perpLine, &perpPose)) + return -1; + return (perpPose.squaredFindDistanceTo(pose)); + } + + /// Gets the distance from this line segment to a point. + /** + * If the point can be projected onto this line segment (i.e. a + * perpendicular line can be drawn through the point), then + * return that distance. Otherwise, return the distance to the closest + * endpoint. + @param pose the pointer of the pose to find the distance to + **/ + double getDistToLine(const ArPose &pose) const + { + ArPose perpPose; + ArLine perpLine; + myLine.makeLinePerp(&pose, &perpLine); + if (!intersects(&perpLine, &perpPose)) + { + return ArUtil::findMin( + ArMath::roundInt(getEndPoint1().findDistanceTo(pose)), + ArMath::roundInt(getEndPoint2().findDistanceTo(pose))); + } + return (perpPose.findDistanceTo(pose)); + } + + /// Determines the length of the line segment + double getLengthOf() const + { + return ArMath::distanceBetween(myX1, myY1, myX2, myY2); + } + + /// Determines the mid point of the line segment + ArPose getMidPoint() const + { + return ArPose(((myX1 + myX2) / 2.0), + ((myY1 + myY2) / 2.0)); + } + + + /// Gets the x coordinate of the first endpoint + double getX1(void) const { return myX1; } + /// Gets the y coordinate of the first endpoint + double getY1(void) const { return myY1; } + /// Gets the x coordinate of the second endpoint + double getX2(void) const { return myX2; } + /// Gets the y coordinate of the second endpoint + double getY2(void) const { return myY2; } + /// Gets the A line parameter (see ArLine) + double getA(void) const { return myLine.getA(); } + /// Gets the B line parameter (see ArLine) + double getB(void) const { return myLine.getB(); } + /// Gets the C line parameter (see ArLine) + double getC(void) const { return myLine.getC(); } + + /// Internal function for seeing if a point on our line is within our segment + bool linePointIsInSegment(ArPose *pose) const + { + bool isVertical = (ArMath::fabs(myX1 - myX2) < ArMath::epsilon()); + bool isHorizontal = (ArMath::fabs(myY1 - myY2) < ArMath::epsilon()); + + if (!isVertical || !isHorizontal) { + + return (((isVertical) || + (pose->getX() >= myX1 && pose->getX() <= myX2) || + (pose->getX() <= myX1 && pose->getX() >= myX2)) && + ((isHorizontal) || + (pose->getY() >= myY1 && pose->getY() <= myY2) || + (pose->getY() <= myY1 && pose->getY() >= myY2))); + } + else { // single point segment + + return ((ArMath::fabs(myX1 - pose->getX()) < ArMath::epsilon()) && + (ArMath::fabs(myY1 - pose->getY()) < ArMath::epsilon())); + + } // end else single point segment + } + + const ArLine *getLine(void) const { return &myLine; } + + /// Equality operator (for sets) + virtual bool operator==(const ArLineSegment& other) const + { + + return ((fabs(myX1 - other.myX1) < ArMath::epsilon()) && + (fabs(myY1 - other.myY1) < ArMath::epsilon()) && + (fabs(myX2 - other.myX2) < ArMath::epsilon()) && + (fabs(myY2 - other.myY2) < ArMath::epsilon())); + } + + virtual bool operator!=(const ArLineSegment& other) const + { + return ((fabs(myX1 - other.myX1) > ArMath::epsilon()) || + (fabs(myY1 - other.myY1) > ArMath::epsilon()) || + (fabs(myX2 - other.myX2) > ArMath::epsilon()) || + (fabs(myY2 - other.myY2) > ArMath::epsilon())); + + } + + /// Less than operator (for sets) + virtual bool operator<(const ArLineSegment& other) const + { + + if (fabs(myX1 - other.myX1) > ArMath::epsilon()) { + return myX1 < other.myX1; + } + else if (fabs(myY1 - other.myY1) > ArMath::epsilon()) { + return myY1 < other.myY1; + } + if (fabs(myX2 - other.myX2) > ArMath::epsilon()) { + return myX2 < other.myX2; + } + else if (fabs(myY2 - other.myY2) > ArMath::epsilon()) { + return myY2 < other.myY2; + } + // Otherwise... all coords are equal + return false; + } + +protected: + double myX1, myY1, myX2, myY2; + ArLine myLine; +}; + +/** + @brief Use for computing a running average of a number of elements + @ingroup UtilityClasses +*/ +class ArRunningAverage +{ +public: + /// Constructor, give it the number of elements to store to compute the average + AREXPORT ArRunningAverage(size_t numToAverage); + /// Destructor + AREXPORT ~ArRunningAverage(); + /// Gets the average + AREXPORT double getAverage(void) const; + /// Adds a value to the average. An old value is discarded if the number of elements to average has been reached. + AREXPORT void add(double val); + /// Clears the average + AREXPORT void clear(void); + /// Gets the number of elements + AREXPORT size_t getNumToAverage(void) const; + /// Sets the number of elements + AREXPORT void setNumToAverage(size_t numToAverage); + /// Sets if this is using a the root mean square average or just the normal average + AREXPORT void setUseRootMeanSquare(bool useRootMeanSquare); + /// Gets if this is using a the root mean square average or just the normal average + AREXPORT bool getUseRootMeanSquare(void); + /// Gets the number of values currently averaged so far + AREXPORT size_t getCurrentNumAveraged(void); +protected: + size_t myNumToAverage; + double myTotal; + size_t myNum; + bool myUseRootMeanSquare; + std::list myVals; +}; + +/// This is a class for computing a root mean square average of a number of elements +/// @ingroup UtilityClasses +class ArRootMeanSquareCalculator +{ +public: + /// Constructor + AREXPORT ArRootMeanSquareCalculator(); + /// Destructor + AREXPORT ~ArRootMeanSquareCalculator(); + /// Gets the average + AREXPORT double getRootMeanSquare (void) const; + /// Adds a number + AREXPORT void add(int val); + /// Clears the average + AREXPORT void clear(void); + /// Sets the name + AREXPORT void setName(const char *name); + /// Gets the name + AREXPORT const char *getName(void); + /// Gets the num averaged + AREXPORT size_t getCurrentNumAveraged(void); +protected: + long long myTotal; + size_t myNum; + std::string myName; +}; + + +//class ArStrCaseCmpOp : public std::binary_function +/// strcasecmp for sets +/// @ingroup UtilityClasses +struct ArStrCaseCmpOp +{ +public: + bool operator() (const std::string &s1, const std::string &s2) const + { + return strcasecmp(s1.c_str(), s2.c_str()) < 0; + } +}; + +/// ArPose less than comparison for sets +/// @ingroup UtilityClasses +struct ArPoseCmpOp +{ +public: + bool operator() (const ArPose &pose1, const ArPose &pose2) const + { + return (pose1 < pose2); + + //return (pose1.getX() < pose2.getX() || pose1.getY() < pose2.getY() || + // pose1.getTh() < pose2.getTh()); + } +}; + +/// ArLineSegment less than comparison for sets +/// @ingroup UtilityClasses +struct ArLineSegmentCmpOp +{ +public: + bool operator() (const ArLineSegment &line1, + const ArLineSegment &line2) const + { + return (line1 < line2); + + //return (line1.getX1() < line2.getX1() || line1.getY1() < line2.getY1() || + // line1.getX2() < line2.getX2() || line1.getY2() < line2.getY2()); + } +}; + + +#if !defined(WIN32) && !defined(SWIG) +/** @brief Switch to running the program as a background daemon (i.e. fork) (Only available in Linux) + @swigomit + @notwindows + @ingroup UtilityClasses + @ingroup OptionalClasses + */ +class ArDaemonizer +{ +public: + /// Constructor that sets up for daemonizing if arg checking + AREXPORT ArDaemonizer(int *argc, char **argv, bool closeStdErrAndStdOut); + /// Destructor + AREXPORT ~ArDaemonizer(); + /// Daemonizes if asked too by arguments + AREXPORT bool daemonize(void); + /// Daemonizes always + AREXPORT bool forceDaemonize(void); + /// Logs the options + AREXPORT void logOptions(void) const; + /// Returns if we're daemonized or not + bool isDaemonized(void) { return myIsDaemonized; } +protected: + ArArgumentParser myParser; + bool myIsDaemonized; + bool myCloseStdErrAndStdOut; + ArConstFunctorC myLogOptionsCB; +}; +#endif // !win32 && !swig + + + +/// Contains enumeration of four user-oriented priority levels (used primarily by ArConfig) +class ArPriority +{ +public: + enum Priority + { + IMPORTANT, ///< Basic things that should be modified to suit + BASIC = IMPORTANT, ///< Basic things that should be modified to suit + FIRST_PRIORITY = IMPORTANT, + + NORMAL, ///< Intermediate things that users may want to modify + INTERMEDIATE = NORMAL, ///< Intermediate things that users may want to modify + + DETAILED, ///< Advanced items that probably shouldn't be modified + TRIVIAL = DETAILED, ///< Advanced items (alias for historic reasons) + ADVANCED = DETAILED, ///< Advanced items that probably shouldn't be modified + + EXPERT, ///< Items that should be modified only by expert users or developers + FACTORY, ///< Items that should be modified at the factory, often apply to a robot model + + CALIBRATION, ///< Items that apply to a particular hardware instance + + LAST_PRIORITY = CALIBRATION ///< Last value in the enumeration + }; + + enum { + PRIORITY_COUNT = LAST_PRIORITY + 1 ///< Number of priority values + }; + + /// Returns the displayable text string for the given priority + AREXPORT static const char * getPriorityName(Priority priority); + + /// Returns the priority value that corresponds to the given displayable text string + AREXPORT static Priority getPriorityFromName(const char *text); + +protected: + + /// Whether the map of priorities to display text has been initialized + static bool ourStringsInited; + /// Map of priorities to displayable text + static std::map ourPriorityNames; + /// Map of displayable text to priorities + static std::map ourNameToPriorityMap; + + /// Display text used when a priority's displayable text has not been defined + static std::string ourUnknownPriorityName; +}; + +/// holds information about ArStringInfo component strings (it's a helper class for other things) +/** + This class holds information for about different strings that are available + **/ +class ArStringInfoHolder +{ +public: + /// Constructor + ArStringInfoHolder(const char *name, ArTypes::UByte2 maxLength, + ArFunctor2 *functor) + { myName = name; myMaxLength = maxLength; myFunctor = functor; } + /// Destructor + virtual ~ArStringInfoHolder() {} + /// Gets the name of this piece of info + const char *getName(void) { return myName.c_str(); } + /// Gets the maximum length of this piece of info + ArTypes::UByte2 getMaxLength(void) { return myMaxLength; } + /// Gets the function that will fill in this piece of info + ArFunctor2 *getFunctor(void) { return myFunctor; } +protected: + std::string myName; + ArTypes::UByte2 myMaxLength; + ArFunctor2 *myFunctor; +}; + +/// This class just holds some helper functions for the ArStringInfoHolder +class ArStringInfoHolderFunctions +{ +public: + static void intWrapper(char * buffer, ArTypes::UByte2 bufferLen, + ArRetFunctor *functor, const char *format) + { snprintf(buffer, bufferLen - 1, format, functor->invokeR()); + buffer[bufferLen-1] = '\0'; } + static void doubleWrapper(char * buffer, ArTypes::UByte2 bufferLen, + ArRetFunctor *functor, const char *format) + { snprintf(buffer, bufferLen - 1, format, functor->invokeR()); + buffer[bufferLen-1] = '\0'; } + static void boolWrapper(char * buffer, ArTypes::UByte2 bufferLen, + ArRetFunctor *functor, const char *format) + { snprintf(buffer, bufferLen - 1, format, + ArUtil::convertBool(functor->invokeR())); + buffer[bufferLen-1] = '\0'; } + static void stringWrapper(char * buffer, ArTypes::UByte2 bufferLen, + ArRetFunctor *functor, + const char *format) + { snprintf(buffer, bufferLen - 1, format, functor->invokeR()); + buffer[bufferLen-1] = '\0'; } + static void unsignedLongWrapper(char * buffer, ArTypes::UByte2 bufferLen, + ArRetFunctor *functor, const char *format) + { snprintf(buffer, bufferLen - 1, format, functor->invokeR()); + buffer[bufferLen-1] = '\0'; } + static void longWrapper(char * buffer, ArTypes::UByte2 bufferLen, + ArRetFunctor *functor, const char *format) + { snprintf(buffer, bufferLen - 1, format, functor->invokeR()); + buffer[bufferLen-1] = '\0'; } +}; + +/** A class to hold a list of callbacks to call + GenericFunctor must be a pointer to an ArFunctor or subclass. + e.g. declare like this: + @code + ArGenericCallbackList< ArFunctorC * > callbackList; + @endcode + then invoke it like this: + @code + callbackList.invoke(); + @endcode + To pass an argument to the callbacks, use ArCallbackList1 instead. + @ingroup UtilityClasses +**/ + +template +class ArGenericCallbackList +{ +public: + /// Constructor + ArGenericCallbackList(const char *name = "", + ArLog::LogLevel logLevel = ArLog::Verbose, + bool singleShot = false) + { + myName = name; + mySingleShot = singleShot; + setLogLevel(logLevel); + std::string mutexName; + mutexName = "ArGenericCallbackList::"; + mutexName += name; + mutexName += "::myDataMutex"; + myDataMutex.setLogName(mutexName.c_str()); + myLogging = true; + } + /// Destructor + virtual ~ArGenericCallbackList() + { + } + /// Adds a callback + void addCallback(GenericFunctor functor, int position = 50) + { + myDataMutex.lock(); + myList.insert( + std::pair(-position, + functor)); + myDataMutex.unlock(); + } + /// Removes a callback + void remCallback(GenericFunctor functor) + { + myDataMutex.lock(); + typename std::multimap::iterator it; + + for (it = myList.begin(); it != myList.end(); it++) + { + if ((*it).second == functor) + { + myList.erase(it); + myDataMutex.unlock(); + remCallback(functor); + return; + } + } + myDataMutex.unlock(); + } + /// Sets the name + void setName(const char *name) + { + myDataMutex.lock(); + myName = name; + myDataMutex.unlock(); + } +#ifndef SWIG + /// Sets the name with formatting + /** @swigomit use setName() */ + void setNameVar(const char *name, ...) + { + char arg[2048]; + va_list ptr; + va_start(ptr, name); + vsnprintf(arg, sizeof(arg), name, ptr); + arg[sizeof(arg) - 1] = '\0'; + va_end(ptr); + return setName(arg); + } +#endif + /// Sets the log level + void setLogLevel(ArLog::LogLevel logLevel) + { + myDataMutex.lock(); + myLogLevel = logLevel; + myDataMutex.unlock(); + } + /// Sets if its single shot + void setSingleShot(bool singleShot) + { + myDataMutex.lock(); + mySingleShot = singleShot; + myDataMutex.unlock(); + } + /// Enable or disable logging when invoking the list. Logging is enabled by default at the log level given in the constructor. + void setLogging(bool on) { + myLogging = on; + } +protected: + ArMutex myDataMutex; + ArLog::LogLevel myLogLevel; + std::string myName; + std::multimap myList; + bool mySingleShot; + bool myLogging; +}; + +/** A class to hold a list of callbacks to call sequentially. + @ingroup UtilityClasses +*/ +class ArCallbackList : public ArGenericCallbackList +{ +public: + /// Constructor + ArCallbackList(const char *name = "", + ArLog::LogLevel logLevel = ArLog::Verbose, + bool singleShot = false) : + ArGenericCallbackList(name, logLevel, singleShot) + { + } + /// Destructor + virtual ~ArCallbackList() + { + } + /// Calls the callback list + void invoke(void) + { + myDataMutex.lock(); + + std::multimap::iterator it; + ArFunctor *functor; + + if(myLogging) + ArLog::log(myLogLevel, "%s: Starting calls", myName.c_str()); + + for (it = myList.begin(); + it != myList.end(); + it++) + { + functor = (*it).second; + if (functor == NULL) + continue; + + if(myLogging) + { + if (functor->getName() != NULL && functor->getName()[0] != '\0') + ArLog::log(myLogLevel, "%s: Calling functor '%s' at %d", + myName.c_str(), functor->getName(), -(*it).first); + else + ArLog::log(myLogLevel, "%s: Calling unnamed functor at %d", + myName.c_str(), -(*it).first); + } + functor->invoke(); + } + + if(myLogging) + ArLog::log(myLogLevel, "%s: Ended calls", myName.c_str()); + + if (mySingleShot) + { + if(myLogging) + ArLog::log(myLogLevel, "%s: Clearing callbacks", myName.c_str()); + myList.clear(); + } + myDataMutex.unlock(); + } +protected: +}; + +/** A class to hold a list of callbacks to call with an argument of type P1 + The functors added to the list must be pointers to a subclass of ArFunctor1. + Declare like this: + @code + ArCallbackList1 callbackList; + @endcode + then add a functor like this: + @code + ArFunctor1C func; + ... + callbackList.addCallback(&func); + @endcode + then invoke it like this: + @code + callbackList.invoke(23); + @endcode + @ingroup UtilityClasses +**/ +template +class ArCallbackList1 : public ArGenericCallbackList *> +{ +public: + /// Constructor + ArCallbackList1(const char *name = "", + ArLog::LogLevel logLevel = ArLog::Verbose, + bool singleShot = false) : + ArGenericCallbackList *>(name, logLevel, singleShot) + { + } + /// Destructor + virtual ~ArCallbackList1() + { + } + /// Calls the callback list + void invoke(P1 p1) + { + ArGenericCallbackList *>::myDataMutex.lock(); + + typename std::multimap *>::iterator it; + ArFunctor1 *functor; + + if(ArGenericCallbackList *>::myLogging) + ArLog::log( + ArGenericCallbackList *>::myLogLevel, + "%s: Starting calls1", + ArGenericCallbackList *>::myName.c_str()); + + for (it = ArGenericCallbackList *>::myList.begin(); + it != ArGenericCallbackList *>::myList.end(); + it++) + { + functor = (*it).second; + if (functor == NULL) + continue; + + if(ArGenericCallbackList *>::myLogging) + { + if (functor->getName() != NULL && functor->getName()[0] != '\0') + ArLog::log(ArGenericCallbackList *>::myLogLevel, + "%s: Calling functor '%s' at %d", + ArGenericCallbackList *>::myName.c_str(), + functor->getName(), -(*it).first); + else + ArLog::log(ArGenericCallbackList *>::myLogLevel, + "%s: Calling unnamed functor at %d", + ArGenericCallbackList *>::myName.c_str(), + -(*it).first); + } + functor->invoke(p1); + } + + if(ArGenericCallbackList *>::myLogging) + ArLog::log(ArGenericCallbackList *>::myLogLevel, "%s: Ended calls", ArGenericCallbackList *>::myName.c_str()); + + if (ArGenericCallbackList *>::mySingleShot) + { + if(ArGenericCallbackList *>::myLogging) + ArLog::log(ArGenericCallbackList *>::myLogLevel, + "%s: Clearing callbacks", + ArGenericCallbackList *>::myName.c_str()); + ArGenericCallbackList *>::myList.clear(); + } + ArGenericCallbackList *>::myDataMutex.unlock(); + } +protected: +}; + +#ifndef ARINTERFACE +#ifndef SWIG +/// @internal +class ArLaserCreatorHelper +{ +public: + /// Creates an ArLMS2xx + static ArLaser *createLMS2xx(int laserNumber, const char *logPrefix); + /// Gets functor for creating an ArLMS2xx + static ArRetFunctor2 *getCreateLMS2xxCB(void); + /// Creates an ArUrg + static ArLaser *createUrg(int laserNumber, const char *logPrefix); + /// Gets functor for creating an ArUrg + static ArRetFunctor2 *getCreateUrgCB(void); + /// Creates an ArLMS1XX + static ArLaser *createLMS1XX(int laserNumber, const char *logPrefix); + /// Gets functor for creating an ArLMS1XX + static ArRetFunctor2 *getCreateLMS1XXCB(void); + /// Creates an ArUrg using SCIP 2.0 + static ArLaser *createUrg_2_0(int laserNumber, const char *logPrefix); + /// Gets functor for creating an ArUrg + static ArRetFunctor2 *getCreateUrg_2_0CB(void); + /// Creates an ArS3Series + static ArLaser *createS3Series(int laserNumber, const char *logPrefix); + /// Gets functor for creating an ArS3Series + static ArRetFunctor2 *getCreateS3SeriesCB(void); + /// Creates an ArLMS5XX + static ArLaser *createLMS5XX(int laserNumber, const char *logPrefix); + /// Gets functor for creating an ArLMS5XX + static ArRetFunctor2 *getCreateLMS5XXCB(void); + /// Creates an ArTiM3XX + static ArLaser *createTiM3XX(int laserNumber, const char *logPrefix); + /// Gets functor for creating an ArTiM3XX + static ArRetFunctor2 *getCreateTiM3XXCB(void); + /// Creates an ArSZSeries + static ArLaser *createSZSeries(int laserNumber, const char *logPrefix); + /// Gets functor for creating an ArSZSeries + static ArRetFunctor2 *getCreateSZSeriesCB(void); + +protected: + static ArGlobalRetFunctor2 ourLMS2xxCB; + static ArGlobalRetFunctor2 ourUrgCB; + static ArGlobalRetFunctor2 ourLMS1XXCB; + static ArGlobalRetFunctor2 ourUrg_2_0CB; + static ArGlobalRetFunctor2 ourS3SeriesCB; + static ArGlobalRetFunctor2 ourLMS5XXCB; + static ArGlobalRetFunctor2 ourTiM3XXCB; + static ArGlobalRetFunctor2 ourSZSeriesCB; +}; + +/// @internal +class ArBatteryMTXCreatorHelper +{ +public: + /// Creates an ArBatteryMTX + static ArBatteryMTX *createBatteryMTX(int batteryNumber, const char *logPrefix); + /// Gets functor for creating an ArBatteryMTX + static ArRetFunctor2 *getCreateBatteryMTXCB(void); + +protected: + static ArGlobalRetFunctor2 ourBatteryMTXCB; +}; + +/// @internal +class ArLCDMTXCreatorHelper +{ +public: + /// Creates an ArLCDMTX + static ArLCDMTX *createLCDMTX(int lcdNumber, const char *logPrefix); + /// Gets functor for creating an ArLCDMTX + static ArRetFunctor2 *getCreateLCDMTXCB(void); + +protected: + static ArGlobalRetFunctor2 ourLCDMTXCB; +}; + +/// @internal +class ArSonarMTXCreatorHelper +{ +public: + /// Creates an ArSonarMTX + static ArSonarMTX *createSonarMTX(int sonarNumber, const char *logPrefix); + /// Gets functor for creating an ArSonarMTX + static ArRetFunctor2 *getCreateSonarMTXCB(void); + +protected: + static ArGlobalRetFunctor2 ourSonarMTXCB; +}; + +#endif // SWIG +#endif // ARINTERFACE + +#ifndef SWIG +/// @internal +class ArDeviceConnectionCreatorHelper +{ +public: + /// Creates an ArSerialConnection + static ArDeviceConnection *createSerialConnection( + const char *port, const char *defaultInfo, const char *logPrefix); + /// Gets functor for creating an ArSerialConnection + static ArRetFunctor3 *getCreateSerialCB(void); + + /// Creates an ArTcpConnection + static ArDeviceConnection *createTcpConnection( + const char *port, const char *defaultInfo, const char *logPrefix); + /// Gets functor for creating an ArTcpConnection + static ArRetFunctor3 *getCreateTcpCB(void); + + /// Creates an ArSerialConnection for RS422 + static ArDeviceConnection *createSerial422Connection( + const char *port, const char *defaultInfo, const char *logPrefix); + /// Gets functor for creating an ArSerialConnection + static ArRetFunctor3 *getCreateSerial422CB(void); + + /// Sets the success log level + static void setSuccessLogLevel(ArLog::LogLevel successLogLevel); + /// Sets the success log level + static ArLog::LogLevel setSuccessLogLevel(void); +protected: + /// Internal Create ArSerialConnection + static ArDeviceConnection *internalCreateSerialConnection( + const char *port, const char *defaultInfo, const char *logPrefix, bool is422); + static ArGlobalRetFunctor3 ourSerialCB; + static ArGlobalRetFunctor3 ourTcpCB; + static ArGlobalRetFunctor3 ourSerial422CB; + static ArLog::LogLevel ourSuccessLogLevel; +}; +#endif // SWIG + +/// Class for finding robot bounds from the basic measurements +class ArPoseUtil +{ +public: + static std::list findCornersFromRobotBounds( + double radius, double widthLeft, double widthRight, + double lengthFront, double lengthRear, bool fastButUnsafe); + static std::list breakUpDistanceEvenly(ArPose start, ArPose end, + int resolution); +}; + +#endif // ARIAUTIL_H + + diff --git a/Legacy/Aria/include/md5.h b/Legacy/Aria/include/md5.h new file mode 100644 index 0000000..3ee2a8c --- /dev/null +++ b/Legacy/Aria/include/md5.h @@ -0,0 +1,129 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +/* + This is the software we use for doing the md5 checksums, its from + http://sourceforge.net/project/showfiles.php?group_id=42360 +*/ + +/* + Copyright (C) 1999, 2002 Aladdin Enterprises. All rights reserved. + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + L. Peter Deutsch + ghost@aladdin.com + + */ +/* + Independent implementation of MD5 (RFC 1321). + + This code implements the MD5 Algorithm defined in RFC 1321, whose + text is available at + http://www.ietf.org/rfc/rfc1321.txt + The code is derived from the text of the RFC, including the test suite + (section A.5) but excluding the rest of Appendix A. It does not include + any code or documentation that is identified in the RFC as being + copyrighted. + + The original and principal author of md5.h is L. Peter Deutsch + . Other authors are noted in the change history + that follows (in reverse chronological order): + + 2002-04-13 lpd Removed support for non-ANSI compilers; removed + references to Ghostscript; clarified derivation from RFC 1321; + now handles byte order either statically or dynamically. + 1999-11-04 lpd Edited comments slightly for automatic TOC extraction. + 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5); + added conditionalization for C++ compilation from Martin + Purschke . + 1999-05-03 lpd Original version. + */ + +#ifndef md5_INCLUDED +# define md5_INCLUDED + +/* + * This package supports both compile-time and run-time determination of CPU + * byte order. If ARCH_IS_BIG_ENDIAN is defined as 0, the code will be + * compiled to run only on little-endian CPUs; if ARCH_IS_BIG_ENDIAN is + * defined as non-zero, the code will be compiled to run only on big-endian + * CPUs; if ARCH_IS_BIG_ENDIAN is not defined, the code will be compiled to + * run on either big- or little-endian CPUs, but will run slightly less + * efficiently on either one than if ARCH_IS_BIG_ENDIAN is defined. + */ + +typedef unsigned char md5_byte_t; /* 8-bit byte */ +typedef unsigned int md5_word_t; /* 32-bit word */ + +/* Define the state of the MD5 Algorithm. */ +typedef struct md5_state_s { + md5_word_t count[2]; /* message length in bits, lsw first */ + md5_word_t abcd[4]; /* digest buffer */ + md5_byte_t buf[64]; /* accumulate block */ +} md5_state_t; + +// MPL (ActivMedia) taking out the extern since its only being used in c++ +/* +#ifdef __cplusplus +extern "C" +{ +#endif +*/ + +// RH (ActivMedia/MobileRobots) Added "AREXPORT" symbol to all public functions. On Windows, this must be defined +// to either import or export the symbols to/from DLLs. On other platforms, it should be defined to be nothing. + +/* Initialize the algorithm. */ +AREXPORT void md5_init(md5_state_t *pms); + +/* Append a string to the message. */ +AREXPORT void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes); + +/* Finish the message and return the digest. */ +AREXPORT void md5_finish(md5_state_t *pms, md5_byte_t digest[16]); + +/// MPL (ActivMedia) taking out the extern since its only being used in c++ +/* +#ifdef __cplusplus +} // end extern "C" +#endif +*/ + +#endif /* md5_INCLUDED */ diff --git a/Legacy/Aria/include/wrapper.i b/Legacy/Aria/include/wrapper.i new file mode 100644 index 0000000..757d0a9 --- /dev/null +++ b/Legacy/Aria/include/wrapper.i @@ -0,0 +1,742 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ + + /* SWIG 1.3 Wrapper Interface Definition for Aria */ + +#ifdef SWIGPYTHON +/*#warning Defining ARIA wrapper interface for Python*/ + +/* We need the module declared as "AriaPy" here so that other modules + (like ArNetworking or ARNL) that use this wrapper will know what + the resulting Python module and wrapper library are called. +*/ +%module(directors="1", docstring="Python wrapper library for Aria") AriaPy + +#else +# ifdef SWIGJAVA +/*# warning Defining ARIA wrapper interface for Java*/ + +%module(directors="1", docstring="Java wrapper library for Aria") AriaJava + +# else +# warning Defining ARIA wrapper interface for something other that Java or Python. This might be an error. + +%module(directors="1", docstring="Wrapper library for Aria") Aria + +# endif +#endif + +#ifdef SWIGIMPORTED +#warning Imported ARIA wrapper +#endif + +%feature("autodoc", "1"); + + + +%{ +#include "Aria.h" +#include "ArGPSConnector.h" +#include "ArSystemStatus.h" +#include "ArMD5Calculator.h" +/*#include "SwigTestClass.h"*/ +#include "wrapper_ExtraClasses.h" +#include "wrapper_Functors.h" + +#include +%} + +/* Filter out warnings about setting const char* members in these classes-- + they are all static so the warning about leaking memory doesn't really apply. */ +%warnfilter(451) ArUtil; +%warnfilter(451) ArCameraCommands; +%warnfilter(451) ArMapInfoInterface; +%warnfilter(451) ArMapInterface; + + + + +/* Enable director classes (subclasses) for ArAction. + Other classes in Aria that can be subclasses, but very rarely are, + include ArResolver, ArBasePacket, ArDeviceConnection, ArRangeDevice, + ArActionGroup, ArMode; maybe others. + In Java it needs to be enabled for various ArFunctor subclasses too, + see later. + You could add %feature("director") directives for those classes + and regenerate the wrapper libraries if you want to use them. + (They are omitted since making a class a director adds lots + of code to the wrapper library.) + ArASyncTask is also often subclassed, but threading in Python is + kind of hard to get working right, at least as of Python 2.3, + especially going through Swig to do it, so providing ArASyncTask is + postponed. +*/ +%feature("director") ArAction; + +/* Supply an alternate setRobot() to avoid infinite recursion + between the Python/Java subclass and Swig's director method. +*/ +%extend ArAction { + void setActionRobot(ArRobot* robot) + { + self->ArAction::setRobot(robot); + } +} + + +/* ArMap needs directors, and to be explicitly not abstract, for constructors to be made correctly */ + +#ifdef SWIGJAVA +%feature("director") ArMap; +#endif + +%feature("notabstract") ArMap; +%feature("notabstract") ArMapInfo; + + + +/** Functors: **/ + +%{ +#include "wrapper_Functors.h" +%} + + +/* In python, use typemaps to convert function objects to ArFunctor subclasses */ + +#ifdef SWIGPYTHON + +%typemap(in) ArFunctor* { + $1 = new ArPyFunctor($input); /* XXX Memory leak. How to free? */ +} + +%typecheck(SWIG_TYPECHECK_POINTER) ArFunctor* { + $1 = PyCallable_Check($input); +} + + +%typemap(in) ArRetFunctor* { + $1 = new ArPyRetFunctor_Bool($input); /* XXX Memory leak. How to free it? */ +} + + +%typecheck(SWIG_TYPECHECK_POINTER) ArRetFunctor* { + $1 = PyCallable_Check($input); +} + +#endif /* ifdef SWIGPYTHON */ + + + + +/* In Java, enable directors so you can subclass ArFunctors. */ + +#ifdef SWIGJAVA + + +%feature("director") ArFunctor; +%feature("director") ArRetFunctor; +%feature("director") ArRetFunctor; +%feature("director") ArRetFunctor1; +%feature("director") ArFunctor1; +%feature("director") ArRetFunctor1; + +#endif + + + + +/* Rename or ignore things that can cause problems for SWIG: */ + +%rename (removePendingItemsWithType) ArSoundsQueue::removePendingItems(const %char*, ItemType); +%rename (removePendingItemsByPriority) ArSoundsQueue::removePendingItems(int); +%rename (removePendingItemsByPriorityWithType) ArSoundsQueue::removePendingItems(int, ItemType); +%rename (removePendingItemsByType) ArSoundsQueue::removePendingItems(ItemType); +%rename (nextItemByType) ArSoundsQueue::nextItem(ItemType); +%rename (nextItemByPriority) ArSoundsQueue::nextItem(int); +%rename (nextItemByTypeAndPriority) ArSoundsQueue::nextItem(ItemType, int); +%ignore ArActionTriangleDriveTo::getData; +%rename (addPreMapChangedCBPos) ArMapInterface::addPreMapChangedCB(ArFunctor*, ArListPos::Pos); +%rename (addPreMapChangedCBPos) ArMap::addPreMapChangedCB(ArFunctor*, ArListPos::Pos); +%rename (addMapChangedCBPos) ArMapInterface::addMapChangedCB(ArFunctor*, ArListPos::Pos); +%rename (addMapChangedCBPos) ArMap::addMapChangedCB(ArFunctor*, ArListPos::Pos); + +/* arconfig cannot target pointers in the wrapped languages: */ +%ignore ArConfigArg::ArConfigArg(const char*, int*, const char*, int, int); +%ignore ArConfigArg::ArConfigArg(const char*, short*, const char*, int, int); +%ignore ArConfigArg::ArConfigArg(const char*, unsigned short*, const char*, int, int); +%ignore ArConfigArg::ArConfigArg(const char*, unsigned char*, const char*, int, int); +%ignore ArConfigArg::ArConfigArg(const char*, double*, const char*, double, double); +%ignore ArConfigArg::ArConfigArg(const char*, bool*, const char*); + + +/* Rename reserved words in Python: */ +#ifdef SWIGPYTHON +%rename(NoLog) ArLog::None; +%rename(printQueue) ArRingQueue::print; +%rename(printPoint) Ar3DPoint::print; +#endif + +/* In Java and Python, you can easily concatenate strings and primitive types, + so we can just refer to logPlain() as log(), and ignore the varargs log(). */ +%ignore ArLog::log; +%rename (log) ArLog::logPlain; + +/* Rename names of some built in methods in java.lang.Object */ +#ifdef SWIGJAVA +%rename(waitFor) ArCondition::wait; +%rename(cloneMap) ArMapInterface::clone; +#endif + +/* cant wrap operators (should provide replacement methods though, TODO) */ +%ignore operator=; +%ignore operator==; +%ignore operator<; +%ignore operator>; +%ignore operator(); +%ignore operator+; +%ignore operator-; +%ignore operator*; +%ignore operator!=; +%ignore operator+=; +%ignore operator-=; + +/* Typemaps to make ARIA classes more accessible and work better in various + * target languages: + */ + +%include "typemaps.i" + +%apply int *OUTPUT {int *x, int *y, int *z}; +%apply double *OUTPUT {double *x, double *y, double *th}; +%apply double *OUTPUT {double *x, double *y, double *z}; + + +/* In python, use a standard list of strings for argc and argv: */ + +#ifdef SWIGPYTHON + +// TODO: ArArgumentParser can modify the argv list, these changes +// need to be reflected in the Python or Java list after the C++ function +// returns (if possible). Not sure how to do that yet. + +%typemap(in) (int *argc, char **argv) { + # (begin %typemap(in) for (int *argc, char **argv) + int i; + if (!PyList_Check($input)) { + PyErr_SetString(PyExc_ValueError, "Expecting a list"); + return NULL; + } + int tmpArgc = PyList_Size($input); + tmpArgc = PyList_Size($input); + $2 = (char **) malloc((tmpArgc+1)*sizeof(char *)); + for (i = 0; i < tmpArgc; i++) { + PyObject *s = PyList_GetItem($input,i); + if (!PyString_Check(s)) { + free($2); + PyErr_SetString(PyExc_ValueError, "Arguments must be strings"); + return NULL; + } + $2[i] = PyString_AsString(s); + } + $2[i] = 0; + /* Allocate a new int to hold the size, since some classes retain the pointer + and try to use it after this wrapped function returns. + Note this is not deallocated, in general classes using this typemap are + defacto singletons that live for the life of the program, so it's not a problem, + but if this typemap ever gets used for other kinds of classes is may come up. */ + int *newArgc = (int*) malloc(sizeof(int)); + *newArgc = tmpArgc; + $1 = newArgc; + # (end %typemap(in) for (int *argc, char **argv) +} + +%typecheck(SWIG_TYPECHECK_POINTER) (int *argc, char **argv) { + $1 = PyList_Check($input); +} + +#endif /*SIWGPYTHON*/ + + + +/* Modify Java wrapper to make it easier to access functions with pointer and + array arguments: + +*/ + +#ifdef SWIGJAVA + + +/* Use a String[] for argc and argv (e.g. the argv[] parameter in main()) */ + +%typemap(in) (int *argc, char **argv) (jint size){ + /* (begin %typemap(in) for (int *argc, char **argv) */ + size = jenv->GetArrayLength((jarray)$input); + int tmpArgc = size; + int i; + $2 = (char**)malloc( (size+1) * sizeof(char*) ); + for(i = 0; i < size; i++) { + jstring js = (jstring) jenv->GetObjectArrayElement((jobjectArray)$input, i); + const char *cs = jenv->GetStringUTFChars(js, 0); + $2[i] = (char*)malloc(strlen(cs)+1 * sizeof(const char)); + strcpy($2[i], cs); + jenv->ReleaseStringUTFChars(js, cs); + jenv->DeleteLocalRef(js); + } + $2[i] = 0; + int *newArgc = (int*) malloc(sizeof(int)); + *newArgc = tmpArgc; + $1 = newArgc; + /* (end %typemap(in) for (int *argc, char **argv) */ +} + + +/* XXX TODO? or will the jni and jtype typemaps below deal with it? : +%typecheck(java,SWIG_TYPECHECK_POINTER) (int *, char **) { + // TODO +} +*/ + + +%typemap(jni) (int *argc, char **argv) "jobjectArray" +%typemap(jtype) (int *argc, char **argv) "java.lang.String[]" +%typemap(jstype) (int *argc, char **argv) "java.lang.String[]" +%typemap(javain) (int *argc, char **argv) "$javainput" +%typemap(javaout) (int *argc, char **argv) { return $jnicall; } + + +/* In Java, we alsoneed to override how SWIG defines some methods in the wrappers, + * to be public not protected (the defaut javabody typemap is defined in + * java.swg) so that other packages such as ArNetworking and ARNL can access them: + */ +%typemap(javabody) SWIGTYPE %{ + /* (begin code from javabody typemap) */ + + private long swigCPtr; + protected boolean swigCMemOwn; + + /* for internal use by swig only */ + public $javaclassname(long cPtr, boolean cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = cPtr; + } + + /* for internal use by swig only */ + public static long getCPtr($javaclassname obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + /* (end code from javabody typemap) */ +%} + +%typemap(javabody_derived) SWIGTYPE %{ + /* (begin code from javabody_derived typemap) */ + + private long swigCPtr; + + /* for internal use by swig only */ + public $javaclassname(long cPtr, boolean cMemoryOwn) { + super($imclassname.SWIG$javaclassnameUpcast(cPtr), cMemoryOwn); + swigCPtr = cPtr; + } + + /* for internal use by swig only */ + public static long getCPtr($javaclassname obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + /* (end code from javabody_derived typemap) */ +%} + + +%typemap(javabody) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [], SWIGTYPE (CLASS::*) %{ + /* (begin code from javabody typemap for pointers, references, and arrays) */ + + private long swigCPtr; + + /* for internal use by swig only */ + public $javaclassname(long cPtr, boolean bFutureUse) { + swigCPtr = cPtr; + } + + protected $javaclassname() { + swigCPtr = 0; + } + + /* for internal use by swig only */ + public static long getCPtr($javaclassname obj) { + return (obj == null) ? 0 : obj.swigCPtr; + } + + /* (end code from javabody typemap for pointers, references, and arrays) */ +%} + + + +#endif /* SWIGJAVA */ + + + +#ifndef SWIGPYTHON +/* These are special additional structs used by methods added to + * ArJoyHandler via %extend below */ +%{ +struct ArJoyVec3f { double x, y, z; }; +struct ArJoyVec3i { int x, y, z; }; +%} +#endif + + +/* Give names to some standard library container template types. + * In Java, you must use the special template instance names defined + * here to subclass from, e.g. "class MyPacketHandler extends ArRetFunctor1_Bool_ArRobotPacketP" + */ + + +%include "std_vector.i" +%template(ArPoseWithTimeVector) std::vector; +%template(ArSensorReadingVector) std::vector; +%template(DoubleVector) std::vector; + +#include +/*#ifndef SWIGJAVA*/ /* doesn't have std_list.i */ +#ifdef SWIGJAVA +%include "wrapper_std_list_java.i" +#else +%include "std_list.i" +#endif + +%template(ArMapObjectPtrList) std::list; +%template(ArFunctorPtrList) std::list; +%template(ArPoseList) std::list; +%template(ArPosePtrList) std::list; +%template(ArPoseWithTimeList) std::list; +%template(ArPoseWithTimePtrList) std::list; +%template(ArRangeDevicePtrList) std::list; +%template(ArArgumentBuilderPtrList) std::list; +%template(ArLineSegmentList) std::list; +%template(ArLineSegmentPtrList) std::list; +/*#endif*/ + +#ifndef SWIGJAVA /* doesn't have set */ +%include "std_set.i" +%template(IntSet) std::set; +#endif + +%include "std_map.i" +%template(IntArPoseMap) std::map; + + +%include "std_string.i" + + /* Bring in header files with classes to wrap. */ + +/* note dont include ArVersalogicIO.h or ArRobotTypes.h */ + +/* Base classes first. */ +%include "ariaTypedefs.h" +%include "ariaUtil.h" +%include "md5.h" +%include "ArBasePacket.h" +%include "ArPTZ.h" +%include "ArRangeDevice.h" +%include "ArRangeDeviceThreaded.h" +%include "ArLaser.h" +%include "ArResolver.h" +%include "ArThread.h" +%include "ArFunctor.h" + +/* Give names to some instantiations of ArFunctor template classes (for use as + * .h files that use these instantiations are loaded). */ +%template(ArRetFunctor_VoidP) ArRetFunctor; +%template(ArRetFunctor_Bool) ArRetFunctor; +%template(ArFunctor1_CString) ArFunctor1; +%template(ArFunctor1_Int) ArFunctor1; +%template(ArFunctor1_ArRobotPacketP) ArFunctor1; +%template(ArRetFunctor_Int) ArRetFunctor; +%template(ArRetFunctor_Double) ArRetFunctor; +%template(ArRetFunctor_UnsignedInt) ArRetFunctor; +%template(ArRetFunctor1_Double_ArPoseWithTime) ArRetFunctor1; +%template(ArRetFunctor1_Bool_ArRobotPacketP) ArRetFunctor1; +%template(ArRetFunctor1_Bool_ArgumentBuilder) ArRetFunctor1; +%template(ArRetFunctor1_Bool_ArgumentBuilderP) ArRetFunctor1; +%template(ArRetFunctor1_VoidP_VoidP) ArRetFunctor1; + +%include "ArACTS.h" +%include "ArAMPTU.h" +%include "ArASyncTask.h" +%include "ArAction.h" +%include "ArActionAvoidFront.h" +%include "ArActionAvoidSide.h" +%include "ArActionBumpers.h" +%include "ArActionColorFollow.h" +%include "ArActionConstantVelocity.h" +%include "ArActionDeceleratingLimiter.h" +%include "ArActionDesired.h" +%include "ArActionDriveDistance.h" +%include "ArActionGoto.h" +%include "ArActionGotoStraight.h" +%include "ArActionGroup.h" +%include "ArActionGroups.h" +%include "ArActionIRs.h" +%include "ArActionInput.h" +%include "ArActionJoydrive.h" +%include "ArActionKeydrive.h" +%include "ArActionLimiterBackwards.h" +%include "ArActionLimiterForwards.h" +%include "ArActionLimiterTableSensor.h" +%include "ArActionMovementParameters.h" +%include "ArActionRatioInput.h" +%include "ArActionRobotJoydrive.h" +%include "ArActionStallRecover.h" +%include "ArActionStop.h" +%include "ArActionTriangleDriveTo.h" +%include "ArActionTurn.h" +%include "ArAnalogGyro.h" +%include "ArArg.h" +%include "ArArgumentBuilder.h" +%include "ArArgumentParser.h" +%include "ArBumpers.h" +%include "ArCameraCollection.h" +%include "ArCameraCommands.h" +%include "ArCommands.h" +%include "ArCondition.h" +%include "ArConfig.h" +%include "ArConfigArg.h" +%include "ArConfigGroup.h" +%include "ArDataLogger.h" +%include "ArDPPTU.h" +%include "ArDeviceConnection.h" +%include "ArDrawingData.h" +%include "ArFileParser.h" +%include "ArForbiddenRangeDevice.h" +%include "ArFunctor.h" +%include "ArFunctorASyncTask.h" +%include "ArGPS.h" +%include "ArGPSConnector.h" +%include "ArGPSCoords.h" +%include "ArGripper.h" +%include "ArIRs.h" +%include "ArInterpolation.h" +%include "ArIrrfDevice.h" +%include "ArJoyHandler.h" +%include "ArKeyHandler.h" +%include "ArLaserConnector.h" +%include "ArLaserFilter.h" +%include "ArLaserLogger.h" +%include "ArLaserReflectorDevice.h" +%include "ArLineFinder.h" +%include "ArLog.h" +%include "ArLogFileConnection.h" +%include "ArMD5Calculator.h" +%include "ArMapInterface.h" +%include "ArMap.h" +%include "ArMapComponents.h" +%include "ArMapObject.h" +%include "ArMapUtils.h" +%include "ArMode.h" +%include "ArModes.h" +%include "ArModule.h" +%include "ArModuleLoader.h" +%include "ArMutex.h" +%include "ArNMEAParser.h" +%include "ArNetServer.h" +%include "ArNovatelGPS.h" +%include "ArP2Arm.h" +%include "ArPriorityResolver.h" +%include "ArRangeBuffer.h" +%include "ArRatioInputJoydrive.h" +%include "ArRatioInputKeydrive.h" +%include "ArRatioInputRobotJoydrive.h" +%include "ArRecurrentTask.h" +%include "ArRingQueue.h" +%include "ArRobot.h" +%include "ArRobotConfig.h" +%include "ArRobotConfigPacketReader.h" +%include "ArRobotConnector.h" +%include "ArRobotJoyHandler.h" +%include "ArRobotPacket.h" +%include "ArRobotPacketReceiver.h" +%include "ArRobotPacketSender.h" +%include "ArRobotParams.h" +%include "ArRVisionPTZ.h" +%include "ArSensorReading.h" +%include "ArSerialConnection.h" +%include "ArSignalHandler.h" +%include "ArSimpleConnector.h" +%include "ArSimulatedLaser.h" +%include "ArSocket.h" +%include "ArSonarAutoDisabler.h" +%include "ArSonarDevice.h" +%include "ArSonyPTZ.h" +%include "ArSoundPlayer.h" +%include "ArSoundsQueue.h" +%include "ArSpeech.h" +%include "ArStringInfoGroup.h" +%include "ArSyncLoop.h" +%include "ArSyncTask.h" +%include "ArSystemStatus.h" +%include "ArTCM2.h" +%include "ArTCMCompassDirect.h" +%include "ArTCMCompassRobot.h" +%include "ArTaskState.h" +%include "ArTcpConnection.h" +%include "ArTransform.h" +%include "ArTrimbleGPS.h" +%include "ArUrg.h" +%include "ArVCC4.h" +#if !defined(SWIGWIN) && !defined(WIN32) +%include "ArVersalogicIO.h" +%include "ArMTXIO.h" +#endif +%include "ariaInternal.h" + +%include "wrapper_Functors.h" +%include "wrapper_ExtraClasses.h" + + + + +/* Extensions to make ARIA classes more convenient in various target languages: */ + +/* Extension to print an ArPose nicely in Python: */ +#ifdef SWIGPYTHON +%extend ArPose { + char* __str__() { + static char tmp[256]; + snprintf(tmp, 256, "(X:%.4f, Y:%.4f, T:%.4f)", self->getX(), self->getY(), self->getTh()); + return &tmp[0]; + } +} +#endif + +/* Extension that allows you to access pose components as member attributes + rather than using accessor methods. We do this by providing "dummy" member + variables, then overloading Swigs internal accessors: + */ +#ifdef SWIGPYTHON +%extend ArPose { + double x, y, th; +} +%{ + const double ArPose_x_get(ArPose* p) { + return (const double) p->getX(); + } + void ArPose_x_set(ArPose* p, double x) { + p->setX(x); + } + const double ArPose_y_get(ArPose* p) { + return (const double) p->getY(); + } + void ArPose_y_set(ArPose* p, double y) { + p->setY(y); + } + const double ArPose_th_get(ArPose* p) { + return (const double) p->getTh(); + } + void ArPose_th_set(ArPose* p, double th) { + p->setTh(th); + } +%} +#endif + + +%extend ArSocket { + std::string read(size_t len, unsigned int msWait) { + char *buf = (char*)malloc(len); + int n = self->read(buf, len, msWait); + if(n <= 0) { + free(buf); + return ""; + } + std::string s(buf, n); + free(buf); + return s; + } + + bool write(std::string s) { + return self->write( (void*)(s.c_str()), (size_t)(s.length())); + } +} + + +/* Extend the ArJoyHandler class to return structs with vector values, which is + * easier to use than return via pointer arguments. */ +#ifndef SWIGPYTHON // In Python the original functions return a nicer python tuple + +struct ArJoyVec3f { double x, y, z; }; +struct ArJoyVec3i { int x, y, z; }; + +%extend ArJoyHandler { + /** @copydoc getDoubles(double *x, double *y, double *z) + @added 2.7.3 + */ + ArJoyVec3f getDoubles() { + ArJoyVec3f r; + self->getDoubles(&r.x, &r.y, &r.z); + return r; + } + /** @copydoc getAdjusted(int *x, int *y, int *z) + @added 2.7.3 + */ + ArJoyVec3i getAdjusted() { + ArJoyVec3i r; + self->getAdjusted(&r.x, &r.y, &r.z); + return r; + } + /** @copydoc getUnfiltered(int *x, int *y, int *z) + @added 2.7.3 + */ + ArJoyVec3i getUnfiltered() { + ArJoyVec3i r; + self->getUnfiltered(&r.x, &r.y, &r.z); + return r; + } + /** @copydoc getSpeeds(int *x, int *y, int *z) + @added 2.7.3 + */ + ArJoyVec3i getSpeeds() { + ArJoyVec3i r; + self->getSpeeds(&r.x, &r.y, &r.z); + return r; + } +} + +#endif + +/* TODO: + * Make ArConfig and ArConfigSection have dictionary access operators in Python +*/ + + + + +/* TODO: typemap to check if a pointer returned by a method is NULL, and + throw an exception. (Many methods in ARIA return NULL if an object + is not found.) Maybe only do this for Java since Python has the "None" + object value? (Also falso boolean returns for status?) +*/ + diff --git a/Legacy/Aria/include/wrapper_ExtraClasses.h b/Legacy/Aria/include/wrapper_ExtraClasses.h new file mode 100644 index 0000000..f347313 --- /dev/null +++ b/Legacy/Aria/include/wrapper_ExtraClasses.h @@ -0,0 +1,74 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ + +#ifndef ARIA_wrapper_ExtraClasses_h +#define ARIA_wrapper_ExtraClasses_h + +/** @cond INCLUDE_SWIG_ONLY_CLASSES */ + +/* ArConfigArg subclasses for specific types, since for some target languages + * (Python) Swig can't differentiate booleans, integers, short integers, + * unsigned integers, etc. Furthermore, ArConfig can't change program variables + * via pointers in most languages, so you need to only use the constructors that take + * an initial value for an internally held variable instead of pointers anyway. + */ + +class ArConfigArg_Bool : public ArConfigArg +{ +public: + ArConfigArg_Bool(const char *name, bool b, const char *desc = "") : + ArConfigArg(name, b, desc) + { } +}; + +class ArConfigArg_Int : public ArConfigArg +{ +public: + ArConfigArg_Int(const char *name, int i, const char *desc = "", int min = INT_MIN, int max = INT_MAX) : + ArConfigArg(name, i, desc, min, max) + { } +}; + +class ArConfigArg_Double : public ArConfigArg +{ +public: + ArConfigArg_Double(const char *name, double d, const char *desc = "", double min = -HUGE_VAL, double max = HUGE_VAL) : + ArConfigArg(name, d, desc, min, max) + { } +}; + +class ArConfigArg_String : public ArConfigArg +{ +public: + ArConfigArg_String(const char *name, char *str, const char *desc) : + ArConfigArg(name, str, desc, 0) + { + } +}; + +/** @endcond INCLUDE_SWIG_ONLY_CLASSES */ + +#endif // wrapperExtraClasses.h diff --git a/Legacy/Aria/include/wrapper_Functors.h b/Legacy/Aria/include/wrapper_Functors.h new file mode 100644 index 0000000..73efb12 --- /dev/null +++ b/Legacy/Aria/include/wrapper_Functors.h @@ -0,0 +1,100 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ + +#ifndef ARIA_wrapper_Functors_h +#define ARIA_wrapper_Functors_h + +/* For Python, define ArFunctor subclasses to hold Python C library + * callable function objects. These are used internally by the + * wrapper library, and typemaps convert target-language function + * objects to these ArFunctor subclasses-- you only need to pass + * the function to Aria when in the C++ API you would pass a Functor. + * + * For Java, define subclasses of ArFunctor for various argument types, + * since you can't access template classes in Java. Then you can + * further subclass within Java and pass that object to Aria. + */ + +#include "ArFunctor.h" + +/* Functiors for Python: */ + +#ifdef SWIGPYTHON +class ArPyFunctor : public ArFunctor +{ +protected: + PyObject* pyFunction; +public: + ArPyFunctor(PyObject* _m) : pyFunction(_m) { + Py_INCREF(pyFunction); + } + + virtual void invoke() { + PyObject* r = PyObject_CallObject(pyFunction, NULL); + if(!r) { + fputs("** ArPyFunctor: Error calling Python function: ", stderr); + PyErr_Print(); + } + } + + virtual ~ArPyFunctor() { + Py_DECREF(pyFunction); + } + + virtual const char* getName() { + return (const char*) PyString_AsString(PyObject_Str(pyFunction)); + } +}; + + +class ArPyRetFunctor_Bool : + public ArRetFunctor, + public ArPyFunctor +{ +public: + ArPyRetFunctor_Bool(PyObject* _m) : ArRetFunctor(), ArPyFunctor(_m) { + } + + virtual bool invokeR() { + PyObject* r = PyObject_CallObject(pyFunction, NULL); + if(!r) { + fputs("** ArPyRetFunctor_Bool: Error calling Python function: ", stderr); + PyErr_Print(); + } + return(r == Py_True); + } + + virtual const char* getName() { + return (const char*) PyString_AsString(PyObject_Str(pyFunction)); + } +}; + +#endif // PYTHON + + + + +#endif // wrapperFunctors.h diff --git a/Legacy/Aria/include/wrapper_std_list_java.i b/Legacy/Aria/include/wrapper_std_list_java.i new file mode 100644 index 0000000..f555ddb --- /dev/null +++ b/Legacy/Aria/include/wrapper_std_list_java.i @@ -0,0 +1,74 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +/* ----------------------------------------------------------------------------- + * See the LICENSE file for information on copyright, usage and redistribution + * of SWIG, and the README file for authors - http://www.swig.org/release.html. + * + * std_list.i + * ----------------------------------------------------------------------------- */ + +%include + +%{ +#include +#include +%} + +namespace std { + + template class list { + public: + typedef size_t size_type; + typedef T value_type; + typedef const value_type& const_reference; + list(); + size_type size() const; + %rename(isEmpty) empty; + bool empty() const; + void clear(); + %rename(add) push_back; + void push_back(const value_type& x); + %extend { + const_reference get(int i) throw (std::out_of_range) { + int size = int(self->size()); + int j; + if (i>=0 && i::const_iterator p; + p=self->begin(); + for (j=0; j + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/java/ArNetworkingSwigJava.vcproj b/Legacy/Aria/java/ArNetworkingSwigJava.vcproj new file mode 100644 index 0000000..f56f467 --- /dev/null +++ b/Legacy/Aria/java/ArNetworkingSwigJava.vcproj @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/java/AriaJava-vc2010.sln b/Legacy/Aria/java/AriaJava-vc2010.sln new file mode 100644 index 0000000..312431b --- /dev/null +++ b/Legacy/Aria/java/AriaJava-vc2010.sln @@ -0,0 +1,79 @@ +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual C++ Express 2010 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AriaJava", "AriaJava.vcxproj", "{3270E630-D0D3-434D-AB7E-703362AEA947}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AriaDLL", "..\src\AriaDLL-vc2010.vcxproj", "{606257AE-E882-4C66-84C0-72331642D09F}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ArNetworkingJava", "ArNetworkingJava.vcxproj", "{01933B6F-657F-49FA-8AD8-BDC061910E92}" + ProjectSection(ProjectDependencies) = postProject + {783BA2AB-07CE-43AD-8FC2-FFD9F19DF575} = {783BA2AB-07CE-43AD-8FC2-FFD9F19DF575} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ArNetworkingSwigJava", "ArNetworkingSwigJava.vcxproj", "{AC5CCD7A-1657-4A3D-9E09-C1434B49AEFB}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AriaSwigJava", "AriaSwigJava.vcxproj", "{E333276C-952E-4A46-BED2-BC918AF7D957}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ArNetworkingDLL", "..\ArNetworking\src\ArNetworkingDLL-vc2010.vcxproj", "{783BA2AB-07CE-43AD-8FC2-FFD9F19DF575}" + ProjectSection(ProjectDependencies) = postProject + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {3270E630-D0D3-434D-AB7E-703362AEA947}.Debug|Win32.ActiveCfg = Debug|Win32 + {3270E630-D0D3-434D-AB7E-703362AEA947}.Debug|Win32.Build.0 = Debug|Win32 + {3270E630-D0D3-434D-AB7E-703362AEA947}.Debug|x64.ActiveCfg = Debug|Win32 + {3270E630-D0D3-434D-AB7E-703362AEA947}.Debug|x64.Build.0 = Debug|Win32 + {3270E630-D0D3-434D-AB7E-703362AEA947}.Release|Win32.ActiveCfg = Release|Win32 + {3270E630-D0D3-434D-AB7E-703362AEA947}.Release|Win32.Build.0 = Release|Win32 + {3270E630-D0D3-434D-AB7E-703362AEA947}.Release|x64.ActiveCfg = Release|Win32 + {3270E630-D0D3-434D-AB7E-703362AEA947}.Release|x64.Build.0 = Release|Win32 + {606257AE-E882-4C66-84C0-72331642D09F}.Debug|Win32.ActiveCfg = Debug|Win32 + {606257AE-E882-4C66-84C0-72331642D09F}.Debug|Win32.Build.0 = Debug|Win32 + {606257AE-E882-4C66-84C0-72331642D09F}.Debug|x64.ActiveCfg = Debug|x64 + {606257AE-E882-4C66-84C0-72331642D09F}.Debug|x64.Build.0 = Debug|x64 + {606257AE-E882-4C66-84C0-72331642D09F}.Release|Win32.ActiveCfg = Release|Win32 + {606257AE-E882-4C66-84C0-72331642D09F}.Release|Win32.Build.0 = Release|Win32 + {606257AE-E882-4C66-84C0-72331642D09F}.Release|x64.ActiveCfg = Release|x64 + {606257AE-E882-4C66-84C0-72331642D09F}.Release|x64.Build.0 = Release|x64 + {01933B6F-657F-49FA-8AD8-BDC061910E92}.Debug|Win32.ActiveCfg = Debug|Win32 + {01933B6F-657F-49FA-8AD8-BDC061910E92}.Debug|Win32.Build.0 = Debug|Win32 + {01933B6F-657F-49FA-8AD8-BDC061910E92}.Debug|x64.ActiveCfg = Debug|Win32 + {01933B6F-657F-49FA-8AD8-BDC061910E92}.Debug|x64.Build.0 = Debug|Win32 + {01933B6F-657F-49FA-8AD8-BDC061910E92}.Release|Win32.ActiveCfg = Release|Win32 + {01933B6F-657F-49FA-8AD8-BDC061910E92}.Release|Win32.Build.0 = Release|Win32 + {01933B6F-657F-49FA-8AD8-BDC061910E92}.Release|x64.ActiveCfg = Release|Win32 + {01933B6F-657F-49FA-8AD8-BDC061910E92}.Release|x64.Build.0 = Release|Win32 + {AC5CCD7A-1657-4A3D-9E09-C1434B49AEFB}.Debug|Win32.ActiveCfg = Debug|Win32 + {AC5CCD7A-1657-4A3D-9E09-C1434B49AEFB}.Debug|Win32.Build.0 = Debug|Win32 + {AC5CCD7A-1657-4A3D-9E09-C1434B49AEFB}.Debug|x64.ActiveCfg = Debug|Win32 + {AC5CCD7A-1657-4A3D-9E09-C1434B49AEFB}.Debug|x64.Build.0 = Debug|Win32 + {AC5CCD7A-1657-4A3D-9E09-C1434B49AEFB}.Release|Win32.ActiveCfg = Release|Win32 + {AC5CCD7A-1657-4A3D-9E09-C1434B49AEFB}.Release|Win32.Build.0 = Release|Win32 + {AC5CCD7A-1657-4A3D-9E09-C1434B49AEFB}.Release|x64.ActiveCfg = Release|Win32 + {AC5CCD7A-1657-4A3D-9E09-C1434B49AEFB}.Release|x64.Build.0 = Release|Win32 + {E333276C-952E-4A46-BED2-BC918AF7D957}.Debug|Win32.ActiveCfg = Debug|Win32 + {E333276C-952E-4A46-BED2-BC918AF7D957}.Debug|Win32.Build.0 = Debug|Win32 + {E333276C-952E-4A46-BED2-BC918AF7D957}.Debug|x64.ActiveCfg = Debug|Win32 + {E333276C-952E-4A46-BED2-BC918AF7D957}.Debug|x64.Build.0 = Debug|Win32 + {E333276C-952E-4A46-BED2-BC918AF7D957}.Release|Win32.ActiveCfg = Release|Win32 + {E333276C-952E-4A46-BED2-BC918AF7D957}.Release|Win32.Build.0 = Release|Win32 + {E333276C-952E-4A46-BED2-BC918AF7D957}.Release|x64.ActiveCfg = Release|Win32 + {E333276C-952E-4A46-BED2-BC918AF7D957}.Release|x64.Build.0 = Release|Win32 + {783BA2AB-07CE-43AD-8FC2-FFD9F19DF575}.Debug|Win32.ActiveCfg = Debug|Win32 + {783BA2AB-07CE-43AD-8FC2-FFD9F19DF575}.Debug|Win32.Build.0 = Debug|Win32 + {783BA2AB-07CE-43AD-8FC2-FFD9F19DF575}.Debug|x64.ActiveCfg = Debug|Win32 + {783BA2AB-07CE-43AD-8FC2-FFD9F19DF575}.Release|Win32.ActiveCfg = Release|Win32 + {783BA2AB-07CE-43AD-8FC2-FFD9F19DF575}.Release|Win32.Build.0 = Release|Win32 + {783BA2AB-07CE-43AD-8FC2-FFD9F19DF575}.Release|x64.ActiveCfg = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Legacy/Aria/java/AriaJava.sln b/Legacy/Aria/java/AriaJava.sln new file mode 100644 index 0000000..ccbd5a1 --- /dev/null +++ b/Legacy/Aria/java/AriaJava.sln @@ -0,0 +1,61 @@ +Microsoft Visual Studio Solution File, Format Version 8.00 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AriaJava", "AriaJava.vcproj", "{3270E630-D0D3-434D-AB7E-703362AEA947}" + ProjectSection(ProjectDependencies) = postProject + {E333276C-952E-4A46-BED2-BC918AF7D957} = {E333276C-952E-4A46-BED2-BC918AF7D957} + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AriaDLL", "..\src\AriaDLL-vc2003.vcproj", "{606257AE-E882-4C66-84C0-72331642D09F}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ArNetworkingJava", "ArNetworkingJava.vcproj", "{01933B6F-657F-49FA-8AD8-BDC061910E92}" + ProjectSection(ProjectDependencies) = postProject + {3270E630-D0D3-434D-AB7E-703362AEA947} = {3270E630-D0D3-434D-AB7E-703362AEA947} + {E333276C-952E-4A46-BED2-BC918AF7D957} = {E333276C-952E-4A46-BED2-BC918AF7D957} + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ArNetworkingSwigJava", "ArNetworkingSwigJava.vcproj", "{AC5CCD7A-1657-4A3D-9E09-C1434B49AEFB}" + ProjectSection(ProjectDependencies) = postProject + {3270E630-D0D3-434D-AB7E-703362AEA947} = {3270E630-D0D3-434D-AB7E-703362AEA947} + {01933B6F-657F-49FA-8AD8-BDC061910E92} = {01933B6F-657F-49FA-8AD8-BDC061910E92} + {606257AE-E882-4C66-84C0-72331642D09F} = {606257AE-E882-4C66-84C0-72331642D09F} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AriaSwigJava", "AriaSwigJava.vcproj", "{E333276C-952E-4A46-BED2-BC918AF7D957}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfiguration) = preSolution + Debug = Debug + Release = Release + EndGlobalSection + GlobalSection(ProjectConfiguration) = postSolution + {3270E630-D0D3-434D-AB7E-703362AEA947}.Debug.ActiveCfg = Debug|Win32 + {3270E630-D0D3-434D-AB7E-703362AEA947}.Debug.Build.0 = Debug|Win32 + {3270E630-D0D3-434D-AB7E-703362AEA947}.Release.ActiveCfg = Release|Win32 + {3270E630-D0D3-434D-AB7E-703362AEA947}.Release.Build.0 = Release|Win32 + {606257AE-E882-4C66-84C0-72331642D09F}.Debug.ActiveCfg = Debug|Win32 + {606257AE-E882-4C66-84C0-72331642D09F}.Debug.Build.0 = Debug|Win32 + {606257AE-E882-4C66-84C0-72331642D09F}.Release.ActiveCfg = Release|Win32 + {606257AE-E882-4C66-84C0-72331642D09F}.Release.Build.0 = Release|Win32 + {01933B6F-657F-49FA-8AD8-BDC061910E92}.Debug.ActiveCfg = Debug|Win32 + {01933B6F-657F-49FA-8AD8-BDC061910E92}.Debug.Build.0 = Debug|Win32 + {01933B6F-657F-49FA-8AD8-BDC061910E92}.Release.ActiveCfg = Release|Win32 + {01933B6F-657F-49FA-8AD8-BDC061910E92}.Release.Build.0 = Release|Win32 + {AC5CCD7A-1657-4A3D-9E09-C1434B49AEFB}.Debug.ActiveCfg = Debug|Win32 + {AC5CCD7A-1657-4A3D-9E09-C1434B49AEFB}.Debug.Build.0 = Debug|Win32 + {AC5CCD7A-1657-4A3D-9E09-C1434B49AEFB}.Release.ActiveCfg = Release|Win32 + {AC5CCD7A-1657-4A3D-9E09-C1434B49AEFB}.Release.Build.0 = Release|Win32 + {E333276C-952E-4A46-BED2-BC918AF7D957}.Debug.ActiveCfg = Debug|Win32 + {E333276C-952E-4A46-BED2-BC918AF7D957}.Debug.Build.0 = Debug|Win32 + {E333276C-952E-4A46-BED2-BC918AF7D957}.Release.ActiveCfg = Release|Win32 + {E333276C-952E-4A46-BED2-BC918AF7D957}.Release.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + EndGlobalSection + GlobalSection(ExtensibilityAddIns) = postSolution + EndGlobalSection +EndGlobal diff --git a/Legacy/Aria/java/AriaJava.vcproj b/Legacy/Aria/java/AriaJava.vcproj new file mode 100644 index 0000000..8cef722 --- /dev/null +++ b/Legacy/Aria/java/AriaJava.vcproj @@ -0,0 +1,160 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/java/AriaSwigJava.vcproj b/Legacy/Aria/java/AriaSwigJava.vcproj new file mode 100644 index 0000000..b730cac --- /dev/null +++ b/Legacy/Aria/java/AriaSwigJava.vcproj @@ -0,0 +1,144 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/javaExamples/Makefile b/Legacy/Aria/javaExamples/Makefile new file mode 100644 index 0000000..f7a0cf4 --- /dev/null +++ b/Legacy/Aria/javaExamples/Makefile @@ -0,0 +1,48 @@ + +ifdef JAVA_BIN +JAVAC=$(JAVA_BIN)/javac +JAVA=$(JAVA_BIN)/java +else +JAVAC=javac +JAVA=java +endif + +#### Different options for Windows or Linux: +host:=$(shell uname | cut -d _ -f 1) +ifeq ($(host),MINGW32) # host is MINGW32 on Windows: +CLASSPATH_SEP=; +RUNTIME_PATH_VAR=PATH +RUNTIME_LIB_DIR=../bin +LIB_EXT=dll +LIB_PREFIX= +else +CLASSPATH_SEP=: +RUNTIME_PATH_VAR=LD_LIBRARY_PATH +RUNTIME_LIB_DIR=../lib +LIB_EXT=so +LIB_PREFIX=lib +endif + + + +all: $(patsubst %.java,%.class,$(wildcard *.java)) + +%.class: %.java ../java/Aria.jar $(RUNTIME_LIB_DIR)/$(LIB_PREFIX)Aria.$(LIB_EXT) + @echo $^ + "$(JAVAC)" -classpath ../java/Aria.jar $< + +run%: %.class + $(RUNTIME_PATH_VAR)=$$$(RUNTIME_PATH_VAR):$(RUNTIME_LIB_DIR) "$(JAVA)" -cp ../java/Aria.jar:. $* $(ARGS) + +gdb%: %.class + $(RUNTIME_PATH_VAR)=$$$(RUNTIME_PATH_VAR):$(RUNTIME_LIB_DIR) gdb --args "$(JAVA)" -cp ../java/Aria.jar:. $* $(ARGS) + +info: + @echo host=$(host) + @echo "JAVA_BIN=$(JAVA_BIN)" + @echo "JAVAC=$(JAVAC)" + @echo "JAVA=$(JAVA)" + @echo "CLASSPATH_SEP=$(CLASSPATH_SEP)" + @echo "RUNTIME_PATH_VAR=$(RUNTIME_PATH_VAR)" + @echo "RUNTIME_LIB_DIR=$(RUNTIME_LIB_DIR)" + @echo "LIB_EXT=$(LIB_EXT)" diff --git a/Legacy/Aria/javaExamples/README.txt b/Legacy/Aria/javaExamples/README.txt new file mode 100644 index 0000000..32ee0b9 --- /dev/null +++ b/Legacy/Aria/javaExamples/README.txt @@ -0,0 +1,95 @@ + +USING THE JAVA WRAPPER FOR ARIA +------------------------------- + +A "wrapper" library for Java has been provided in the "java" directory. +This wrapper layer provides a Java API which simply makes calls using JNI +into the regular Aria or ArNetworking "native" library. + +To use the Aria Java wrapper you need to download a Java SDK. + +On Debian 3, Debian 5, and Windows, the Sun J2SE JDK +1.6 (Java SE6) was used to build the wrapper. You can download it from: + + http://java.sun.com/javase/downloads + +Find the Java SE Development Kit 6 and click "Download". (Only the JDK +is needed, ARIA does not need Java EE or any other extra Java technologies.) + +The JDK also includes the runtime environment (JRE) that allows you to run +Java programs. If you only need the JRE, it can also +be obtained from . + +On Ubuntu, Ubuntu's "default-jdk" package was installed and used to build +the wrapper (which uses openjdk 6 on Ubuntu 12.04). + +In Windows you must then put Aria's 'bin' directory into your PATH environment +variable so that Java can find the dlls needed to run the wrapper. (Environment +variables are set in the System control panel. If you used the default +installation location, add "C:\Program Files\MobileRobots\Aria\bin" to PATH.) +(The java wrapper tries to load AriaJava.dll, which also requires AriaVC10.dll.) + +For an example you can start the simulator, then enter the javaExamples +directory and compile the simple Java example by using this command: + + javac -classpath ../java/Aria.jar simple.java + +Then run it with this command in Windows: + java -cp ../java/Aria.jar;. simple + +or this one in Linux: + java -cp ../java/Aria.jar:. simple + +(The difference is the seperator in the class path: ';' vs ':'.) + +The Java wrapper is not as well tested as Aria itself. If you encounter +problems using it, please notify the aria-users mailing list. + +You can use the C++ API documentation in 'docs', or you can use javadoc +to generate a Java API reference based on the java source files in the 'java' +directory. + + + +USING ARFUNCTOR IN JAVA +----------------------- + +Since you can't have a "pointer" to a method in Java, to use ArFunctors, +you must define a subclass of ArFunctor which overrides invoke(). For +functors that take arguments, you can only use specially defined +ArFunctor subclasses, see java/com/mobilerobots/Aria/ArFunctor_*.java. +(More can be added by adding them to wrapper.i and rebuilding the wrapper +using SWIG.) + + + + +REBUILDING THE JAVA WRAPPER +--------------------------- + +If you want to rebuild the Java wrapper you need to install SWIG: +See You should get at +least version 1.3.29. + +You then need to set the environment variable JAVA_INCLUDE to the include +directory in your Java SDK, and JAVA_BIN to the bin directory in your Java +SDK. + +If you installed Sun Java on Linux in "/usr/local/jdk", use +"/usr/local/jdk/bin" for JAVA_BIN and "/usr/local/jdk/include" for +JAVA_INCLUDE. + +If you installed "default-jdk" on Ubuntu, then use +"/usr/lib/jvm/default-java/bin" for JAVA_BIN and +"/usr/lib/jvm/default-java/include" for JAVA_INCLUDE. + +On Windows, use "C:\Program Files\Java\jdk1.6.0_10\bin" for +JAVA_BIN and "C:\Program Files\Java\jdk1.6.0_10\include" for JAVA_INCLUDE. + +In Linux, run 'make java' in the Aria directory. + +In Windows with Visual Studio 2010, open java/AriaJava-vc2010.sln, select +Tools menu -> Options -> Projects -> VC++ Directories and add your SWIG +directory. Select Release build configuration. Then build or rebuild the AriaJava +project. + diff --git a/Legacy/Aria/javaExamples/actionExample.java b/Legacy/Aria/javaExamples/actionExample.java new file mode 100644 index 0000000..5926cf7 --- /dev/null +++ b/Legacy/Aria/javaExamples/actionExample.java @@ -0,0 +1,273 @@ + +/* + +example program demonstrating how to make and use new actions. + +This example program creates two new actions, Go and Turn. Go will drive the robot forward safely, +while Turn will avoid obstacles detected by the sonar by turning. +This program also adds a predefined +action from Aria which tries to recover from stalls (hit something and +can't move forward) by backing and turning. + +Each of these actions have the normal constructor and destructor, note that +the constructors use constructor chaining to create their ArAction part +correctly. Each action then also implements the essential virtual method, +fire(). This fire function is called by the action resolver, and +returns values that, in combination with other actions' desired behavior, +determine the driving commands sent to the robot. + +Also note that each of these actions override the setRobot function; these +implementations obtain the sonar device from the robot in addition to doing the +needed caching of the robot pointer. This is what you should do if you +care about the presence or absence of a particular sensor. If you don't +care about any particular sensor you could just use one of the checkRangeDevice... +methods in ArRobot (there are four of them). +Also note that these are very naive actions, they are simply an example +of how to use actions. + +See the @ref actions Actions section of the Aria reference manual overview for more details about actions. + +Note that actions must take a small amount of time to execute, to avoid +delaying the robot synchronization cycle. + +*/ + + + +import com.mobilerobots.Aria.*; + +/** + * Example Action class that drives the robot forward, but stops if obstacles are + * detected by sonar. + */ +class ExampleGoAction extends ArAction +{ + // constructor, sets myMaxSpeed and myStopDistance + public ExampleGoAction(double maxSpeed, double stopDistance) + { + super("Go"); + myMaxSpeed = maxSpeed; + myStopDistance = stopDistance; + myDesired = new ArActionDesired(); + } + + + /** + This fire is the whole point of the action. + currentDesired is the combined desired action from other actions + previously processed by the action resolver. In this case, we're + not interested in that, we will set our desired + forward velocity in the myDesired member, and return it. + + */ + public ArActionDesired fire(ArActionDesired currentDesired) + { + double speed; + + + // reset the actionDesired (must be done), to clear + // its previous values. + myDesired.reset(); + + // get the range of the sonar + double robotRadius = 400; + double range = mySonar.currentReadingPolar(-70, 70) - robotRadius; + // if the range is greater than the stop distance, find some speed to go + if (range > myStopDistance) + { + // just an arbitrary speed based on the range + speed = range * .3; + // if that speed is greater than our max, cap it + if (speed > myMaxSpeed) + speed = myMaxSpeed; + // now set the velocity + myDesired.setVel(speed); + } + // the range was less than the stop distance, so request stop + else + { + myDesired.setVel(0); + } + // return the actionDesired to the resolver to make our request + return myDesired; + } + + + /** + Override ArAction.setRobot() to get the sonar device from the robot, or deactivate this action if it is missing. + You must also call ArAction.setRobot() to properly store + the ArRobot pointer in the ArAction base class. + */ + public void setRobot(ArRobot robot) + { + setActionRobot(robot); + mySonar = robot.findRangeDevice("sonar"); + } + + // the sonar device object obtained from the robot by setRobot() + protected ArRangeDevice mySonar; + + + /** Our current desired action: fire() modifies this object and returns + to the action resolver a pointer to this object. + This object is kept as a class member so that it persists after fire() + returns (otherwise fire() would have to create a new object each invocation, + but would never be able to delete that object). + */ + protected ArActionDesired myDesired; + + protected double myMaxSpeed; + protected double myStopDistance; +} + +/** Example action class that turns the robot away from obstacles detected by the + * sonar. Used by actionExample.java. */ +class ExampleTurnAction extends ArAction +{ + + public ExampleTurnAction(double turnThreshold, double turnAmount) + { + super("Turn"); + myTurnThreshold = turnThreshold; + myTurnAmount = turnAmount; + myTurning = 0; + myDesired = new ArActionDesired(); + } + + /** + This is the guts of the Turn action. + */ + public ArActionDesired fire(ArActionDesired currentDesired) + { + double leftRange, rightRange; + // reset the actionDesired (must be done) + myDesired.reset(); + double robotRadius = 400; + // Get the left readings and right readings off of the sonar + leftRange = (mySonar.currentReadingPolar(0, 100) - robotRadius); + rightRange = (mySonar.currentReadingPolar(-100, 0) - robotRadius); + // if neither left nor right range is within the turn threshold, + // reset the turning variable and don't turn + if (leftRange > myTurnThreshold && rightRange > myTurnThreshold) + { + myTurning = 0; + myDesired.setDeltaHeading(0); + } + // if we're already turning some direction, keep turning that direction + else if (myTurning != 0) + { + myDesired.setDeltaHeading(myTurnAmount * myTurning); + } + // if we're not turning already, but need to, and left is closer, turn right + // and set the turning variable so we turn the same direction for as long as + // we need to + else if (leftRange < rightRange) + { + myTurning = -1; + myDesired.setDeltaHeading(myTurnAmount * myTurning); + } + // if we're not turning already, but need to, and right is closer, turn left + // and set the turning variable so we turn the same direction for as long as + // we need to + else + { + myTurning = 1; + myDesired.setDeltaHeading(myTurnAmount * myTurning); + } + return myDesired; + } + + + /** + Calls the ArAction.setRobot() method to store the robot object (all setRobot overloaded functions must do this), + finds the sonar device from the robot. + */ + public void setRobot(ArRobot robot) + { + setActionRobot(robot); + mySonar = robot.findRangeDevice("sonar"); + } + + // this is to hold the sonar device form the robot + protected ArRangeDevice mySonar; + // what the action wants to do; used by the action resover after fire() + protected ArActionDesired myDesired; + // distance at which to start turning + protected double myTurnThreshold; + // amount to turn when turning is needed + protected double myTurnAmount; + // remember which turn direction we requested, to help keep turns smooth + protected int myTurning; // -1 == left, 1 == right, 0 == none +} + + + +public class actionExample { + + + /* Try to load the Aria and ArNetworking wrapper libraries when the + * program starts: + */ + static { + try { + System.loadLibrary("AriaJava"); + } catch(UnsatisfiedLinkError e) { + System.err.println("Native code library libAriaJava failed to load. Make sure that its directory is in your library path. See javaExamples/README.txt and the chapter on Dynamic Linking Problems in the SWIG Java Documentation (http://www.swig.org) for help.\n" + e); + System.exit(1); + } + } + + + public static void main(String argv[]) { + Aria.init(); + + ArSimpleConnector conn = new ArSimpleConnector(argv); + ArRobot robot = new ArRobot(); + ArSonarDevice sonar = new ArSonarDevice(); + + // Create instances of the actions defined above, plus ArActionStallRecover, + ExampleGoAction go = new ExampleGoAction(500, 350); + ExampleTurnAction turn = new ExampleTurnAction(400, 10); + + // a predefined action from Aria. + ArActionStallRecover recover = new ArActionStallRecover(); + + + // Parse all command-line arguments + if(!Aria.parseArgs()) + { + Aria.logOptions(); + System.exit(1); + } + + // Connect to the robot + if(!conn.connectRobot(robot)) + { + ArLog.log(ArLog.LogLevel.Terse, "actionExample: Could not connect to robot! Exiting."); + System.exit(2); + } + + // Add the range device to the robot. You should add all the range + // devices and such before you add actions + robot.addRangeDevice(sonar); + + + // Add our actions in order. The second argument is the priority, + // with higher priority actions going first, and possibly pre-empting lower + // priority actions. + robot.addAction(recover, 60); + robot.addAction(turn, 50); + robot.addAction(go, 40); + + // Enable the motors, disable amigobot sounds + robot.enableMotors(); + + // Run the robot processing cycle. + // 'true' means to return if it loses connection, + // after which we exit the program. + robot.run(true); + + Aria.exit(0); + } +} + diff --git a/Legacy/Aria/javaExamples/joyHandler.java b/Legacy/Aria/javaExamples/joyHandler.java new file mode 100644 index 0000000..c84fcc0 --- /dev/null +++ b/Legacy/Aria/javaExamples/joyHandler.java @@ -0,0 +1,46 @@ + +/* How to use ArJoyHandler in Java */ + +import com.mobilerobots.Aria.*; + +public class joyHandler { + + static { + try { + System.loadLibrary("AriaJava"); + } catch (UnsatisfiedLinkError e) { + System.err.println("Native code library libAriaJava failed to load. Make sure that its directory is in your library path; See javaExamples/README.txt and the chapter on Dynamic Linking Problems in the SWIG Java documentation (http://www.swig.org) for help.\n" + e); + System.exit(1); + } + } + + public static void main(String argv[]) { + Aria.init(); + ArJoyHandler joyHandler = new ArJoyHandler(); + if(!joyHandler.init()) { + System.out.println("Error initializing joy handler. (No joystick or no joystick OS device installed?)"); + Aria.exit(1); + } + boolean havez = joyHandler.haveZAxis(); + System.out.printf("Initialized? %s\tHave Z? %s\tNum Axes %d\tNum Buttons %d\n", + joyHandler.haveJoystick()?"yes":"no", havez?"yes":"no", joyHandler.getNumAxes(), joyHandler.getNumButtons()); + while(true) { + ArJoyVec3f pos = joyHandler.getDoubles(); + ArJoyVec3i adj = joyHandler.getAdjusted(); + ArJoyVec3i unf = joyHandler.getUnfiltered(); + ArJoyVec3i speed = joyHandler.getSpeeds(); + System.out.print("("+pos.getX()+", "+pos.getY()+", "+pos.getZ()+") "+ + "\tAdjusted: ("+adj.getX()+", "+adj.getY()+", "+adj.getZ()+") "+ + "\tUnfiltered: ("+unf.getX()+", "+unf.getY()+", "+unf.getZ()+") "+ + "\tSpeed: ("+speed.getX()+", "+speed.getY()+", "+speed.getZ()+")\tButtons: ["); + for(int i = 0; i < joyHandler.getNumButtons(); ++i) { + if (joyHandler.getButton(i)) { + System.out.print(i + " "); + } + } + System.out.println("]"); + ArUtil.sleep(1000); + } + //Aria.exit(0); + } +} diff --git a/Legacy/Aria/javaExamples/laserWander.java b/Legacy/Aria/javaExamples/laserWander.java new file mode 100644 index 0000000..99723b1 --- /dev/null +++ b/Legacy/Aria/javaExamples/laserWander.java @@ -0,0 +1,82 @@ +/* A simple Java program that demonstrates using a SICK laser rangefinder + * as well as sonar on the robot, and using a predefined ArAction from + * the ARIA library to avoid obstacles. + * + * NOTE you currently must change the call to configureShort() below if + * you are using the simulator. This is a bug in the Java wrapper. + */ + +import com.mobilerobots.Aria.*; + +public class laserWander { + + static { + try { + System.loadLibrary("AriaJava"); + } catch (UnsatisfiedLinkError e) { + System.err.println("Native code library libAriaJava) failed to load. Make sure that its directory is in your library path; See javaExamples/README.txt and the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e); + System.exit(1); + } + } + + public static void main(String argv[]) { + System.out.println("Starting Java Laser Example"); + + Aria.init(Aria.SigHandleMethod.SIGHANDLE_THREAD, true); + + // Main robot object + ArRobot robot = new ArRobot("robot1", true, true, true); + + // Range device + ArSick laser = new ArSick(); + ArSonarDevice sonar = new ArSonarDevice(); + robot.addRangeDevice(sonar); + robot.addRangeDevice(laser); + + // Connect to robot + ArSimpleConnector conn = new ArSimpleConnector(argv); + if(!Aria.parseArgs()) + { + System.err.println("Error parsing arguments (defaults or command line). Exiting."); + Aria.logOptions(); + System.exit(1); + } + if (!conn.connectRobot(robot)) + { + System.err.println("Could not connect to robot, exiting.\n"); + System.exit(1); + } + + // Configure and connect to laser. The first argument determines whether + // to use simulated laser connection over the TCP port, or to try to connect + // to a real SICK on the serial port. + conn.setupLaser(laser); + //laser.configureShort(false /* Use Simulator? */, ArSick.BaudRate.BAUD38400, ArSick.Degrees.DEGREES180, ArSick.Increment.INCREMENT_ONE); + laser.runAsync(); + if(!laser.blockingConnect()) + { + System.err.println("Could not connect to a laser, it won't be used."); + } + else + { + } + + // Add actions + ArActionBumpers bumpers = new ArActionBumpers(); + ArActionLimiterForwards limiter = new ArActionLimiterForwards("speed limiter", 300, 600, 250, 1.1); + ArActionTurn turn = new ArActionTurn(); + ArActionConstantVelocity constantVel = new ArActionConstantVelocity("constant velocity", 400); + robot.addAction(bumpers, 75); + robot.addAction(limiter, 49); + robot.addAction(turn, 30); + robot.addAction(constantVel, 20); + + + // Let program run forever until cancelled + System.out.println("Wandering..."); + robot.enableMotors(); + robot.run(true); + System.out.println("Robot disconnected. Shutting down and exiting."); + Aria.exit(0); + } +} diff --git a/Legacy/Aria/javaExamples/map.java b/Legacy/Aria/javaExamples/map.java new file mode 100644 index 0000000..d9a4f5c --- /dev/null +++ b/Legacy/Aria/javaExamples/map.java @@ -0,0 +1,45 @@ + +/* A simple example of connecting to and driving the robot with direct + * motion commands. + */ + +import com.mobilerobots.Aria.*; + +public class map { + + static { + try { + System.loadLibrary("AriaJava"); + } catch (UnsatisfiedLinkError e) { + System.err.println("Native code library libAriaJava failed to load. Make sure that its directory is in your library path; See javaExamples/README.txt and the chapter on Dynamic Linking Problems in the SWIG Java documentation (http://www.swig.org) for help.\n" + e); + System.exit(1); + } + } + + public static void main(String argv[]) { + System.out.println("Starting Java Map Test"); + + Aria.init(); + + //System.out.println("Will be able to load maps from the c++ maps directory: + //../maps."); + //ArMap map = new ArMap("../maps/"); + ArMap map = new ArMap(); + System.out.println("loading map: ../maps/columbia.map"); + if(!map.readFile("../maps/columbia.map")) + { + System.out.println("Error loading map."); + } + else + { + //System.out.println("writing map: out.map in ../maps directory"); + System.out.println("writing map: out.map"); + if(!map.writeFile("out.map")) + { + System.out.println("error writing map"); + } + } + + Aria.exit(0); + } +} diff --git a/Legacy/Aria/javaExamples/robotSyncTaskExample.java b/Legacy/Aria/javaExamples/robotSyncTaskExample.java new file mode 100644 index 0000000..7aa9e5e --- /dev/null +++ b/Legacy/Aria/javaExamples/robotSyncTaskExample.java @@ -0,0 +1,114 @@ +/* + Shows how to add a task callback to ArRobot's synchronization/processing cycle + + This program will just have the robot wander around, it uses some avoidance + routines, then just has a constant velocity. A sensor interpretation task callback is invoked + by the ArRobot object every cycle as it runs, which records the robot's current + pose and velocity. + + In Java, to pass an ArFunctor object to Aria, you must define a subclass + of ArFunctor which overrides the invoke() method. + + Note that tasks must take a small amount of time to execute, to avoid delaying the + robot cycle. +*/ + +import com.mobilerobots.Aria.*; + +class PrintingTask extends ArFunctor +{ + private ArRobot myRobot; + + + // Constructor. Adds our 'user task' to the given robot object. + public PrintingTask(ArRobot robot) + { + System.out.println("Java PrintingTask: adding sensor interpretation task to ArRobot..."); + myRobot = robot; + myRobot.addSensorInterpTask("PrintingTask", 50, this); + } + + // This method will be called when Aria invokes the task functor + public void invoke() + { + // print out some info about the robot + System.out.println("Java PrintingTask: x " + (int) myRobot.getX() + + " y " + (int) myRobot.getY() + + " th " + (int) myRobot.getTh() + + " vel " + (int) myRobot.getVel() + + " mpacs " + (int) myRobot.getMotorPacCount()); + + // Need sensor readings? Try myRobot.getRangeDevices() to get all + // range devices, then for each device in the list, call lockDevice(), + // getCurrentBuffer() to get a list of recent sensor reading positions, then + // unlockDevice(). + } + +} + + +public class robotSyncTaskExample +{ + static { + try { + System.loadLibrary("AriaJava"); + } catch(UnsatisfiedLinkError e) { + System.err.println("Native code library (libAriaJava.so or AriaJava.dll) failed to load. Make sure that it is in your library path."); + System.exit(1); + } + } + + public static void main(String argv[]) + { + Aria.init(); + ArArgumentParser parser = new ArArgumentParser(argv); + parser.loadDefaultArguments(); + ArSimpleConnector con = new ArSimpleConnector(parser); + if(!Aria.parseArgs()) + { + Aria.logOptions(); + System.exit(1); + } + + ArRobot robot = new ArRobot(); + + ArSonarDevice sonar = new ArSonarDevice(); + + PrintingTask printingTask = new PrintingTask(robot); + + // the actions we will use to wander + ArActionStallRecover recover = new ArActionStallRecover(); + ArActionAvoidFront avoidFront = new ArActionAvoidFront(); + ArActionConstantVelocity constantVelocity = new ArActionConstantVelocity("Constant Velocity", 400); + + + // add the sonar object to the robot + robot.addRangeDevice(sonar); + + // open the connection to the robot; if this fails exit + if(!con.connectRobot(robot)) + { + System.err.println("Could not connect to the robot."); + System.exit(1); + } + System.out.println("Java robotSyncTaskExample: Connected to the robot. (Press Ctrl-C to exit)"); + + + // turn on the motors + robot.enableMotors(); + + // add the wander actions + robot.addAction(recover, 100); + robot.addAction(avoidFront, 50); + robot.addAction(constantVelocity, 25); + + // Start the robot process cycle running. Each cycle, it calls the robot's + // tasks. When the PrintingTask was created above, it added a new + // task to the robot. 'true' means that if the robot connection + // is lost, then ArRobot's processing cycle ends and this call returns. + robot.run(true); + + System.out.println("Java robotSyncTaskExample: Disconnected. Goodbye."); + + } +} diff --git a/Legacy/Aria/javaExamples/simple.java b/Legacy/Aria/javaExamples/simple.java new file mode 100644 index 0000000..5a1c117 --- /dev/null +++ b/Legacy/Aria/javaExamples/simple.java @@ -0,0 +1,71 @@ + +/* A simple example of connecting to and driving the robot with direct + * motion commands. + */ + +import com.mobilerobots.Aria.*; + +public class simple { + + static { + try { + System.loadLibrary("AriaJava"); + } catch (UnsatisfiedLinkError e) { + System.err.println("Native code library libAriaJava failed to load. Make sure that its directory is in your library path; See javaExamples/README.txt and the chapter on Dynamic Linking Problems in the SWIG Java documentation (http://www.swig.org) for help.\n" + e); + System.exit(1); + } + } + + public static void main(String argv[]) { + System.out.println("Starting Java Test"); + + Aria.init(); + + ArRobot robot = new ArRobot(); + ArSimpleConnector conn = new ArSimpleConnector(argv); + + if(!Aria.parseArgs()) + { + Aria.logOptions(); + Aria.exit(1); + } + + if (!conn.connectRobot(robot)) + { + System.err.println("Could not connect to robot, exiting.\n"); + System.exit(1); + } + robot.runAsync(true); + robot.lock(); + System.out.println("Sending command to move forward 1 meter..."); + robot.enableMotors(); + robot.move(1000); + robot.unlock(); + System.out.println("Sleeping for 5 seconds..."); + ArUtil.sleep(5000); + robot.lock(); + System.out.println("Sending command to rotate 90 degrees..."); + robot.setHeading(90); + robot.unlock(); + System.out.println("Sleeping for 5 seconds..."); + ArUtil.sleep(5000); + robot.lock(); + System.out.println("Robot coords: robot.getX()=" + robot.getX() + ", robot.getY()=" + robot.getY() + ", robot.getTh()=" + robot.getTh()); + ArPose p = robot.getPose(); + System.out.println(" pose.getX()=" + p.getX() + ", pose.getY()=" + p.getY() + ", pose.getTh()=" + p.getTh()); + double[] xout = {0}; + double[] yout = {0}; + double[] thout = {0}; + p.getPose(xout, yout, thout); + System.out.println(" pose.getPose(): x=" + xout[0] + ", y=" + yout[0] + ", th=" + thout[0]); + robot.unlock(); + robot.lock(); + System.out.println("exiting."); + robot.stopRunning(true); + robot.unlock(); + robot.lock(); + robot.disconnect(); + robot.unlock(); + Aria.exit(0); + } +} diff --git a/Legacy/Aria/javaExamples/socket.java b/Legacy/Aria/javaExamples/socket.java new file mode 100644 index 0000000..19685cc --- /dev/null +++ b/Legacy/Aria/javaExamples/socket.java @@ -0,0 +1,54 @@ + + +import com.mobilerobots.Aria.*; + +public class socket { + + static { + try { + System.loadLibrary("AriaJava"); + } catch (UnsatisfiedLinkError e) { + System.err.println("Native code library libAriaJava failed to load. Make sure that its directory is in your library path; See javaExamples/README.txt and the chapter on Dynamic Linking Problems in the SWIG Java documentation (http://www.swig.org) for help.\n" + e); + System.exit(1); + } + } + + public static void main(String argv[]) { + Aria.init(); + ArSocket s1 = new ArSocket(); // server socket. accepts clients. + ArSocket s2 = new ArSocket(); // client + ArSocket s1client = new ArSocket(); // used by server to communicate with client + if (!s1.open(6789, ArSocket.Type.TCP)) { + System.err.println("Error opening first TCP socket on port 6789."); + Aria.exit(1); + } + System.out.println("First socket opened and listening on port 6789."); + System.out.println("Connecting second socket to localhost port 6789..."); + if (!s2.connect("localhost", 6789)) { + System.err.println("Error connecting second TCP socket to local host port 6789"); + Aria.exit(2); + } + if (!s1.accept(s1client)) { + System.err.println("Error accepting client on first socket."); + Aria.exit(3); + } + System.out.println("Connected."); + System.out.println("Second socket is sending \"hello\" to first..."); + s2.write("hello"); + String text = new String(""); + text = s1client.read(512, 5000); // arguments are buffer size and timeout to wait + /* + while(text.length() == 0) + { + text = s1client.read(512, 5000); // arguments are buffer size and timeout to wait + } + */ + System.out.println("=> First socket recieved \""+text+"\" ("+text.length()+")"); + System.out.println("First socket is sending \"hello\" to second..."); + s1client.write("hello"); + text = s2.read(512, 5000); + System.out.println("=> Second socket recieved \""+text+"\""); + s2.close(); + Aria.exit(0); + } +} diff --git a/Legacy/Aria/lib/libAria.so b/Legacy/Aria/lib/libAria.so new file mode 100644 index 0000000000000000000000000000000000000000..ee2c0c56c0a1597548a0c86c8d41203ca61a586e GIT binary patch literal 5447696 zcma&O4_KSWndtk@Xe35L;E@nmV4RMGAOe#_V4PytO-Diyfw3zvPD$dlGQloMoD@4w z*G;qA(TBi-5JzC*lGJGh!6|Xw7U$o(+3r?g?BLYtlEm4jX?G7!lh#es-6U;K(>=ZC zoL8x`Pwu(*KF^)!`T2ckB&6?~Z)V;Gqrk zpr8@*@ZWM+^Wl5V|MklMQ*mvKe%Sbt1dt!rv)^Gs1!PyzP|Leeg8L^$=%9Fl7ILr07IE&DfjySDSf&3eI&E*&6em}2YR#m z$%^YgtpA@foco}U|E!0PC3I_FY#~FjK<|rHTe#OSYcY)@vTh4 zlnhr3uBGsJJYL|eEq>LQc1t_B!u_#*wmJx$e;W9+v0D^>In?NOn_^(dW&o>@Au3Y# zb>XdcUgVM^gRXOa$Cw|^DWROjc$tEjd4cJ*!i@2zRRjd~j}jAtr5pR3%zhe5FP5KzP+MkabZY6HZ~9MbTP2&WAqelJ2MN4@~3iJ#Qu_<5sM zW;R$ouRWO$d~fkLQPy>H1{9aV+ai0R9W*TWL0Y`v7_IOX zHi8F-f?Wf#5zb2va;tE;MORq`AD#D5Ab2qpIJE4iP#}}h&B++9M5Ven%qpHEzkT?o z)dN07QkEx`mH0&hn4V<47CVzBs{Bu~B^*w5Gu|E?Hc_~uh#l{NZE(XM7$|&aKR=_y zOhrei#SoAHgZe9~>|pr-4tUy%6HQT*0b$7*&;)F8h>WX=#!bOq<&i~a6^Nc1e|XLoX?mI} zk25UZ<@dO8X_z)7H7Kqr@hQ9<2lrY>=I}C9g*RRm1Hy(oEjPgJp&+A?UKp&G9(zgy zH93@~0hhrYCc5+lcnmAvn>#}GkXZ(;VD?1KbyG2;GV_7r)Vj$WZ--IFRGqJ}v1VMR z_lK85yPwo}sbL`<=dc^Rs!3P`$vY|$)TDcEN#ZwaJzaFDKJ zg^Wv>hu%(Url%wov2r7^EMYd z8eODD?9d_GKixZfUBXhQog`kEp_2+!kbfIA~k0BP23ojlr554LHL!_*hH`>KAj%{wk-ZKn%wKkU^B9SVzh zJPotw-j|NRpPEijyfh$PG91=8By>Ciq2RwHZ@9eDKrJE8Q^DpEhs z-tVd+;ykE%jc&0*oO2a4)ssZOIdT1w>MCAnL~jve=}V@B0K=%y7ViEE zZHu)IDxeW_p(sX^1)&9V3%GC8(CZR>(N-PIfK=Kxhs$Be&!8)He^D{0GiD2Ksr=N~ zqjuFJJL~D1w=&!arCu8HPC&_!NrwR5-(C2U_(n-s>UgxF+8%EegHwZ1;Ew4^Zw5zc zGT)MMmYeY2H*g>30&@^F*$i>G{=LSv; z;GSl=Nm=PRs8>%q?`+rB2XHO12w%PQS84ML)>&5?k_4A*(qwS;DIPub36u-{TBg zhBmJ3y3>B9t+D$bQ;DnQ=?7}PT?8XB<=8z%#I*2kFM-Mt(=IOEEeF1NcA}<{)y8_$ zG7002sm2oi*r)Tte78Y)m=Mtn%6EAboetgzWTQ?2iyE;TRHwPyZ@WUPV(r5l)TGa5 z8)z_=g~<`yj(t~0I7~>g>DG%UEcSd-6osa+&%ocdorw_CMO}Q}A_AF1;_& zmttuyHGM%PX>stI9M*ig!L^QuT1f&@e2dL$S>+l&SQ2^;+H_Qf+s&`cmxSKElSy$f zJ}#Zr_oCqk0x6-7CO^T>Hz%y2n1FG9C}V?iCRIGC#r?Om2fCiOscmOnHs|6soy|$A z*7+52oHnhLUVj|Ysrd}?5g**2+@*s%=eF62-~gVnKqReX00ieC;W(ej^hbCk-npmt z;6D9NR>;K169s_)gi6b3XBoMa?7LOAGPhx;rD_!#P=E%oGzP0>qiMyJ(E}lG!%Q%- zDwcA&1{QfL%4Z?yW8M6mK%wnA59S$RBlH!z2g3 zV6NRf7I;rs(U%Hdu1=vnO+-v#^03RFIA34wEu7v52f`d5A4C*qTuCM*a5eq>s^GhU zmn{QEQBS*nsge^&8Z78|GHI)g)6(In(_?NDfGe)aaXKuLsKNxuxU`q@`hCpjZnuYv zb;rml$bUcz;K4XVWo9}ioC1D=L!=AR3lC8@kBSAS)lnm&4V__Nan7n#0SG2Zf7EFelngn7vl9cn(;<0%TgHhzb(R(k44pM z;E*&>gkcuUP4bF|CS2}EimC@a?CPU!ag(9D@2Z8T0^S;Vp(!9z)w0VA zVHoB~_4;a{3jM%pKYH+y34+s_OT~okHsGL4cMhozJp!g{NUv${(uh5{SOS-yY!Puf*m-5un#xwn_XOJ6AT!0GSwQHSeP*>m;L?f`((mI5c!AdSt?f&L{v#0*3C zC*(&H3n~N5PN5{o)T3~Hi^{CI{x>1hest8pu0=*W%rFc2mbP^#0?~Ek1{^sZTJyC1 z%x~$-4aq`b?bH9uZf$^a+HoYjf!Ge23mJyV2^=P*z9^ms9n` zO_^Edzss)zl9Y8LAnz!0tsHO~izdB3d~&QxM@?Qvw8fc%C^5?$Lob8$?GBt{z^4j5 zOvIP~YgsxRI4Fv;)6fsqF->-Iph7wU`W!o+-r8&JVen$Yl(Hm>2wWR1rX?Pk8qEB!r~4U^u(OC8r^B2Gh)vy99$y4E>Kn$rc}C!Dl)`A5>!&w zK_0scL!u?{f(c@Z3Ko?t;Zi=nN$AOAb?*0rrfwd-%9_calwPxkR;M+X&7`Q-hKoBs zwUBT+!hT?itzT&Ja2!f6NIL2c=6myf@WT6F8n4Z3I)(Q|I}0I|&T=62PIz%+EGq1^#qVYX&RAC%%{K&8efD7(;oU6a)9 z#D}AIUt-sOOTXvxL}}u+%Vg_JXrs}8Xw;)|Bzv5S+F1CAia|e&C|voq3R^KsbNXx@ z`N-&fLi@R7|flefM)oX}+<)IkIVjH6(u8FH`*M%MNSEF53^=BCp=!BZ2U6 z!$lq{Q>n=dSM?4GahxbB9hOl-kNZ*?*_rZ3h^$ozUvqM-)vsWdXeWF6=33BY2( zYbo$ykHOAvrUzS{Kwae;HdcQy0Eb!p7tu@2bAEgu#^b@@b+?3$N33Qk>T6~_DrR#8 z(6r3koHAZCNKf2ae; zAy?+0vK?KBS-B*q^HRW1P;sF+s-He_m3u5>A34A>WP$Yau#vQq(8WcJa4mj?nXLLt zQ$eTWM((2nTSL={C4(h3EP*8O2u*LEl(q=V{BU44dN+f^DVY3zuuV-RNxSrWChq(4 z%?7$`CW#>)_A`1tXgSQ#6c*FKaDrrj8p)18X2b-11>GIN5)(c2NNUTQ*hvHkdXqW` zpd(J99pQOSLTr1|kO|Of@5B}Mb8wEP2X456O}gxHWuA>pjp1?_wk>S2R}?|N1r)Be z+2`B3){q6Tg()anOszHcyP0o#6-cj01RKPo+Z-6feel(;%eN1Ms7&5w^2%AV+*xie zo;!+P&T+Dj6G&lr8d>&}_@o13UggK~5;1oqe6QT0aY!LgV*dHr-zwcv`x=|I+Ej;NXT2LVLKlTH>{0vPBsY zuUKz}Rl8kTpW$j!Heq^hrH5h`@-AVLa4|>a5UqAW=UR;a&_!yx%`m&Pp9UU(efgR^B=CwSeliI9XV<%#{kzS*q~J|S;%iSo*6(Q|Zl5N1^8O%!@gDN&WR?F7YIYPx zXJAITr6IxV@lr7KK$@l>Z;XskdLB&kwUsYzN;vO#)|2~$L9*QhFm}11VfgLnKz2w0 z;mX?vQq8zXSwGNjes$#9X5d#wV^E~=GakvP~VDiGgtIe((R2+QsIh=c7WgXXSc9O z^{@+QH7GB3nve;jHbjoOX)GCXmOmSO*%_zQ7f6G**c<%i*~@{$zfL)0A|X}4n+LR+ zVK)QLn&qP_A`$206hns`-BJoyh3V5!(hRb-}K;qo>0;gF%jV#6n++^H;q0T56uXkHqH9kI1?L8ZAtT2pq8p^2NE^|9$P%a`>{U> zi7@rno@N;b z*_qHcf=+0`TfrnFag}y}+!iLKJ8lIqck8LBjasZ$Q`+@S0Y2BM#mM|+UrI`t&PZZi zHid0ek%}VKVRd?zlsdv&k4?aIejgKjCRG`I+Y`l)MOWfj&4P)3;)M&0nBOtG7q2zz zIyOxy1|+RPz9{$3d|o@PxVQnl2Hv-J{4V%~nb~tb5^p>d1X=%DqnBHG#zhTR&nH-q zhInh(ZeRA{im0WHmL>9<7?6Q`p8SP4RsSs<&SkjvVF1(>v<$kdC$HbD)PMK0D(yp~ zrKi%;>q&W{F7v&~AGU?-Yo1s$|5cq49scj0FKpc(e5%3$bb{$AgERxtOAfY5LkErM z^sbavE1DH>^O!h4b2&X({9Ss<6%|y<6)gi^@{30KN$DL*yCe;oHhCB+sS`UK#9ouI z$DNL!_NA=R&8GAYOw|@j{RV+OwX`)=M;4?7!}}|_IRxE7ez-ZPhAh9tphgFJNL+c; zH@iejqI8CMB-<<%yd^ z1+fC_eP8aTu!cT$(QT%jxNfcx58l{KcLq8M4>`al=nm!bTyN`8z&f z&km1)^Yo5yq@qEW9z~}j6kfe8;a){d6JTTI9%!SUp?A7XlZ{S`Oz8#_q_k$r11U*N zj6u`a^m}jAct;s`mkXN#N3V?ci$PQ9X?he`oS?rd287YrGfZ_9!?SS34P6n=j zoC1|N5@~$aV<&UMzlzvBLEoEiDpk$>Xb#(0q2{I=tPZ1GvVd00Y1#0>ir2{nC)0ta z2GQ!eQoY)eR`EbXY9$@NmcdvLEbnX#hl-nk~EJZ2bx){IA?9YXnbxc18A3W4hf4nT- zd|F?#$ypcuZk+dvQ|s@Cu;G3qWn#h=hOT;+b@yU6>S^#rxIp*b#3q3Xf2%uk4y+Pr zC;`F&%ww@ox3LrlXaU37tzDQi zh2D~fsiOi-Q;w`yO4{6t4T&=qK51XbNLUZ@4`ZqZe^vC$vEe0MxxX&bBTB1T8rW6NX3YMGCL zXm_WrVq5qDt{{(pUgN^S7$cCT0+K-{)w|C<;!jo!!5j)qXQCY;39rSM1bTFylhhzn ziNJ~wNq7_BlV=Z*0=4q_b4wiK3$F$LhSC{wfQH<*>VYE#jJ91kCmN5giBR|L1;lKJ zc8}cyy>)f?Z~}v!VC^iHZS`T05WM~D>cDqw-q9v=jRhucx>@<@E-U5Vw{3i1r7PY| ze}EPmw5Gp(y3QQuKT8cVV)qu=0i?r?@hS$Oi43NOs-gGwz_-*@itt5S}UTPsSMs-DQF>;k9og#vsY zN@nJ%3Q{^iX~t4)Nuh&Nu0W1$0G4N&@#!;;?ptGts9Tv+>$#uq2(v2EWp-o+WEW(X zc;f`L+yuM*7enoWdcvLUxV$`~zj3_b-)|nBueecS?<6x&O_FSEB-q^T#2B7?gJYB^ zslFa>aho^D7S>jH{2;i`!gvNu%(SFkhDG$afkCX|lf~s~M%a>>ymE)d1V85(#cCOx z)vB3byaTBomfA{05QmjeK~Gs2Hr^$R!IcSu`HdH(6m(sZ_s>7dHMV0b)vI?Wbc z$mnB3UNTCg2T~p`KoFQj%r*EFv>Nr!Gc!%vL2|9}-&Q|ZRFE$TfDA`~#GmF4| zR8u8^41>Jn8NT3i%N`2XdcK{sD6%a=Qqz84zuarmwmWE72c_v6!xRHggG#z6XcKAo z4cov<3m(N#B2wgo0Fbd!7lG>QG0Xw0&)C{d zAiiqs9==|TIYgh1gH8Lm33S0ByMoOS)c2hqr4ety?^Nt1Z_ z4*3BF?IfZ^nGwX@=V1&y6ESO=!KT5Qh^u~0m8C&4+^h_3z)| z_c}w`ke_oH+vD)I*V3rHUwDJ1KlIcbEutn>5Y3dszTtx1ODEx+Edem!B`e#54Qo`O{K4OJdZLZN zeb=%z-!tm}rXu)r@wlt_>oavlr>N)Jc2#r$Zj01;HaE(lUh%`LY5^3&JAN5V!fa z^YBcw%Q=_^@VXOn+~EczRye)1Pk zR0GD0eK^%Iz^qLPS4U87#M1;$km1{zSvI#Tb@P=*$ey?!6WU!-33GWN8V=6kD)N%^ z6QkQmVE?nFbib0WkXCkc!sO9WcI>?*1Gg9$_KP9v9n04{Ao&=DNP&N+vp(`OA=IcO#gFJ$7bI)i||Y$f=w31Ip8s{8tU zP7RoARa`vlta&qdqc0D3nQ*pSe1!&uWuJ?HKM^Met|}oJo6#v?{0Fy4;(cHHt_7K< zwP?hFb1xK;CU=b@Js96v!nNpu;pgIfrZrz>g=e#vj0Y^F`8m;G|7F3h8EWrBBn zi~PY1iAsSRZEm7U=2G7FH!)He-)NLan-iItM=C?TS9q4Fr(`h%Nj?skMB0*hpnc{D zx?#!j>{qz`J~UdcTLmsQnIE(cJJkAv_J?}|HF#mhOI}6-Eoa2dcvd3~JMGmM$8drR z80rv939@OqR$HPl5X(Oam;9h-sx2mD^B>0TV&I?v<1UfR5fepNSrLDfE4Yx1EH zSf28i_+nF?7pD4p*e=_`!1THGP9>nM)r{``Fmwv_1h8LU9ho`CnI~g4sjz5)WV2(B zU-kx}+ONax%^`Ede3LQq4-Utyz{Et{g3jv#KVn|CH5c`jFf=xM#l4SFAGH;F3_)=$ z-~vd~l0N{xU!1+z{LBg@+iJ}Zta45aw?&SO24#x_w;MU-9><9Mo5XJtfkR{JZ$tdd zx@2bGTHW%*+H+9=l|j$sN9^j3wA=QgXgkAk^~7zHai1Hs5&fCX)zE9^F8b~==T*o3 z6>hI#pTScl%eZa2K8VL&Zu4Hjuse#tdL`H<3s0ZU9MG8kBI8Am+x+>OrvhrNIZ7ef z>X%@LWK}I&?B(&zT6yqHg2po)GKs5c6hv!fDWk516rMGL#4C-JM3~O_)hV0g0%sS- zzL%Wy!;h>?6W2eRYrX%TcsVg>kE+4Of9-(lGiAVcU@VDlZ@`6L6H1jXS+&N|k&skG znn0L4dDi$rXerd)2nuS=$Ne*A>nAtTINmV~+Q`&rN4LTaCTa7UO^%dOp-gm8DoRfs zZGo>wExl?Hid@6o=ZgQKF_~1V6y`H*rshu`jPgjYN#TC9x^eR7^CXijMCL-E7BP#d`m?!)Xo*Mx{(7iG$kR~Sr?>V|FXC=3E>4vXCk11 zI&mQ?OyiD=oaQ(NZ}WHb_+mAHal)HEe~KA;CxAX?9#!E)4Y!#aVd1VNcoLdr4ENu( z)7d2KD=bEi86@n_-^qO4o{}1;0@v$t6VOme`FDjy*&OtuoO(rna-P z0iID3==#w?P*>hIq&uuWb425ASZbj_1of_3NqDH!;E4tIHJ16f*l&gani?+69$}3L zj3hQ$+(2)-{rhHu)8i}4b(3*U@oI6y_43c|&`U9%`m~?ByFCJ26SmLLWY~}6Zd`;c z`M*DT^zw%K0!aBlH#bE|4{cHb7H7eObP{wQ;HFBl>-|k8^^~hFiGQTKa5q@s3WFWQ z79g8wQOf9lPuM!8n%`?4#9(R!_q@!S-#P+D`!5`cQwi{d<6&c+ zlZdT2=iJH2iUv|Hco(P5G+K|J>q}fTC6-p+@@$Qrg?XnGw!vzeF1dIVp+oE4-rwdk_q?`UF?P+_aCk5&+j*TznB|lNHp{e7i3gVqodt;ot zxU{G#w<)U3mC&mb7cuAcAWn<0bTSP^iY_$as_SToV<%&mxp61iU}aJcZU++(wi5cs z@6x&Nt&ta8Jz^@7U#u_JCacT4n&v~rBu35JI_8whC#L=JG1`Sj&6`xx*qsM_LinS> zL?)Ox6Fd|dVT0Z)=C)aUns=_)Lbs`fb-{j538o8ph(_EE0g3ypYHKoxZb~w?8Hy;*A2?0U z!Ehrhp)yqH#);69S264_7z+|ST>+Jj0%3*9uzxPifw=6MLUoz>B%q%x%B>?pi+Hb( zgK2pwx|ou9E-g)-zZV)@<|2?d$sz0?FYGIGTa06dx5E7_ocW?HfC~}B-L$B_JnyTF zr%u|LtKU!_ZnJ6gHjI*bmjt}6RtA9vgB8PxhO|1swGOErn(o(MF z?$AS-n^JjYJ@p+uRUXd^pvFO>RNuh&8%s4Td73(F>An=MI=xxMOh_R0QTu+4SM2qo&sQPo2I8p{E`1vk0GE;oFR|wbD`G(CH-mPx6klK zTgH|N2T3d0F1%Ep(E*Wyq66hgv=3+!M9?corlqgNp`N~{an{QDVz?;fIQ4BSu8O8slPmO z=d0kfwhN)D!>E9|KxI@^$VP%s6|9ke35bj+)vN+vz(-_t$_;xe_oS3Ns31?jBMg*XV z|Eh{GySFZx3OG7uz@kcCOm>G{$wjBzU(w8T!%%&-tpZkBw1jMkTYwHpm7moeS%kP& zY%3@H#jE%E3Pumb3{X-JyK%8%=n7cg!gu4t3Ip~u_qqxWt9W8a@_?SJF9)sED?UdO zWBInlW+PGInCba%C35@7?vie!q;Z3$Fdi@LNTFfAVg%+L33PV+uo?zQIs&9Eh(mzM zhr5)$!uI@aG2<#`X|Z{VRxK>dA1uk^j+uT@!08iWThix|ZZFH=+LOGo50l%h~224JhG zO}%RDVXB5Ey1}y=+JM#3SRlI9drOK0kBmBD zG+Km7;(D3D^_oC^C>SZN`vhF&HCY$zh5JV=cuo*UUEjR1bGlTS-@@@Flgk77v1J?L4CCX*P6E%%C$F6N# zr>u!yh?dR(>&2-n-*k5n(>M@8fI&jzNVx0gZ=4_0kDMPccxx?g8oUesqqfWv<{WVX zTQihAV$~#ch3f|JuPpLdcnNrBGE6kVssBgM4dUx#Fz$D(?F)boi+Z2?Bw9Inf9lDz zBP!iLtH_qR4m(hH-K%n`iF2BaX)SR3y`?;Y!7}KNK^oUk4{coIgb1dV;Mg>;t}YJ1}0weD$L>0ql2ejOD)=8322e z{T|*^E)EdipWRE^BK&UkE$dcJ)tFWBHlWfY9&-vZ8Pp!f1>xg(racIn@AmL`1FKpX z^U|h~Vrw({AEg`z#bmilAArbe!x_Z5E+cWDv(@5JaJA-`Mpf|gH4a{UzReHW(07P$ z1Uas8xxx^gap5B3X^~n{gvDJEYg&zxUAL-269n7knVU$Uc4^YLjQ7);z`qEG!AQ;E z-}N27lfBJJ{XBfm`_QJjbH2Ns1`kbEz9nhhtG^2KODd>9wNSS;(Q02l;jIr{4JEq( ze+LkSXfaFKS1i;8L{c*(Zx6#+qI)%Wcw^A0B)~9wDm+&5U@!1OPatBNYzWTQSbpj5 z?|z1#VE%+Mw4>EPm+q13SJIy}2OaLtxR<1>zyN%P7j)pW>bR=CzQN&?uD(kS!6!qhmZQfqpm{MOP;z@idDv6s&89(F&>VK!<9 z$5nWEsJA5e9UQJYf*v6Ej1UOnqu&#nT_G_b9M2cIf_TD_yy5QEU?F>`ECCM7GE$B6 zV8530A^S_XZxIpK@;Br7%zW2I$RNwD^aThZv~`CrtP#rw0J~!RrKtNrqPz@sLR3XUbZS}K`-rTLz~2|~WH zIZXqSB>n7O3N^Jnf(sGMis$v2@?UyuY zBUii9+}bP*;gRMCRb?>18E>Yzgps8{j0n#!qx?z7%T2IitWCHMgzfSn(%0!Zp05>M zt{IWL+@!E$;Cd@Y!om-dSfV9<;!vtQZ^oIr8F!u`1UOl^176j7X*jQ*?1mo$>t?RZ zj1CG5Sp0x@;Tdel-@Qpy>!oDH)&b_LK!LP?-UYZxtr}wF^BEBb8G_D=ttB3J1NtF1 zaL;4JY#P4Uf~!SZq&B4nTZz`jklQIK12bPjK??0@g8D~qq4 zy19?w(h_ajZXb><9@u5pvxFEaz1K7y9p-p;y8kPWj|0vD^9z-+_^88W7GNi`-_D>6 z4lc^=Rn7dJM^ldsM0s$d~JtVZQS0o+>0S`2Mw(pV~O~M)HRG zZozP!weKdfJ^*1Yar+SFUjgb3i10fa&flLzKlXJPOj1L7e%x5s5_R-kQji>U)c8r& z5L=WgCMpe_`c=sp@Bt;5ViL*uK!sQ0++XB`yV{=-uclPDb9A17 zQ(}xekUf0b;jZdc5f=E2WjzeepB2vL8m@VqDl@y72{=0%w?x93+A-`^1?_0s-?U2HWeFNl zQalRUCcN+)0$XqdrWfo2H<-0ljyzx^HKlRKtamn+N`!tx2Mn>`*=%76JdlNE`Lb4^ z4&ruO?9w>JeWfw?7AN6gku^AriW_ZoZ`51-WVh#dIGzfFS%G*)w!K4{XBU6j;5G~WA~5iT4QF%Wmq6%1Ku^R!~~tr?hBd~{szE~UhUab+R^%T!whf6 zhdNv(CsQRH{)qYLS}*s`cJn;nuFz2dAVkNKtPb9u!i7PBcCVK5cgA?hM-S@S$Z*t0+pdP^ZX&u;4P&#TO`im zasSkY(Z5jq;V~$jMqWIuj2`p1y?0)$xhbIV)CWl{P`omR=a)5}WWcEn57F8q+_NrC z@5fU{x+ZBKnHDB5fsWgh7ZYL_ID&YRrqWguK3rJ`il;r`utDMx4D)dz1Nd~hqa&}v z^cV)K#PyyXjR%F*Cmfk%oMl3Bt%DeP4pHS>z&Y9E7BAZaj}a*1vV9s?)`E1$js8_Y zd?|}9iQ^m0VQOEROWZvpwAJto!RJnz}q= zA3LIjzaYM_lC&}CO?X{12^(Cl7p%I$of4K~J@wq~4d4(;^a!@XGYKHLpYH`&sdQU+ z3^RjJ=)TP(X^XyaE<|WZmHvo!&qrgT>aHY&B`>YbBq90+Y&aT>r2{P_y5g}iLvMx5 z41g8$=w66YTyH@J&YzHul2&y#+G?9~9xw_4J$a7V#SusVD8E%lW5j}oFB-}$=4Y)n zt#ZWT_?`|dA0Ix&HbPq)$0O-1F~GpCNHeAunA7dKL?Qble@s}d?}D;SD$?kubtOMY zTfMaxburO=2wn7C$^M@J@8$Gt)ckwo56GX850L+Xd{q8|%Kyq%a5eZ)HXsyj&ZOs}BqQLg&L$n3LI6C0lTp8A=d0QiiNWB$6#SxB$n+AgxGSu5C+BwxisN zd=}}*wRNGq0r?zqBXTox3-SfzR-_l%jbzInlzqtU$Q`-1Z2Ml+@5=Bl4$QJ^P*yQ2!suUp{Kf&Q&aE z4#9*l#DZ9ne53$bg*cFG!Q)gPmJ*b1q%2oogK{l$1tJmjub~S0c)2oHugS@)b25N( zJ+cAWjC>l&mg`V{22n@|X+pwCwzQzc{Xl3%FtZC=kai?nwxawj(t%)D0NarpkdMme zaylMhh8vNak)6orkuM;-kZkEi`9%c1K)3_hi`j{7qdbm0o~wU5CudQf$mu6heh>M6uAcq8r%-4YKK(ghJIr*oY%(i`i`d@PO z|LbGz|1+zbvhTn-gwmYTEjgKO&qEy#3w~G%auTyk9~P05xc~NHDMq=5)*h z!x{wLr2i@vAJZ#ydKJoQWF1nAT!m!IH7El}9kM>x_SaYb`Y)c8|F5#)WBMm^`o^5x zjPlbt{WBf_`5Po#4(8-nP~MxZy{62W4X4OoIH+lHm5&< z@SvgHiQMdTdvJaQg+0m+sh zqr8B;i2MY333(a0h-AyFD1VB)hWsqo_SaVcevb8jMOKhEak*koab8UZp1?Lvl*CP!G z{op3}GH+=lE$?nFK+UqZbf+4r%wyHUUAWA%fme-*h8 z`CH`gkgp-xqEW_?fm}V2lS4UqC?~V;O`?8(u0Hy)_QR;BkTGN&If6_e4NX1+bCy|Cvx@d>nBh@nX7*n<@b>9BXh_z$loJB zK%PVX0r`0O(Z}lZsGmcgN6sTJATJ`z$jitp$VKE;Th{tfx6Z#9s{!;yw@{Qw}`#tZueZ*&c#SggW7d=!s*A|)#s~%1n zfsCjgiHw41+M_Ey$-lo{SRWc&_xNN2Bt&8)MRKHoO=>a?(jq-F!6viPdKP*%$DW;@ z)3N8K=S4xs&EDsnLOd({&-0?}#ZVk2P!gr!1NT&*`)aR5`k@M{=~j#6+st{?L0!~C zeb_W0{nc%6MsJSRXoL2!>8R{Xc2&1~H+pyU(5<(!kFqa000S`ygW;Z`^kLeED@T!I zFc#x50TW>}iR52xdrZ;py1IUx%555^W2TR*3I?A!z0+SZ=>(PF6_ZR9Kb;whRqSBYvXH`{UlD|jN{o^ z`g!dal$Xe>xP}|Jg%CW%6FkLpxaS4^mG;-iYH z9G%}O=8*}Rkrmlslby_gT-tLh^OE^d00mJ9MPO5u^hOEorOC1=r`=vtUfq|h1V2>K z&7N0x^qTbAsEhh&h(_>-O%tW{ru1fLiB`I|QMM)9p@a5LWEXTp58doDdeVENFZyE; zoD;x41ooejY=)DgFk1UqKJXDxjl zHtDvR+=8vzx05@tQ~NHZy?-}-4-Vomj=<(9c?`$3pCnJ=G|u82F5n_A;WDn^I&Q%^ zxBuBg*ze*Y9_iU*@|pT`TjBCyp{6nFvXc99~EPn^a1EmyAbxWYV5hnN4Z0%}LLT{3w7z zuqjGXP-)01eRu&Cnbz z&=RfC8a8c|ZOL}%h)(E?uIPsD=z-qoi~g_~LqQ!_!YYU4gYcH@9_JBJrW@?k{~IP!^TUQicAB3 z&9Fy$WQ2P%)3Z2s_dP4OZ2#PIu;+sPT1A_DWPTJtK@^5fQPLYFwA-yDy$pO%PWST4 z3S?ze)o!n^Mz5j07Fip0P!D_$FOP<3j3#Ibo94=vWE-^A-k$8N-j(d8Ztv-?-otV0 zMem0J7>oeeFJBsl5g3Wl7>@~X&P45#9QQ!_6im}?x^j+ko^qkmK5r3yF_vLDR)Jr; z=CKBAu?`!t1;Mb{MsCM0?Yqf6*o%WWj3YRX)37;5Uce>ocDq8qhU>VY`z`XedI)(B z5AX<&Ve^!Hju&`^*RXk`d`rH=M|{N({09G7%_9`TAS@!nCNdcXQ4tN%;R*Nf`x!i9 zA{OExF5)8r5+N~?AQ_Uw3n`Hb>5v6kkq!3S_H)7}mog8TSKaRU=><_3MNkaI;f<0g z4ZgFghY!l30(?;!eyD;PsD(PHi~48;f7mo8o1ht5q7_=hrk&Dy2YM%T)~zeqUA+g{ z6TQ$|w?1S)^v6I9#t;m}Fbu~C*o-7csk<(&AIEVUulq!D5+-AcZqtL7J~rL)IO z%))HU!F(*hLO5rU_QlF2z-gS(?X2<~c^;Q>MYn6@b=<&B-EJ$Lf1NwrLUg}N z-gCU>q531`WAX`};RRmeHQwSKY(6MIDnFCo@DsoA8=?4Z%b^hlVPO-F43CJ21b(6L ze-mBZlZ*v^Gq^{5Btl{&MKYuW-^Ift4Q$eq>5v{7kP%tHZ(I0pa?o=k7jh#%3ZNit z3X?@pOnY(C8>LVdrl)eKvg#=3<`XZm*lqzCgD{|J#0?s(RN-V1%u4+Ag=gAssX7>-eJ&sh3+OvGfz-JS=sPr)<<>DhF02IgR% zZu7~7Sd1lDiWOLiRdCK4?Q6+(SdWd^j9}PoCwHjZzLUNSyLH>6+(+)mLGAY1!}KFK zieosAlQ@ObusK7XRX?XZue?BB!e#AOmAA;->aI_5{dnh}+gbTiGI=lTMzgW84cV4oI zL&imXBtRl0flV^fOFgABjWQjXQ9Tox1zEv23HUp?$-Kyqf+z%=!bBZoUQo5HR z%c_?nE1;rwUu7k-GW<|gw`xlJT$}3JYyNYuqrE=a01X|_8`1q8dlPz7?Jbq9$+l>x zy*=4cy%X6PUCMZw9|K@BNI94cz%cE@$&nb1vAT^@jwdHzA|_!nYy!z3^;yc< z#+fw5Dc5G%FI0E+^r61FN zoIK%pc8Y!mXK@baVRMnZf~&ZO>$riNxP?0i!CgGSL)bheU#Pn-{QaW#H{^TukIGNv zXMDqV{K6mD@4yTN_k^KGbnKDoQ4tNEhynM+RF6Z(MLfjU&0dq3o(w6F3aOC>>5v}( zPDb4_lUdYrDES5te-L%`SC%qT?IBxyu12E8Wv)2x0572E0 zISj+Kk03{348~$2Cc`F>oPw#Ch9JzqOw7V;*vuj4VLldM5!|!b(U+;OBv)gN_Vwfj zY{C`6<*^FY~Cv0kssARlV9)yKk*CB2^F1x4nr8YC%mIaaP&y@$cTcd zx<^xbk}(k%@sR*FiO9t2Nt8*+cWq%CgFeWF`2aCTgKJ>cKq?>5a8FC7YuKTI$w{Y>hT(hxV}PKz3B` zqU@^dM)pv**Y>3MMt|J~kOMJT`w(&{hG95HU?fIi493A`JUIaqF&TlF0-LGiG)&iS zw;A-An2ouZhXq)KrEt%3^_7m>YWiC38yxqI>YK@6Y{fS0fXyCqFZSaA4&gA4!#O9| zPdaXA=;s{!dHMxh#1-AIlGkwqH*pIgxC@(msjNAfei zXt&S%rv8KcjZmI;bxmk`ScF3aL_}mnK~zLTba)~rVk0i%BLNa236dfiypR$$smL_y z8I*RYc6&`fdVlQ$ z9QT3r!3e-G4994U!FWu9O`vj$aw<6uL70J=u$e{9#vIJU5-h_Cti&4FtR>f}ZzMNi zGq&jFdKF(Y>|3!7JFyGy*+butgE*x7Ve%+W;3Q7tENspzFOU~;372sd*Kq?kaT_79 zd7yM{t{)$9d!qYO7an|5`2VJex;I$@B~c1KD2MW}sYv>wGW<{# zHr2=)sExX)hx)MLn|}YV@n>(WTN7ndvISbA6 zty_O`fchYEFos~LZuY)m^x@h^kR#Pck)tsV6LgzI2Eu;xnoSTn6LY|~s`r?O`B(s( zg~~O06?>buE(IDkVq0-K}Cdti0GotlVkFU?luQmU?R?Yy zzmtYci;T#G%&^HqW<_@7Ku+XB9^^v-6h;vgMKKhIH%h>!6j>TRD2wuNP6c-Uupf`g zy89`skk!;{D&6m^#axE!AyrMQ@FE=zuQhhMwpR_w-Tk zPYy(Y_Mzl(^%2UEyxcYodrZmX~wYq1Xh&U$Veuo0UOjP2No-PnWuI0%~~)xKaDev`#Jh~ zT)<^q#dX|(%}w$aLbN|1pWr!O;1youE#BchY(A2o@daOXb3Nf}iv2r&;txW_;_C01qQX?(W zBO`1wlUb1s*>%gQbiIPFEA~9PQd_8~zj~kMioiO1oEa^s4k~+N+Z_ zP*c0T)~5D9yX(r=7k9o5v`0hu>otwZChGROru61$g*Ir54(JH?bfR}gSKYdkJ=J?D z`zq}{{nZDMgD@BY7y+A+W4!hW6oE?rgAPhUwr|&P~G)c z;cJY2F_vLDR$>*_U_CZq6KuASTh+IbJJs#kZu(yA!+spZAsogL9K#9NoFq@-G|uRD zmOQV1nY^NYmAsDI+V7BeaS!)(d!T$sKEh)>)9oesTHWLd= zi9ZMxo1drP9=-+Se-lAHA{iM`v_~bQA-Z-?CEsuO@5CfysmCVcA%XTp%EV+6B-5Up z^g>GQ_CcxWsgXvv49YCZtYmiN&~ER^NzbJ{FPR?&v=<}`tJ`afIJ)gc|JjRaFYdT| z(@UTCw#w1iD-vaNbMvI9D5?@V?> zcl1IZ^hJLR1iv-iV=w|R1U5sJ!^jaBrQP+^_2U?B<8+@uPISCxvZGI-2Wg+KoS~dW z&c+Pu}rrWlWR&lH1g`D|e7Pu}Awp@&FFv zFplCFj^iZG;2bW%<|26sS8x?Ka0@nf$PnDcJ>Bk;57ZwkU9bM%KR(g37vxL4a=iA9 z`djinKH;lw-^d^MiC_4QKd=eKH~ZsTWO;-^ScHR(eG|Y4>il5`9+43RQ4tL`o+RIY z!y^`ABR&!#F>I14lPm3(f}RSgkp}6I5t)z~S>T?mj&8Rc>^YIkanDW9t34l?9|g4+ zA`7D!ymfPbc1iY9C<7mqgL5jf`~GvQ#O{ZxsHSJN$l9obx~Pu^Xas*WK~uP=xudtD zx7Oa4Y>$rGJCR+{9X)jGN%lq`48R}+z-A~pT-|lyYm|Mg<2H^yUi$=PpfZS@iP@N= z+dSoba-q6?_991LPG5mlj@ugb_2dR@L9lN2{;lfU9Jk%{z1WBSx*t#;B#)}w`)!V~ zpU~|zc?RcjUN?KqB}c!aeqDK!48a3D!ecyzd!Ex@IQBP={+9mUv45a{!WYNQKIg0U zZ{&CU)c%Y7gHUl@f3+}VScFGJ-6D}u5mP&V)VW6-#Mho!nS@LV{#2R2lY&f%)JTK$ z$ON0rWOn34F62fY*yL5_Q`#-RqZe@Wg7m^DhT z96R6U+M_C}=~kVrp>FS~MX!Upy46!QP}*z!=}ojZBU_*)TA?l4qa$oOlU>xikv-5$ zyFKqs@1wmxIneRUo)2OltXqI`2ssqPwcG1#MzW8>XpF;n*i0ZNVlo0T1vb;j>6nGt zm;>j`WuK1)x-TRbsV^p%s=ME_O#5=>DsnZ}V4ZI3$qm?uP1p>ZZRB?B&~CR~^xfEt z{Wt`h!{jlX)NZ%4>gSXf$V-mr_L|G=S8yFS_3W0?p5Io#4Gm)8*MSE5<2XZ41@*+QM3MdPbg-}F$QPLYFw3j4H z!v|$i5x)3$Dsl7Ey((E9wY1kJ>#Ely{n1o=GqSn5eP#=KOSIOl4cT731KCl%6WJME z&=uX`o*wGG$-d~10T>9ILF8ZrUEN%6a5M z^~K61O8bnZ^i^1cwOEf0u-T;COm0yRR&G;nSMDHpsqZECsoUoqpdZwJh&+sAIDykR z2b=Rs*T&zcvR~5evhpf zz&%yftC7`FLwjAa9_ph3{LvK6&>XE`(^~1;_~$?Nj{n^3Sto8?&<#EGyeHWkeb5*E zFaU!v7y%dpo1x@zjKD~Y#Y9Yk&15nVQ!o|NU^9c9iCLJ9xtI@|1>_quaileGm3xpPun8b^p#m@{sxwr9C*Veo}dg zJdJZWk4tdQW%et$s{1v^^Xv2*j{Oe(F7Dwz9^w(6z~(9W60h(YZ}1j2@09P!PwK8G z|NFPFbE6#hSmJ>Ivx>V6OoLJD2S$;CmBPXKPm3- z#8So~<01hPAvsbY71AOjG9fdvAS-OLDXr(A=R_{#Ltzv_QMji#-CKJJWl6G(dO5N@ zDrv7w`k^YSqb6#h4(h=@_34eY`;$%49IbV0qjbN%t@d_~dq;X_bknUn*#kYb+k1P_ z`)Kb^4p1LN4pt9P4k3qPg!a)&`B>H6Sf#eiS!%WP^T+G7) zEW&cEgv~1DdU69cY2U20*96nIVLNs@?z`x_weKPKVm}Vx5RSm+D0xi%Bza2xGs&69X&Tak7LhA&yNDS6(S3(7gZKl+6R`PmqcmDt&F4FYkahqRhA>m!&iGH z(hpU%S0$^Vx_0}F8tS!_waGf_b(QwIdi45e0Dm+_6EuZQGqMF*qP1>qmF>um=%U?T z-_6l&cTac6y$8Lw_I_l448ULvg?mQOM`|BMj>RPH_L|A+f#g(7(;h@l#|-VW$l2=i z$ocB_84DbJA$_s-W#n?K#A>X;2DoPA;~r1~lHG|p*vy~Fk6McpoumvKe=b@B#o;Wq9d1b1O`kGziuc!)=Mf~T-~PQJt| z?RI-d|A5c6rD*fdjGZ%%KC*1EMJ+oGNJPGo0wdwmyrH*`l&^g(~v z3?zqOsCK&zqmRTWjK(;O#{^8oWY`3fQ!x!QFbi{GGoM_jzKC3mC0MH4a^(tgt-8H$ z9esmi-$dVnU~F~V?X}z3w__)EVK4UMAP(UuY>p{i8~;4VehO!C9v5*1*Kh;wxlIqj zT|C5NJcZ43@(teNJwD(gY(A4;@eM!l6Tjh+`0rzn&}2A-M+8JfWJEzUL`MwR#8Spq z#!)696CsKAWMp!9X-`F_L0awhS?L@-Jv}2bBb(!%ot_i9kQe#jp8WIz+6yWRkws8k zyEj<^rL_ByMjCz3}h!;nr98{^S7lf#e_zMu2X^l=c}T=p!)-V=x{QF$sZ~is_h* zxv-h9w7!785R0%x_oYgEzRb~AsIPR~R@2vLUrVl2Ur%nv7VW|0R&2v|-R$#s(05}G z_B!tN%w`|A{Wz#+N62G1uKgr=2Ip}B7jX&y&Sh@bbiYa7!fo6^2%K}5{l0Dwm5-E< z$)|X({RR0--9Fa6N!oVgx8A09li1bK^f~bzWJ@aIb ziMWX8c$R>k5Q&gP_oQSp_2i@%Qff~_rc+N(W#D#K5=D$1(LYRc+lP1Hhd)InX?G$0$oA5G8{&CvoaVbg|et8RM- zdPj6ZXLLa~bVpD0LT~g(0ES>FhGQhgVLT?lW}V8RinY^NYjl7Oq2*EwL=RW$<)2blt_itNQ?Bygv_wX zs?0{_LT=7M zfK5y?HsT__Zgx-L=n2)6kV%nDdvY=bQfjyNrJ|=rdfhURnUDopkqtIE$ehTHJi6sm zx?aK8r1nB&VHAV6ZY9W)D2+1kK?V4t5-P(FRZtcGP7Q7~b+4tYt*oc4uWU&Aqp|iT zWK%RlbKP2ztt+Gl(3D;TVZg7!8}T9n%)@*vz#=Th5-fvzmaDID+*Z<8V-40~9oAz5HeoYtwvfTt zs(m}TQ+=0mw{kyu00(g#C-Lu`*6j>=4(D+Jmtb?5yn<`EjvKg%TL{5@JitRd!wbB^ zYrKQa2l5j>;|spwJAUEc`D3@_u4^bVG{Pbr!XpAA!99^3JqkUVWA~)T(jJ?PgSgu5 z{qfWjl1afIk?xTKDUk|kkRBP32{xIP*~sk3rQM$8rsqX|$E`5E7>c8W<6f3t9u*un z`wSajZk13OetKSotcq%=j+&^0x~PZxXoyB=44Wp(W@K~qmSiimK}U2(ci8k)_9Abj;Lk7CBpeE;%2Iv@ao-Vi}g}W}m-; zz8dSW(Q)6RzLngjzLVUAJ=*t?`_=8UYz{j1BlKf9q1$QljJoU9{JRVGbGU#@dUjc9 zuen0Mifg)ECvV`k_B&($!lsxPKZl_NN}?1> zqYQjtQ_kyecvK*L)$LN5UPXH~Wp!mur3X`+UeB>Npf_~v9!w+cjmf5Hj+STzn>Jqj zy(Vlrdhs;~o338`^BKCMCwjrApV!~;7(fohAPm89*o^S{8y;iGvFhW=37CXHOu=-_ z#J@9Jw>e6CKF`r@x0&z7&udtSe`l#~%atq1RqAWVwOEJs*nmygj9_fTPV9zr_OS28 zejLJK*c|oZ=QEsu%_%Sb84l-g9v5&4S8x^A;GXO1H^`f~h1&>$%{?!^F7XgHkG=Ss zgnORTU*Hwq;vL@OBmSMw+`ix&zT*deyh=<8;}jr2u;uwHqFQu>MhCEXs5ls(q7lW(L2#QqYJv~-kt1; zKIn%*7z~>LayUj|EXH9XCLs`0Fcm?Vj@g)lxv*J4E>vGaF2f3})NK{H2J5jATd@t> zu?Kr$v!6VuewaLlD@(aG<2Y%uge&Y{pLZ{^ar{SKk^l;iEkdY7t(RA}9W2na@V!TqW!5@ub(^P4_IlUEHJ8pKjX{TFzvI9DzGrFKB zdZRD;p+5#=2;4J_J{%)3Quk5hSd7DXOoYv3GEjXgISoOWq1#MyHs)d;7GNosVFgyg zJ*ymjHGPftb>w<%z$V=`lfmlt{%!Q_*x|VCr0;d?`{?^|00(ghhjA3gVRMo^rGADy ztA2sJsBW*jOuwT2DtR3@aSI{12b=rK2joNbN91EX!BafL3%KW%`Wxk2@;yG_6F%cB zzQN{)^0)Gj(j%4Yx&0WL9v0yc0TB@ikzo@>X+1hU24W!|;v)eP!X`196kbTFTPiXQ z(jh%E;{TdVx@T2pBXb}(^6HjPS%55zBHD|Q#nrvZk|?d+{nskPUJeydQO|tIN~nVB zsDV1Lsi$l}`lB(LqB;JZmfTvQHQJypI-(Og!=@YA9X+)7RQ4kKpfCFAX0Pv0AEiN{(al~nRXs>KgPe&u+UF`4kPFrAeT&o=lS{A^%drBh zV6&QBi*?%9D>o`PlUvlclH1g`lRK~zyRjGhV6&e*pni}%hT}Maldw6hJV#!{W$mt~ zd>yi1bKGvyZz05Sv)A5ZzmErasArGJC+bg??$3R}{#v&;j%RP_@3ntaeo}rWzv4T7 z;1}EzDz&SHA;TgZA|N6nAu?>DDy>JOM+blAut!Y9Mm!`yLL`QJlF*Yob}#i5WNP)a zWIAL-CS*odxF?%>PBIVjI-cdD7eEmdLvfTqNtA&PY|1IilNC@AzPeRX`jJ)DYmhZj z3$=B#PNi~4BbxZATv?2XX`&GoD$*&1!p4((ynf$XT>ne2kD=z(77hyJh`s2ofN zU?_&^HbOay9F4IUuiFH2A_6fD(=iisU^7oSpInGVSgM;nU#7l7xr$tkwb+1-*o4gp zhRs%T8+Kr)ZhOfCIHdguc~t$F@;G?{r?tC2?SKDx*758d{et$3n+{PW) zgpd#LQ2QhDiTYFJE9GnQ9p2-!ZePf+_>LdC{Um>>{~<%Aas9O-kP#6HQ4kf;5Ci|$ z#Nr-T&k`sTl8KO5donUPytLcrq@t(Ro{r4uc$S%-1=$?89O}8q+{lCcx;g)M6?WW; z(2Jvlv~jaxs=-1y*7eY}S(NupS$+1;N;gZP(ht>81GV9vy6W{DxBB#k+8dKi&>St$3O23Dw&;M4=!7n?=|=WYx4kF5H~ONV z?){Ym$-xM~Fbu~CjKpY+fqTZ%$7`QV1|kSEFcY&e7Yncmi?Iwg%gGg3iB(vOby$xL z*oe&t##U^@ZtR84e)1p=X+J_9#c}QSniKSsIE{0-h=1n_x9hlt+qesx`%3GN=#L${ z-JY;N#WOs|3%rDLUa`M++}_aN;XOX#3v9kAzmq@lOS?V$Z9N@7Hz5qdBLZxqkkQm_ zkKyRHyCGBcSK*^nJMVUvr@g90e1TVZ7p zrM<2gy*Nsv417=)Ra8e!)J9#{)FbPo0sPSzP0$oJ&B*3xfmXV; zQMM<$sJmXx-_NmkLl511lD*Jddq1*21|UGUVdMym#u$vlM7U=%JrGk7gz2!EMb5(l z?TeK5Y_a+h|0q?Kn>06wcr*&fx;wbJ5Z5c1inX@|yY$@)m9*1ovEk!S_y)0P{6;KhrsD#R>ifX71_ta3YN!CVP?G4CA>h9MzW^aOK zx;H0Vp^f&oN_%~KdM9*s-0a?sy(fC3FZy910$?+g9EOn?gYmGLNKR6pOa@{qf-nPf zFc%B3817k0Uxt-ft@|3~I&y>hM&)MZR&tyAF6AC_FAiuwNFKp)oWvQN#W`GndoHS9 zQeIYGC9kR9ByZym?%_Uc9w;9xpDFFxb4Pzcf92Ti`D^X(l^-0>KhnS8n{MC9U+RCz zP#NqK`1ginSoLtq@MJ_p)*eL}m5dHg#6V2Mf=z5P0TOCYOeTky_LO95q}85InSsoR zOxiP(S=6&DbC9{!^N{&a00mJ9g;5kX#gxTKZ?KOSqeYN)^ z2O5b4nW&tsoT9X6Q`M)D)757Uf8uxCdO zeGSwbD*YYL?0IAMrf9Bv3$i6zp)J~@GrFJ$dZ9P^q96LhW&k+|LoiG?yN{rc#2DSi zDJPPXFd0)Y6+xJRnV5w+mgi?BqurQ|X!$7-y>I;_VgxMvGJ7~8M|yRaL3 zV6&e*j3YRP<2ZrSI0NULWj~J#xTI&7mDiLvmG1Z5V!wlXc!0-v0{1+nKiB?3`AYeQ z{D6=6q?^6(EBzb3>-LlUh2QvtP?`8TLKxVDCnF#tA|ooIBL>_P)6rw8$5kdI6C(*y zASKcu9Wo#zGQmBW>DiG3IguNA;GDeL^O5;c00mJPMPO5u^hQaP)~yWbgRybl zmEZ@Ps$?}(M@`g%O>MG18lVvx!=@S8QoS|V7VWgVUctY^VDF4>=%HslmG0N{(%y&c zj{z8{+aNLkL$wbhM`D!rG2~c`#{^8oBuqviY^IRY5QOQNfti>En|b6yEXEQn#d55M z&06I;aw9fjvu?rUR_xHeOSzlehy6H&!#E0?W8?{(#3`J?S=gLYUQk{nFR5Q9uiz@K z;Rf7ulYR$xaUTz1^O$_9?z-^v4*M&-aopcJ`aAWHxykpKyGv(HGZo`g(_Wbi@?{QoAko~3iVCWCrr zG7GXHJ8~c=a=|7KnI8pF7)4PW-Y5Z^Qp(a~8Te>-J>_eTy_{|pNncdfUPWoItxB)v z*lW;hYOk%VN7h$&f4*e{ZjIoN=4gSIa8E1s*2*?ydvroq-R!m9={?X3y>;)S>`V5? z0PTa7_P!zXp%{*lj{6w;SjRq&J{}V=QTIt?Af{@crnJv>PY|~my3ZtMW3Kjj2u|WO zY|fJB)h{S7Dld^&a23~a3%6ktqO^Wb{So;@{RR0FukaS{@BtrT^F{eh>ALdu%l=EZ z-_B=Q_*zD2goRBwGQ4_3GBTpWQ@0poEW|-P#76=oL}DaCQY42LQXn4?L z9^A9Q(HE&NCYNFbR$>)wR+DShZC|gxS-C|SOm4*v?7;yX!eJbP%}MeU&fpx*!#$Vi zmvI%>9Cv$uOZ#nQi1HqJU;Tmd5&0C)@e*(F7VqJn5A=_Y{S*DO_Alf&{J<~##vgcO z<>xEdL{LT~BO?l;>J~#8i;S%vmyCz_+7l`hkxA5(lF5()DUk}PVUt#wp3I=0QR#Yx z>&ML8vLd_VSx!gKMbE8051CIrzp?;XP`waY6vg32TuqjKHQ!lTydj)z$_@WZ3 zq8e(VHtN7V4d@NwkH(IB6M9p$Kug`*knPZ3dq=VpI-`qjJ;`3`eaOD*{mB6ssC_UQ zpgxowhT#~Y+emU0#$udqlgP=KqTT*)m`b09AWX*$*vus7V6OK0-EIfzhjA3gaRN3c$PJ=j02#)NZeRMStzs-_bwdBR=W=h5U-|_<^7J4Vyof z+5T3KP|DC`IQ0l*MD@tZsAM$t=%goNAQs}nCV?^`nONQKN$5$D49Vez6i5a4q@$#EYLp}KB0 z$eO65y)Ic#y#d)s-Cx;Q*+kilY>pP%Tas3CP4c*ZbHoeI{ z=!XHi4I&4t+iQlczFN7?@q7b)llINz76fA}wqZNmvy;9HyRk?2y~=&$0rjKGW8`t1 z#3|iQljm>|mvy^JUdIjG#2tj-J|5x;p2FrC`CR=4`BL4Uy`jIw2i-oBpYR<&?UvnM z^*CVlVn_a zyFHum&u+KL+yXHb(-4H|n1R`tgSnUwn}y^eb=QTT|Jax4wv=3sl~|2+uvxF%KyFsI z`&Rlc?7?2_hs^<{^@H?7IE-UBh0{2T^RT(Byhh%{ZG_-1?!h?^*&pK>Ug8y;^G5qS z@;yG_BR=6PzQa8~9Q_ylx9vIj=O@^NR)!_RsoOm~Jrbhm7M=7&48%el#6>)~Cm}tN zV^2&^rrnE7fs{yvv`7b=^kfG0%u2gwrDxNglg#CKmYbdj1spefPeJxVD5`sL$MX`7 zUW#5CW#Hqu+h>$@?B&#b$x5h_K|l1z01U(+*bF9zVz~B^%2DJP^|9nQOwc}&oTMH| zPQg^|)5su9*Y5hO@O7zuw&OmBJ`eM;SofvmGAzeR-Rv_~(bqWk4fKuJf?#Zgd$!TH zJN6y)-P-q%`*8?|bvr^HRkzPLNk5HqIFC!Xj4QCYMqbAa+|un18KQ2lxlezHM|h(9 zQ{{8=h5AeK72e@JKEmd+@|*Iz()E_9pwFANpee z24WBfV+e*~Bt~Hj#$zIECX-Vz71I!e>6iic%%so8TrALiA-Pz63Aq%@upBF}3hr4$ zUx$slZ6Y_T2P?Od+tqiHyRc9D0i}K3LHZ#a#!(!@ah$+O*qkQM;4IGJJTBlOY%Y;k zaUC~s3n93N$9MvpXXJBr+h5RM;FaZ-`Gg%o(PQg@6Ll9eFt{xzMI^K1KJNM4=az5M{x|taRMiC3a4=f7jOyJU~_}K zg*)0q$a{FG{W19rFYyX*@D}gz9-r|Q-|-Wna`SbCaBxoqdL-?U$tZ}5=<(+i@A<5tws zi_^VP0wo=Hdv9s>GLBn$dIiT`QQeoUr0z#nK{eDwE!0Il{5$ozHPF40(w}UK=Gt2* zTPp1{TG890JvyQ@y27TLvX`t?T+sXmLGtG<9-h{afnNm;TxTF0pc^{9o+j}3YKT$p-U#Pz% zU*V1Rx8!?##An^Ukl*kfKkb&sK9#RKWjHb-A|W!OB04-_6O)Xk9#O^#(=h|Hbel`g!+b2n61Zm>eYy4(AsogL9K~^*fX!+0jQUyfoccxb z5-#HkuHqW5<0fw79-Q+)`y=IJ@(G@5cfR%+x97UQAYVFO^V-qh(BI*`ZlB06_=fNJ zh2IF3*Y)Y4$uJ0y2#5-s=t@szOr`57Utii|lW`Ci@sSXTkQg>emC48yNQKl$3!C(0 z2K9_&CS*nyWP?q1Wlk~|@*+P9pfHM{C~UmR66&^>q?bZzltnp|M@9I;4^>bVHZ{oF zsEc~2j|ON6n?|I+y6eK%q4uU^3&*oo^wwyDcDlD$b|5>UGrFKFx}iIIqaSPrDhH8+ z5rCn(+4EtJK8ijXV=xZm;hqWfi3rqfDj9_7n1$Jx3!4SxLiI(;CFC+J$12^{kn6A> z8?XsmuoX7j$sO2$+bYuo((w>>jf~?4B$KglvlD+U@-< z=q(+4YkFIBaNIi4yPz9-=-yM=o9u`F7@*rga*(?HH3q8>C5NdGCr4l;#$X&KV+y8X z8f=2d>6n4pm;;-+&T-AADeapjb*>Kk6%URjD?UXnTsg%P%>0ziUv&@NRlB`R7eskk)c6Jk|volgiuJ4 zA!CXpk|87_)Bm`hzSi&l@AaN*eH_PmUe~R6y=&d;>DhY^!VnC@Zy1Gf_zTl81G7M< zhQIp(JutvRUsK2t>#(h7>1#IdTQafjlSxHLH+H zq$?v;U@fSD2F#5Xx-RH}KDlo|8j@~A(ipiBHj$nByeUnmc6033um!e)9nj7;>^sTL z9=VJ3J;=SJ&%M77`vG!0h&)8|{4n|vI10ze-3@u1bZ?{&=_imU!H?{xk!Rp6_(LEB z0X4xS|84mDBH1q@LrD+&pLeKtFXMKF<{p6_3DFP>ac~`O!EK=C4)QMPiOBo#08-!) zJcU$v2I-Ii)MSyQ`g8O=$S1b~nrAQ3OQ00W;0;hyfqVy5WdC=?cMW?D&8;52iR{fJ zKO#TF7qWLCJE4p0-;q7gOZGlwKl~*75b_uNhB0#cgPf+iI{uyq)GRJ3mS4nIO6l2!j}i!*Y-WYF3bxM#__}h+GY8U@fSF255mU ztOtEC0BSZOH-jmdg9T7yMUv`UNw-DX!FHNwJ4oM2(jK`R_KoWhJJJI@$$lK^1>R(*e$PpCUpND2!5;$P9Gr(>xCmiDO*rxjT!l!u z1~EW8aoDfJ4Y&oj;VvXWGNb@CkC17Q4jGUMS&$7cpa2S?2#VnqltMYYg}Hf$UIo=O zx4CC^ESeK|=< zk}Hr>AOo`GCXZBrm1I{!s=!*Z|N9g0Jt4amNga}UNPW_ckjAhPOu!V(fEr7r6bfPQitKn}q#_)Tu3$UiUve_;}+nIbt$r6#@)FdycIp7e!CMqna4 z3rSWaJL!v%9KZ=&zyrLn1gPOhE(Ia7|GWPCDU91P5Cd_L0BV+#lq5;rR-j9REXaX8 zP@{lc1*<_BR6rHfKofL85A?wR48a(v*@)Z(o52LkfEsg>7D!9dtw>VOZAjlr(iUk4 z+sID6L(LAd+mqal+zb1_0S>?+pvIBpzYX6t?1#ab+>at%Nq0wjfF~RWFQCQ;c@j>M z{S49{&Os2lokw1P5D0}Zpyo0%0;0%%jpVFhJo5Hn>90waA>Tj+yoE}j<~_0+ zYM>TAKm#;F6EwsBH6O{n75Rzgoi_A#_)2q|`+O&E-^jfS`JMD0l0T5W&<{Uh2!>&9 zexZ-T7`aW5oFYlRH%)ade0O01Fu+1!0d`mfTtE#s$;C)M5FooCN$MS8nojMa*d<^& zxl1BffE3xOcVy7zK%U%`kgGwN>}yF{AqHZ} zjru)tq+dtgq`BWhkB8fE2NHmqL}U^?fJcxD&w!c?WF}<6bI1m2a!KYP^Pzz3g(RtW zUZNM1y#)ChO37Y^EGM0Mw*tKqs-cG5Ymtr61kKO_pP&so;XCxg01Uzq48w02g+DM3 zQ!oRw@ZV_TpM$UfsG&zL1V&&cH&!G&>5GsYzzN*282Er6mVyun!!i&7aiB&5xf~=x z3Zy{>yLrjwpQlKPXfNPkW;2bl|b@B#{;7+ymel*1dCo44riX!iH$HBd`# zACL{CHPY2&OSOC<}BN<3%LNWszu#?*&Bqwl_{okkX_f70e$W4Ie*)nu7vM)zU!V0oW zA*DeEWXVk)xsr4xlB@74 zeisrU3GPEOq`*U<<`MD}v^G6S;UIpjhCP*aF}NjkL`p%+65yoPe9fOqg7YM>VC zpaGg-Za$L!nPeNuFC;sV-=GV+$&LDK4|*@nPTdBu50Tq1-G57-$Fa^|1Bj@Sj z`vVL>4I`2nSb?3~IFVeW|9cDnj)t8VmH+MX z)2VmNu$z;c1=0$vVJq0eHrNh3U?)(s2f3GY2jl@b1Ws@ST;M3Ufd_a3HC{*`I0?Sw z_V3BRpQmy2hX4qKb3n~`u>{ZK|I`sJCFd0 zFgHo0KR`Z$$7FwkdR(rkti%kp2!? z2~|)Hb?^Zipb?s&8Cu{Ie1COZp~71)3s76COJdidS}H}C*2P_tMM-#g%kr9h3K9{#Qf z%V2Iq&_#h7F}?rdzaPs{dbYGHmG~Z3%aMsRCoqykPaD;30W{V+2}byO`hI=LHB}W0m(v=FGhmj%xpAKIsdP46qOw$&Crg z0<6G6Zq%o^(79=L9`wb)2mBxaf*=gbKorDaIn0eD`U;v|23;29U?r>qYLt+xVGXPW zHBbi)&;o6sMhB@2>&U(VX#hrGOm3Tyrlgx8Ex-nB!49a|j@$|MunTqrHTy{JM;;{o z5Yh>p$xgj@1pO%4-H{%odn0|o7tVk`1i=Nk2-JiluRtVRBexi2EL?{ha1(9;HMfy> zNdI@icMbbpNQ8Tk3=iNTQ1b}+7*fgp44DQQkVS6Pd(Y8xXm;wBNA`S@g~%c(CVL6; z73rnOa(F{_>hl$(ze83*HPnz>9kLOc$WFcAOnM9Q6SPAoxqU-+K{xb}8}*qV=zU}# zMvl-t`%U^dassAcn%t<*&Y;iI>~!n#&sLZZ)GQ!Lb$WCLU<77h0XCQ$cACBjodY<@ zjT^}Wyub$nAPB-hJ0jRcK@7w}0#<+wP$P?!BYh>we^2oJ!LA5vY3{1%YGhYOYSTQ^ zLDvO6SWk1`K)NB#jruc;ux|ttFavX#8w+$Ru!b$L73^R;?0}tM54(Vx-6W~L5B&ff zB)3CIM>q^Fa1`do9o-X-gBN(i+?+)BgVW@81{p~DIplfLgOL{@3@$+g%uN(}G}&X2 zu@DD0;Wo@o0{UH=JrO+#lF98M@)7AzNv4u~hRlF0cusEF$Q;Op7myDHPzXg(3?=Xi zN`abku>{Zky|{;JIK3`2=^cvQh=IA zB%dNv;TdF*TNW}K^2q-06aRj`Ah&#EArwIgltLL$Q;vK?dIib1$V$?yknf?I>>rTz z&_MP^lGN{NLT@JfN18kJjG9k0w>I>4=zy=}{*B~!OB#3 zF`AvaiT}?oL9lSaye0;~c>m>Xr%Rgh~z71YU1gQPZ67uJD3Yybl=1Zs?s z8(|Zef;m_KHI^i)ZjEk3_N_E`JM^7k54*{IAJT#J{m4V$M0VyRHvZ$LJZ z-h^z1kI+hPpOEeF1v<#BljJv&)Sul&)2Y1&dq24iAb-Lj*{SD4=)cH5f*gZCFb;oV z5~hH5rm@dZHv@dXfSLs)>5&Y;NOl$^E9q=VPSUxNJitr##mFV3Q@@W7T>ym0O_-z@ zQj&COqzuS|0=cb3Dv`b#sZ6>mQk`@Sq$X&AHt2#LtOr9dhPl~D`X;0an1K~o!xo@s zE7A_OlYJ*i>e(*z-LQw;_8}c$KO7*pgCwc<=f>&(xE;pL`G4+5upcEiSL88pBRloG zj?;86(!G%|MnB>!FU_e1QV5C-9J39bM&5y&Xg|6TAs#2!s^ zi$#xv8*r26KKFh+x!opt2bnN4t8BwPwx824PXdHU<@0<1WbV%bCOiI zqUkoIZ$WM)eH+d5ouuzZ?ga;$XZz6)ko_RZ!^k7xLiVF1k0IT_13ck4%#9bi57|#4 zec=oQKoA5&2!uiygu^Ac0#_jtq97WmiACOoJ7iBl-i1U+f@F9A58)9!foDKFX=G0) znSsoN9I{jIz978-SqLwo2#SH4*Cb1k^MA)Obw1o(g-gkTwnf*4S<9JzvYX_Eh*{QD_GbCaX#^5_bn2&+LEs8J!gmZTa| zopddvHt2vZ=)pSBhq>86(+$v#VI$3LGr9?wf(5x-BCWt0>|i_0%?{Fck=#S`Y%lsg zaDe@A5U4qXbcDm;3@$*;QRFdjhvVP{-f$AAIfe9t)8J2T)I9+G9Gr&`xCqpQkqk#( zg3Dx&KwgC?xCYU11E{%$jE4lWQ@6XM-$UMq2V{SUOoeBV2I-Ii)MO!_Lk`({TSG_o~rrpqAX~kxisGlce6GriJXS$WPEl_IBhK_zIoS z4RiAyy$5>9t&ijY$)Cs}(ua}1V1(?ykz??O?BgUSky9`YGcXJDjPX4KMqq-uVWH`) z=xo3a9KZv-umt9YA68p_{phk8r zlG;dJ()Ez*Kp!@cn*q`oHj;fa(u8zVq&ZlS-3n<9Tfvsx?2tQ1r~Yr&S z846)=2`MjCy+F+Xau9}L1b)LPi~}_j$Vt+tkkeG(h<|PYH4Bl9z(RI5lGHPHbPnJI zZs3K*FgHuk`9S~#$$c48l=Qjx#IQ@ia##UUAPq7g2h^-YD#04EuSKeZ255p7XoC*u zf*!1cxiLWB2&P~GmS6>2!4_!84*Pa;+lkyo`X1yyaDe@A5FCM;!$@a10xsnC@5%rB z>5BU?^308-J4p|uCmbic5Ar0OfdB}CV7LGm;SyYhNQio@Btd389o8+ ze8%2RZeNgJX`X*W?}BdlPVPUDeJ}t&VHie$no*K}k&`e(cIw%@P55^eSO9ZFPtzID z8G#8{$eooW8C@5G*5i5u_-HlYKc-5~M&D7~drC?|Ub@-69A$oEhUbx;pYKut69 zBYc9-@CB&pM0SzhjqHIRWdHZZzn{Ih^}!$vljkGIQ5b{2k~mk?cvx`=lo$AHXAc0#D%?qyaUV$Simc*^mR&3^P6?os0M0kkPXlX&F~Rg;WM;BJA46ZI!Jyc*@^6i9{53S z)O)??ePka%4#6<|f)N;nxfw$rhrcjMbDu(=hFR)nitipU03*x|6FM`n06V!aLUIBZ z*}ZO!2rG1L%V|BX%ix-7vU>L7ud?;?lq>1yU91fbDzuhJ75-rrE%oSJmdu7jy7!$D zro0b?9r-R4^(h#23NT^;JtJ_UK?&(f;JE z={x?qUCDiLAvZ(AiB9V4eNL0n;Fv>|Dqo^rb$6w9x;BP-9@E&%@zwg~K!(Os?eQIN z_q{ZT6o_7_<^McP*Fx}s=&ols_BzaqKl_|cRrIX>(o6gOa~Irx%Wf9fH70bQgFR7x zgN(Yfe#h1~Nk;z80pCO0*OV!rH#gT)I6M`zZNbaCed`Kkc=PQ%8_N?cAVT^%2f5TCs^|K8cvZH8kzweB1@7J zzDUPyKer+*_n_g~%!WNO)2T^YRs^YSlD3aly!O|x#_z-tdewV^+Sig9Sb1{Yb~49= zR9o<}6sNa-3mptfKIP?fwG<8CJT!lw@l_%xHDESdereZ!}P$9 z=c4Ca$_6jg#imWbHu`{trZ5>Rvo7E3!PW^ zYnSrpceSZE=QEh_ne;prZrhoC!J}%smJ8dtmzPaknZna%#zGBm75r99G4dK>a~5I> zImR)VqFh@uv6xOWGvQl++>#;Lp7_^)uYVj_I$HmDm8cQZ?oXc%JYH^4ka{6iWyJdA zEk%L5@|Q&0HeEfY9GSY5Jpt1$!R2KDm}wRShp2JaSJGN9;RA(_R(@^rNl!yaAwe_lvxt&;h=@I#tW)#&{1&-h{QHnXk>Ynm3_FvCTRF`Ib*icb@R!T|SVZW+E>tbM%5aML!hs8BA*~mHvF7w%g_b(*?!4R9EL~(YKju zELR_UVB&6@=IkmM-WVAd!98$qHikF)D3e)qlVo6C$fmHBx4nP*T$Uf2FhAo+XOtqv zU@K%NwXf=UN%&=fmw!C{7@Z;)EOByIJk*h6@|D*sWkg*tY2Rh;^Vd7lu2veR(6>}< z`Wf+crSea<&&gA78rgW?mqZ=ls{0$KDM=W zB$fU-$LeXs?d!WD_raPY3$t50FE6`l5W@0g zaG`J;m!wK>@<~fozIL0d8*Uo)C-z@+tNpU>t+ijkg-f9ldxY0qyZ9sV{I%5^--YFG zn|ykT{W*Szf4A1E@YlSTgZ$~&ZrSr$J=a^cJ8re)q2pOQU-xgm|J%~eF?U)o@P?zi z$cEcb)%`P$r$}k;H1jP_n72}feZG)#?))CkF1;HEGzW*W=Lh)I7KoXy8;fF@o;MR^ z9IL!yok*3yOHFRZq}$off4*_>XnXs)KX%wlgs@UH|9zDXV}r>L%dmsOXsemR}1 z#k5V~rs~RlF*Z*>7X9(?m|4hWY%sVzA|t3qp~X3)U;AUesi$W67 zGheUVVYbz!FOMOt!*iY6-E8|y&c72=zFd42CaICSM^Wg5`tHZ#a>o;jMdp`WyVl<~ zu_B=2ZC!Phz%~6dUh&?IT#mKN1jT)~YTxCsON-xpk4f<0h1>3`AqRAn=LwCs1eY-m zHVrdlD=~-THFpb9Z~S^9SyFc*8#3`IT@`#*H9pulWUm9oy#b9$Djb zS7~o)!T7fD1@#)+L%i$!i>gm8*rTbz&vsf<^`7i(ru50hx*TD%d+05<$MfCmZ69au?zxi2ZO-PvR8K(m{jP?d|(DW-LS^2$ARO%GCz zh)x=>l@-vR-!_(XtMTGvdagP_-JLG`gpUqy)Y>!J8ZhO!NoF#&!;16lRl4#4t;dY6 zz0y?=M!eoV*_oFX5#sW&LEwJG=Ea=~SFP;=4{^+%91&Rl)GGSE$fDY%OMW)`Gbz}p zy!kM=UVK%QLe6q^25U*nr9u04vLs7o>(pqRX|*X7GHOk}o_0zgXt{zC=T_BIR}>5n zD^%ni<#X%Tx;$R?R>aAoZ$Y1+{;x%rY{#GC$D&MFWyzxn&)C!Chb?8-xy z@g-+Vq_VWxdeXw(I|T!>y$*c|vE67duY2)t-%w99+qM1tQ#|$60^NNCocI$#+T63 zpLy8i^le`Z3`sKeDXlDj%NH?O6|Q;ZgSDWe>7%LT2IdNhG6r|`>EESFvhNqa@6c!G z^xeEcM#=cH0%w`%8ILsf`eQ%dddPQ&wir2SeElJ@B>zI2k#DA{wR6?I3zz1_JNVse zaPSVis+^QjB{o*V`ui?h=WWf@uN57l;)`~a9Iv!$XB0dG?D8v}j8lKk&Ldf$>st zQ^TtjEo#9MIwJwTeG&9*_L)h%%MW(FZ@=g?X0WbbSyufCJyHCuLr{*rOGS6j;Hg5Qn3DzpvhERBD>gPvRVYQbhT zi}RPG*)}ib{K)x6)s&~>J7?cfF(#M9m5$?t83Ox1Suu+M*q`v=2e`(%d zp>B4DK#`?;IXDZ)S9Y&b-8m6gFflGN`SC_xuJq7wYKN4_=E$QbbF5A?>`Y%d7BRa> zSl8c|dFR`i>sfLKk}{mS3uAY2ME$Y;WiJxdQP(gdbUwPMbANT=USs107Tq4puiG4? z>-BuF=3=SH?3?YsjQSfbm1|-=CwDm;o}KutSh#d_eCgqN8~u`R=7bL~YPoHm_3)|O zLm4me!){-gAEuspwJB;~M^K8aNKJT#u&ufL;ntxQ+CDE#bUkW!pLu?Zn|b}j!S{}a zDay_Vq-Ec>aJ5+|MfU&tm{M*my>RHm(T?-|A)n2iN_O(uc?JcI+P8~UwGWW05`$iA-T_WITX z8s7LHUe0&u&MEJ`s#-f-ITAAEU~szpxN(T`{Y`)Gn$SJ2R@V!;aduhz@1Krm3s%kQ zzT@UO)sU?v>G)p6!MZo)^8M-3M+I=TG2D?`yk>!n9l zMlF8e<6z9S+9{&4=lRN|rot!U7Vg-P!e(Q)^sX_x;*ELNqNhKdSSBK}NmJhMfrZNL zGcAdyM+$dHD%Kpi`1sBpvqv{f^_zTJHSe3B8WDb))S~3k!Qs6*N4fuy!hlh|*zN~r zVn18dKE+&cGXB%3k)Uvy%Ot?J;>ow|%!=upFN^S6~h6 z--{w<`wm@C*4-J!+Dx4GnID-*AF827ftTlOUz)Vh_< zI zKFj?O?w=yOc!O;)FZZ9>l{stnfAlq#=HmF}cfwwh*-0(m?_u5+V=>tUEi3z2rXFmW zRq=l_F1LQ(xa0{3Mx7q#^=Tg-=8gDxC>Ok#in?s)t94Q3g0J283Sr+cvH4H*YjQT$ z`SDsj6?-x?mEEtsOvhL#YnScew4;R_cOY77pn~W?AuwyAd-Yo4dyG7!KvQ_7vSXb50-*#+O z7}fkc9T+1KTYaIkOZ)R={6zexjCXvj zUF)7I{)9{XPL2C~B~=&G-{H?!#qb7iQR4hGG>_LuLuS!y^*eRdM+So;y$4q}wY_A1 zzSix1Vp%|ZlDE~zK7Y1Sofb}!Rc_}~UBb1$o(Y{S(vacz%->zNfO$~TQ*q+N1HHq; z0l$uP)PLS061&|p*3o}^{x{px<}r#D9-kAAu-Lw`yRz8KdfxOJA2*qN_e);qR||z( zJ(GXvJ(H}!`u4e#2=j6lOXu2zjq7zc=(BEBdc=I6?qo1aPHfPU^bbv|-mO1jf9h~# z?WE!M&K}j5g}K^E?EF4#p{I)Wa&5L5TprB6`A>J+Q})Amx!U;-d$P{^&>=M7^K4_cX3mE$NkZohwCQZ?@wJWb}#k9UVfEQf1hI+ z{Dj<&*8VZ zY0JvBqoz|6+kFZ%gx`Etxufypr~qe$VpqbvC+3~EgD1o+vyvi9-{e01)YRU&`JM7m z{`K!?_pi}iXEw&Fmd?cyvv2Ut8jls;~h~9yI#znG97NLEr zqiIoG!Yj&uvX|xgw0;@%of0|88{cGGzc(>IsgOf=bXF_rgpIhoe`#dux$cY3o`)B( zwPw|G?%95DOGNP78cS|-g_?$1T*>g?_mQSg*qy96^pRQ@L8;vpC3amWaHvdzj z@JZK&1{vLKbXjzxyI;57Nu@UoZ*SifBKOp$P`2UF;Tuv9J1dQ!-`;!UQcb3?K4-*q zn(0XT_8U20N}pyK&Qq^C_FYJFujjlbz74`2+KbQM^xer3D0h!F*Soh|%}8*P@r#?`+;0XcZQkhS6S<{#k6Z{E9BbF9o*J#< zS+U#lY~EdiO^psE0Sgm1H~um-w=ueV`kk$MqoG0?`%uP>tFN+p5=++~{}%PiezBU9 zy_4uJRr8%2Y~m{DUW>K_3>RN%JM;P2;De0#b}s(#FQMbLow0(I!+JJ5KN-{?Y4qNv zE1I@8!PL$tHspJ2=@OY1D~sWiwx`wgnrvd*gdI0)GpAbm-%bDGyygAvr!lHyae93( z?Q{Mr6pwu#ZZJ^j5N97L`mxV2ONA-WE&H(fR9exPkYcQTwtU=kkNc@^WwOQ>juyM8 zO$ga_En@odO5Ca0ieUw_WdWRWP-TJi`6=mald*YH}pMCGKX|o#6y7h!EC3QCH z$g)jOoVM9qn_1-K_)PP`rn8xhxk?vrURS(^|Aa95%91KW2d$ws>s!-9gW4IZ+Oj1w z%(FKcPafaN+!S7Iao;g$UICL-$d*OL={K^(Pu`8DRmFq5)SZrI_e2U(BpydsZ*8_>qjF|@F zJ6LP;Zwh=laZAsIt%ui)J|Wa#`H_&*38^yyFP?Wgq}miG^;j;vtR=gbNxCXf#A4#4 z{=?Q&ip!2&)UK4+%B#CcPVC&p1AA}pSa)x-{IhH1p0As(rm04z9%yAft>|fbDXG^l zPA6=)VC?q!+=ZRqys880nO|HFzT+s6XtLmxdK2KH!p*D9>zA@8?>1fa40A*s8w)MmJAns0$yAmJ(i^knSLt z##?Mwb7l3qh%4%ULqne5Nr}HG(W9TZMO18{?5OXa?IpWhIm~N3SZRZ;4L( zNzsZ;LHpI(Z*56EqLZ(h@REM3K|=7YNpKM1mA6*=t^kmIY^*+>x^0DJmga zZWrWXFtBq#fiB$CNb--fOvn$xk@8%w=-u)?j}EN}c^)gTvD!3rh9Pi@|5v%%=C{!e zTu(Wkb1gSLlEJ@H$F=^0EBj&QmkKK3eakfU`=0R|<=pY8(ULz*XJO|T>E_)hG_)hg z9ls};NtHKi_j5LS+wZcMUuP~IRVb63?Hcfdd-rdRLu zBY(;7O*|Vbsw4BFgtH=zM#cTTi+R#({AX^x+a2~SnUVX!qD<SIS8%2(`R=yMH zyna2-e&3$kY-1A(;tp^{Zag$nbXIoxF01z}5n zBP`|JOth+Kwe!B#)kA+wj@-x-5D~Q19ubsZl977JbV+81ftdWgL+o#&mh9j3^VwlH zyIPfVyEo@rzRcR>x+a@t? zOw*TbkK=!IrW+f?hd)_w(9mx!(P9!&JEX!W9kGZpr}min`e&Pd z?7D~m-Ju=I!eT4`L@ydRoRD2(c0!!>OX1dJ9|N^R$MMr1H$6I}{V~EeZ-LHosZ*RfIh%}DAAZ-jJ%K}$Eq}7lu{vJbChI}q>h;dU zkJ4-0ML(#k6uQ)hz0G6!@pS#`o()R(#s1vd(~tk3ED%lN*3EQF8Y~{qz8TBoqZ<={ zNviz1Yr$lHM6lf7H-(kwRlx zHCkmZZt*#6GpsByBDK~!Zi_FySrPsVQZQ}?hy-obKa~QI0E(?ykU=}Ww>bASPq?d)ij=eW5biFA4yhmm-lRY2y-+A^^ zx~gTT>dr4#i#r@MS(lHEUh(SRlb2>2Sk&(I^!K$=XI2|!Cd0DVTr0Ai-faF6-qpR9 zEmb~Q*LG1T-KUIt*355BKY7G=Hbhs6rarEJ{qP*miNnvhfADEc)=QL~*zzMj?G)3X z*#(x2U$t2#n-f(C1o|yODM%*i>&ukWsnV)fgah3AwYthQ9^7bBWX>iI~H2Y*;lv;zV zALn_K``5b*GVBZO>?}sD)$E13O!r%!etUXa+upUJS8sp0<#ncVI^!DE3GS;23K}o( zG!)9JFu1R?`}pWa#tjzpsn}DT$42WHX68-Z}0ryw2}erCRy9Wc?rUIYO+N zjoF4*4nJXbzrHE9EB$Tj`0EKR83XfYDVGynlVuEIq6P=*+h$%)=djKz ztyiuzaR(X-{t)^&Bc}E9bk%1gC&#BRVz!3KFO71oy4UrCoByu=y@vjE=Q=zL^*3x3 z`|(_wl>$R#b!?8Nv{$PqJ2dXjFIsdn*OrdswB--3 zb9aYNI2mp?3$i{l-{6jBz>1vKq1|<5>G#W%46Q{>O5M#@S#Ky@WD!*GgM09i%v-wD zJ#&UJ88+Q7TQBS;C|HoX zWTl2q>}|1pnT+r3Tb1bAwprBT_nrO|;H#pU{rry48vcznE}i;!kMSnFPFs5GImhxc z7ZEd4rS>fnmgPM{4s9DZ2bb*m>->Gmg7rH;ACB|=Fw`!=OwYJgE?TbfyTb$is_{cd zz05zks_-vK|NY5BgM06~-o+k|8~=9o-`XG~>^!Kqbam3k&nj&q2bdVTL-y>wKB_XJ zP(JP!=W)V!z(iJ0J?DJswu2*1Dmm@hZz7}FUg3KYrJ?+RK9j4zoVmF|p_%{qp0*RV z-}8#5PQ35j-cyr5!+B`UfdrZH%h^LiGPfsLMjJjjJkRR`9FonCNj@H9@!DC##{SY>IUDiy>9OZW)B5!!ChtZHh%aJU%&Xo zh0@1kE5{fF%i9ctMV3lMDmd+O-Q6~^jm~&KPnlD0Sy}scuKCPs4@})mWRi5a>Hk1s zc)+)AxJydJ%&757c+An0{-t^6{eyg&L(-nD%le#fuV;A-)3V1F3--o#)OjUweDPxP z;3%QHawhU!9t-EIy~bvI>5p8?RnIC$tLisC$$q$|DeaM?o`qY|=%;~TF7v^3>FYLC zuP(Rssb4G=ddM`PV$$Du>{Nh6pP7VH=Ik!#Q2*qc)t#dy6Avt0C8OUc>y~M#JlRs) z<7fN&YOQK-uaca$&)azO6V1(dl_%7Z-;87Cpz*{Cd@{;fXfI1@5`@vaGwmG~Wq*@bl$`1c~Bz z$Bk8v);En-WzM9_9(VY=%<^EkpTzU;UU%AsPo|z-{Nbs|*<_x@X)bq9etfyhxvk~z z*;D>c9@~%Q+DP?rU7r&A+EXa_!hElY;Y`u1#|kby`seqoVZJ|`e7>TV?dFohn$Mq~ zsx*9_IWgvAyUfx4W%=zheBVz5I&3;FKDl&Wwph@(Wad@Ltj@f#c=eg`@WKaceTrAa z2`>G@ZtR^Ubdr9-ai7j_UX_d*WfueAuj)F^`mAqq{nn~$mEyvtOu+cmZYjp+z?#VA9RY3USxHz+V_LE_E&~v zt(l+6^oo8{mP1EVBhPWw54-PlH9yu>T3aBvW23H7-mb8*VMgWL7(WxWUT!}1*ZIBy zPA-$%N*OEfk88Duu!WBNop6 zMCNU>%bjJVHj9G<6S;R-Kl>T9gkDmr>Qw>nsx#~_x0DGnnvN{|G_Yf+S}RJ&!8olv zN=aG6_y;rJ*1`EPSq725yZAp1dW1i_?f121Jxhl}gGq&;F8k1pC!w}qwT54Bl70Ll z;M{xWnfcadf1Ej{y}{=IGv-?V&>Tu zx*kt%{;jKdf=4vcZ?k)pYtiP}L-B|5Hw_Jh=xowzqK+#?E8ov9LT++#$G)#= z3v;!XXQlKv72PQ*svMV#jdg$4w{2EsqJ+n5d9OyXqPB~G3-{@$s4C}kavN5;T;VqQ z)izj{@WNZUK>EF~@4cgupB$!guNY{iah-2^T38*r!}7C+I>XRPZAYE_t{uNZ?j%*a z@Qq2t)ih@Y?~n4I^?PyLS8P_etnh4&(=nfjRmYp;29KYE#c?%sB&-xs->z1F!6W@~>W}+!(u3qf58Z8q1;_a-A!`q}8E!Wzn z2MsI63`SUmILF^$dJr-uMWi1FEuk-%~sP%B!6$<>}RmOUvr7WO{Dx+>`d} z6Wdk#oobIfy)P?qziIf{HIbU~n{n_!`pUe*sm21H+U68)n=#ufLc0SEmz+J9b5*@g z*f43Um`ai72Rgr?CDQ(px7upgK1}mVP4o>slb#{|B(a)LB6FdV>WfFrD`k&dS30_* zy@Y|STgfQM$LEsQH<1@QGK;*+zuwxLY5sk5tg)sxHxC8I%{bI8kX^PnI`-<9V+%U6SIr-a zeXid&HShlek3ew08%obgbTKYC%xO&~?ag8113rfzpfJ*SK4%RD1-De2)-^*8bBdFpNpOU0^Fu+j1{WM>ph z#_ioK*EyUQ87>EnnH_gAUQJ65hX-BY^6I}L2Y4dGoZ)9WL0C1|N|H&rBR)+fUCiAy zc0&;@TyCK0*b)%~>@t>JTNKGKNz}B%IeAFA>#nklKB$oE<9Q+eq zi=_?Cf8(xxpzr$bXGvk;wD|U$Q5uSIpFPp7|2Oz`OFc{Qw`ly;%RD-VM>4`=}0p2D&=UM`O8ODGaFK}fL z@drvlGV(|Ie?#QZ`N|U@FYyNsU79X7Cbb-}GV{=+**b0(BC3rcYc)`d))gHl{_t75 zHQ`5(=sCjq2Rr$}IJkz4)fPu8%~A*kf-I#7&63#9P-I$WH%tl3=Ud)pM}9i3rALrV z5>^sVyhZgmfo%$~u^S5gIPxL|;hg~zf%;9_SO5#AfqpY7C(pBXr5;|!lB)jwj_&QX+j{~p}fl%2@{GsckK zOm{J=c1j#(dJ7)ah^ykxfAoFmjmN!UTA(7XIprK!G1zkEQiCp|mv6x(+aJvF>F3{q z-cyD(8sk+8TfSgblSm)ZXFUHbOk*_`-9}}%F@INn6<&dN*y0^%={$IqwXW)4Qp>X) zZE5edh&3P^(e{1CB4YX%k~Zo3!%poBCrI4soNmc$UnF=D3O8GbDQUA39!7+#Q}h72 zFpUkR;aXV~jHl4i)9&HXGah&R3j!d_9(P0SWY!p89cL7jeM2uaY@+Ju*r}MXSr^y% zKt_D7)V8E;6&123W~{Bfo0IU_im_=~(IpxpIvCv2$zCcJ3;yS~C4{?Y-Z)dE#GUFAU&@8=k9!;YlZR3mBf77naj-f4{(tSHnHz0a>9dv0BF*U5Sr*(X zDBpC({@S?VY~2=kGDGD%(LMT$p{zAkpPuLV0vnXKV{T+KpiGEmZ~lA}ntjc{hH7RC z0+v6&fs_ramn$uy`(e&G51HEKZwPr4B#G0;Wt_{4MP@wM4& zayWec894~wbc0_a1f;x+6G1F$amc`_UKNvjawNQ-orO@nJz6@l+**oW)S8&u99P?{ z1z<0`7BeDrALYn(!YcP^9sM?%9QQDn(T!LenL%uLmtGQR84AXhW)pOmyDxKQ4gUrQ zutSj$35Ml|+VA>oq5tlFQoYIu`NXh2%(RKD#XkXNQi&Y+O%v6IYQ`g}kgmUOH%(=i zC@ub0MYED{>eKHIeBOrk(PSO{ISXH^utTr)4P3{icO3}FUR9ds%&liu0x3?VadLTP z7Pf1+E9sikTH=X!^9jMvn%1vhgD7y~MiqzTJ-dgnQ-^(WF#>oM2YOt1%_TdyeHnVFn> zp;pcc`9f|SMVdpL5pZJLfW_Si!!Bz>GjD@U{lGcqs&!b=Q3Gs30+)bZ$_@gB0lM6` zOx!fc7zBA4a~`K3@ljfOowe@dnRw@DRi$jHp5&L%fxZU6i?kV?dS8{glmePV#KvwP zBVE8u=Fo;8&)Q6x3}UUJCFH#4)!JL8^W62!ba$+3+4#CaIT!Ra+x?J?_vqueqfn__ z^~a8=Xv@r9xRa*?^!4v`$`QDa&pr71f1=6*oc6KSh#pbWi`-4WCne|&OzE>*=QO)3 ztAgzCX>rM<`hQF~Mr4Eh$IJy24b?{)06#oOXIo;AN!Ja-{5z%zUNyVSeC~_*hImAn>{HD;2i-- zHXl_z`vHt>O7l*LO1JXS7ZkC$WN;3h6^$Gnl`_gmGn1nhknfYDi`=k?8$!bDY#p*J z^F^vHpj}9>IeE8d%}8V2dcFuMiViRJVz|kdv*OICo2{I~z*Y^>`5n*56c1fd`fZm) z^#)ILkng;d8hE>R#|ITaJ}?mGd|_|N5pAFwX-J4Eh@UU{gFyDv;J-QAg=oO-M=U;FkQFXUb z$#v*bi;3Z#7%&RMQ5)^@=bKL#{Ts|i)*C{?Pa#a`<#rioQ~p|LEE>nP=9n#_rz4j; zekTr$urcEJilQg`_)z=F6o^Ka7$HD0mE#a3-ljEz$>PgMq z(=Q=jSuDb|Q%_KhNk&#sUv|NAP*UQ$=8%0!54W>6++PYZ#8^*gQjp4vbjmL zo0|^_i&|ssD<*rk%vMM`4?sdYnU1&$=w9)>9BFC4MImrUbb;oSEPGlBdlB$w)-TrQ zG2|l&8?ZhcZj?n78h$YdyCE>Ux%Jc!ngJQ#8!z%UCTe?KEBn1c>AH6#+^pV($$Dix z%VG?qVE4?Y+W9o|Mc3B9FHtH$8m2$q2$+@(Z4taM6KNVqJg%Koh6h%JZ`>GlJM=D; zOx0fLx4VHLgR!c23T{TL%goQF(os(At>nM1jlRI?iN89B`a(kX?QB6}v_%fDyzKL$ z@0|@h;;dwi!#XZkEF%2y2J!Fko) z)HQ^5&DDCk*_P6FebrWdCYs6(mnpz#OirwiXH zi`e*A@cf$f&Tos8pk^KYZ$I$;!i%|MTLaX09K>F0yM?W+IJ2H=H2nL~>agGBp8B~| zb_OlUpXj)PfV~O}BA3;xU5llQs z11p&u=ybGE78k?Vxw#yANj}Dkw-2!Ea!8=qS7Ao72U{OZoUJ$s)B5E7BrIQ6KqqJQ z217l-1=}^n@dtH_?aA%EG>TK>Q6k*yfD&^{ZISbe0pg>6&7;uXFEms<3F|28FSYp- zNp5wlxagbXQ?=c($b%f;K`N9%ZIGhg)zZB%ZSLGpH0y;&)35(lZzNq%56To~AGDnR zPrnF;YAjf_eJUlP6TiMOdjt}!Y|V0h@s_WZ{({v}O*J<)iRVWn(hQ1q^F{BJ>=5;2 zBel^Fj9bz$2z_>3L*)ftY*q?lZ!^hAA}`ib(MUfYT&2qvPoet(q}6QpJqq_rvKtDX z9xG0zr=eubKO|ZQN^^pl?~z+B2IVP;?H*h5myYW$v4rF(gr>WmZ@hBej1@lOrsaia za&l90n@vAQ{bG#v0EzE}Ve;{UEf*I#j93~u2Mo-nJ3-k_&Sm2Mi09H@)Mg>XfmtI- zA<7(ML$u4Jo*dIdS{RBoElDcO5Xn|3N4&s_b2e~B=Ofu{Y40oAR!6_Nv~f8MMX?3^ ziO(FL1U0k3QSUJQr9ZOVHznUj)w9V+CX-0qy4klA@wMrQSqLR3>1>b2vAAsc#! zV(VDz9Sg!b_hSg%AznPifU|s`75cm8!#?54Fp^s?N##@3`_Nm{PM#{>-7>zq`-0Nbo|6wIG0Rlr zW0!qP@7>tw74-1C2Qj7_t%mCYm^W%k{piW}YNFzd71sRus-IxF4cK`o@Cvy-`LxwC z7sa5$a;-a?DF;Pl27}Vmp|OB-9|)})JI51t6i9+RcP?sXazSkwv;RneXHy8_IemX&Sp+jKce|4eGS*Otd_X@impX<=JNG z(N>9T-=x=)QMf_JA=}CgkxAJLwcZod2-%Rd2;>hBfg8x8OK>CbZLi*|cJWmv9U!mN zr?xJ-UP48e%k>A4`Ib4-20t`D1AQ{%={cJe=K0jhS3=^tWK8*9 zH#MK^qqtA!bONhQ&#Pbi+vG{u1eHKKHaxM}jgAR6WIN{!IHBp%yU5x>jho<^b+EU( zjtwX(I7*t^CZXABD?6UwTpG^%qV5*+RtY(3n_Xozf>ku-2h;TVW0?))yL?r#XYD*0 zHgRG`G35c^X-D?A{xj6-?D*##DZt`x&kpr;&<`y_ zQA5MVaWzb?-3!*)GdF{YK0E&d`LdGSMqCF~P}(a-?43UyEDSiw9&8Bq&-IAn3}z6d zH;i@a`tccI%eoPxdj}vozz0Y#seDNS&K@41%!Hx+w z4@3g!g?3sN-Svp#m8@IXzrxikwhTg70Cy2F;gN2-QE(dbY`S=&?;a^8ra{NULP31q zTQUcY*dcc@MTf8|5d&C$J!0Z{Lf9$m@vxFKN*sYZ)Q$-@6DVN^c}#A8M1nsBF&BsJ zxFPMV9|D{$@PXr$Yq{>55ne_u!7R+whr)9_)skB-irBQv(~n5T>@imHVfSJtVL~`$ zvEMXk=kydp7`n3~)@IPt{~vXbs+(^xy@OwJddM1|Y-IyP_q z^^OTPYaOl`TQwrR8~$7g-2^G4be6%gm)qeNYc>?aaL^o|lU_cbh`<}k5fUgsHBSAy z7Xt%RoSrT=OTP@3|3oRHoWXm778)HUKlNF=i=z)%78^$@?H|`xolJ{7!Z4)>PePJI zCp<&X@1IzyZ>s>)!~RX$h5?!_@JC0jv$8u?7cS+3`)2eS z%Xx*bH>*6DbmV3f>*s!b9&L&tU(wTDfoe;VBW&_%5OmDi|D5Y51bmL=J;ht?^QymS zUld>)C1tRC&D}XxS(7WAi>jk2q&&EK;tTsF(UkO5YAW;{sUTXZbtKM$w@PeSqkDeX z{kA7Ncc!2?xL|{t%e~}@hDpr-C36x8*mWJ6lN$3!1?1|SJSmk?b7qXweFQ=FP;DvwQ)yWp z3+_A_dL9h1(OI%N-{B69xaH7-asFfEVs#8LPM>AA#e!$lpbg}(@f;zj{~MmMb-Vxs z$igZ_fM$%-A9R2{^DPbq^X1s?FZ#4pWsMA?R*x7%7DQs#F|1+LbxKeedAr%9A3t;^ ztH&a6aBB6{$B;J^by(VS0rd~V&&frK>&eoyZ8i-=bE%ZTS(95Xn!;dJA6SMpnLR?? zMUSl5)KxNx-7jsgX4DSxLbQt%T*F&M`!xI`AJPGZC_#9Ym-n08t!?kMWJQ9NEejLX z33mT~^T{{aV-9{ob9T5G$@|XDm7(6~Yi`EZaFGqAB41e)g;ehz7&7J-huR&2aSgTx%4R6?9Q4*kOO>rUy+}jEv{NBOzuHJ<3OSm5&KFluWxSd$qHg2xz`|G^ujT8LAS2euboVx)iF* zI=vU{+gDOrnb(+Q;352`C&%1ANxZs2YBSz4PfkkDAb?=hP(ci9P8x1I6O)3)b=X&c2kM2Af^i}9I)qfrAK4|No+8=FK zop!+B5cm`(YcdP@_IZXJg!QS3JT#CoZ*DHP3ytCR&PT0lFhs}E#x0o4ZFyg$5Jr$7!=jt&AxP8IhgePYLE#wU&-P2 zX<((vsCmYg|_(*4c^=^b2a*x$i8FF6g*It{)Uk)8DX3~!LF5lk=R5b26 zpQlUMY7!CKx~y!O08*au&8gNV1gqT3hSKPIg-vY_mzRO0m=>~swUcyi9f0eOD2R$& z<^KZp$4{n4d&|##=pQaPOX?;s zix_r6rJpAg&E~X1 z`%lL@c(tPGX|14i=A1^EwW_>TY-oX?AAd-Z5acp%pYH)dD)_ys1$CZ8<%v{r*^9v6 zOi%f7WyppmQC`uXS^@A3aa1@>Okf#xs~AaLOq#8`h`-iLZvR3OPucUc^g|>6eXh_f z8V7yh*Ld+M%G90%H|{~<9_4qlHs3Qd2S~}rW^qir0vNZ*43StpLjl1&E$j9Y`_{%LfAo7E7u_88q`(Slc%e8dXEu9bd<6%gzr_}u8E*OYd z&AFm9W)C157mxn%DrG3Eel!r~+2Cj)f3j3>m}Ivv2DEo}H;WyHW`2(vot4!meZDQ4C?zpDl=vjQkGg`d)p}pyCDWWt)rVhe zWTtsnJ>+D$Lg@-P*$5+DRN{mfHLg0*cb2Cn7C9L%q6#<0pD(vts67?zkFI+G<(6UQ z3Iuf)>3iQYe`R-95m`V40?J)m+SfUmaN~#t;wL^y#k4BQpVV~S?YtmC)K?d{D;F{v zlOOH!n#VLARW&rnDL5j~Th}6dQf3Vzv`w54P~p}?Hr*KEfvungMJ`-c=_i*vbM+L! zmqWL<=SgxLBqFY5(q^q*QY$|>&925m>L-C7-A{wTiZ|=4Q=o`( z`$u1EOJD%n)Rj-!n{j+i*F1l+rP6(l>5ZJ*h}ZiFglct|~P={jTxr9kJepCc?&wZP?rtQPnU|mw+Q4Wvhf&>F1TId2YkR=_+US zBpo|bHiAAV;m`wbwuVTTeE2Su)4Hle_}V)Mm!t(q79sL*oDhQvO>#!7(*1a~Yd56) zT{4Wx>_IIq-{E{@6^Qs)`@&YC+N%YWwMh-xyvZTs-ij22e> z|5b&KWyVH3=&K8HekLadf3|P3^oCe9zddE)+f1PAsPD+0<0@GSty4m6xqONQ4gSP@@N2vh?DSu5R1K+j`1wW$g?rh3fqdFn=g z2j&4d*F2m>|{g$nzcUrW#WzJ;X;-Bx#wdYSA`$TC{6EyY^qj!{(3Y!->P)z6J z{*hO}Me2WQQVZKIQqN;J^oS4#FaID56(t)9IEBnEODY<)S4~(b6TJ{L%ZX?oq@wvZ z`f5YCbr1+6evnaj#fM2ds|^1lCwD{~%qkT%x9EB7BcORv70uQ$m1!wI(_Z8ROWxWC zC4Jiuz>Ayym}-f`zeNY-67Ww+r74s4Z~~`;@S!I;Xr9Uq*Db(knejl;S|lQ3j7sbR zD8>;4?gAzelYEi(mPpjM}G#M++&YR}sM~`XPnAJ+^=<-k$L!PB%``ZN+T&bpZw9 z3gZ7XAinWGV;bAMJi?*8-!XC0jZIIQW~qvb8A}v)#w%pM_oXFbqmB3_tBvsUU8wX> zU05B+Lob;d{~jCRax~(r8+BVr(3(H>HzY%{%y|$oQJ-Ude*GM0-LW_cCSlhdgDYqC zLByU=(CK9amo*lek`7JNCHaWr{*wpsR)15mLBB|AcT5OrXVvCcA8Mr% zoe1_1xu?A>r;@l+lJ<(trM*;MB zj3F~w#gaAO->DQ2{WO1b49@jS5iT;Wt4XkPgt*J3vL**xRYkYSY)vZ6s}e*Z`ljA# zF*QXjft9&1K?GxX|1DMPAFB(eGh{H!i0BMRmP^06v5!sWkEmzzOusR`7TkQzC~=R* zcVw)dwNZhKUk}1MYGgDvS82J6OP&ragb*W8g-wQ-vO79R{4;$74eLabmZTJ(z-T8d z6~_#SN^-^?`%0KNw1BdKt?#zl{jw=kD@Bx^JL|m6LY{KASu$`qnmw8{d9t<(*C4? zE49;}o4=p|Nb#f?JnhN%eCjOZVZ&3jG#$49R@(gegT1N_eN^5w*o6T>C=(U0sxp{3&{nV+i)gMf0)XMbmwID)RLHR|pe^T32nCHVdCak4!PPN8+VI zJ<{6_?^bEO4~(mc{Gqa9KJ`PJ|MC`>=hXC3qs<17g=BXNw&VtWiHqJ*hY^tUZ{rNt zWO3HfV+Pq_0agZIqdp9Pd?GJ4k^*1Utg)Lmqy~ccsZZ!vzRqd z#o2@H;=E7iMZzCfeH-#>Ac2@F1HQOAer9bBk4Ef*GgYo5WHeZgU zd${jk^q#h0zT)Ru>Ao}<5X9V^_KyN?cf^vaf2Wwj`L@SX|MV$gKyQ&$XK>i>u&n)na4}Pg3 z1OR6iksE!d1FR_2Xg<_#%EW>Yy!9YnF8cTJfe>7m;fjHB_I)vgVUIc?Hh?Gy|1adY z^o4(1GPV1UnRpzB%{ul>`lrnCPQzJMLa@&)A(n2sFYEzf7vARqH(_jzT3vl{xDb=5 zPzP9kV)8^O$!J}f>|co`h1@CYH4l>$jq&fb!2?~Mt<&CWKKd7m-WhxFZd`zrQDR0d z@d^Agc!D(JMZm@OE;d&2p!;GbPZHzSi=g3|WU>iS#k)So|0`J43Zb58Sixx)$w*#U ziUK@@#V1w=LL(rUSO7nPdDS`JsyS*|F+PT`#FnLRq?4r(#yFr?Jr&w*umuv9)Y^%( zwiY`l{X%yDf|0eHnQN)HEmNPk{w6V%tLwr)K7>c`HIoT8TLN7P*16ybRK!3P#86KN zg(^2px0=DSOx=ab^&piGH7*!P>`-MTDc*<53VzvswR@;U@#RoSa41@Dc*Ns1jU3|?%rPPD)rf$!eIBd@meBA{~(2cRbuaBbZJmT#qAe8bxt1k2%WB<(pCNo!mfW9nTBXmS%Z5~T{EO{co#Y%nPdGD=~zH($BSycVJ+Ygy+sbQ%Y~ zTSAo5(87&oR}&hHYejgK?^2s@wn7?^o}@m-PbAFSnA+htZ4VRGBrvr#NqYZ(Ocy_0 z^&3q$JxVBAI&oro?L3OC_JjmbVRv;v3ee8B&;O#6?O@JUvy}~{DxGCiW&m)@d0l?G z(95s&xBGQgpKlbD|GyOuF-HQgWp+Q*)8;Lxx;9VYEhweh$|IIY=e7{jIff5SrvZx9 zzMV{PXdWNSUuMEzN65TKpHj&bWhG`2GAnHXRX%}vc?_#|qxKKe4$Zz~65@q(xqbaD`JMJ}415FmczHTjLxvVk1{a|gwBvig* zgGv*bsB8@-KhnjP<|x5Wgnbtah2QVoI~X~KZ6P1IWzp6kZyi1X6E4s$rD+(~P=V{1tif3vO!oz|y zYr=5xAYjW@We|BUUXg|d4#gcbd(qd%o#}tpn!9VriOw%=%31mddHCC9513IzQ8jJC z!_=Q#DPYKaTBagTX*Sa@Pvs_GNPqAwy?NKf8cJ+sffQJ zAxLYk09&2W7ZJ1?7<*b@Q%Esq#LP-`;~N)m2hR+jj**|pH{6j`M(WEb+CjY~#{t;e(^?vgZ0Hn#r7ommy7aD3NAoI5b^ zxnC~pxyh>H>BW!x{(z?3#dzdm=Xqeb{nYuYDUCUeI(zb8CHVTt-M1*+6sC7)7LppT zDGzrX<=w&S=K_l8OzeT6o9b?pz;eUtiIGir3)?CCw0DC|*b^EZIHJ`GwRZQ&5ql}k zSM@J4;=|gMxAe`P5bQCSZ96Te%#ag#5tbf|RC7h)7~hbz$3D*`NoW8#++nrO;gNO> zi})run2Iv|kRys-0_v$)M4-6t;?B2Mnjdun!&oat}L0ZCg}3va^b^;L+}*((b0C)7fH zyH8@u4Ta=2OX$ZrbWb=Aa~J&3i3wG=+wFo65D!(^Bsk&NC`S7}{_Z6E={e zmU@=l(0Nd+K0RC((Uhy}LgkWyX!h?((>a?VK-d%zUm*omOE<{JYyOeEZY@57?w!Ke zR6_b<@8XJ~ja=YIUC22`d-?Jza>rV03tcuecMyU)*knIczRW-DOz$O!Vovy>4%o_+Mw%Q_H}%_SN0&TFN@+QAWQp1QW!mhC0DZ zg-q+ZsUfp+jRRTw;)u;ID_Y+qxnd-O0;>|o#ayi>&GH%W;DdvF=eeqiO;b5-0#e1_ zawX+shkX28OSdL&L8zoy|NSHOq(}1oo$`X*`2QLUOBQj;vbJ-P=c6YRRWG)*i;EkU_pZEE#7Tuo;qw7O6pI`bMtPn@ zOIq$RHAM~bj#K$@`++s{5E(kD6OTy1BVT)jn(ZHGI(^Sbk-`Z9gA+J_ebQT(X+ULP zk7OBjg?5d}zl#kTYv8>j-RfjI8GZ373)!9nwASVPgVQO`sC7)cMI5)t8p}fV_U6}V z-gOBZU3FEZS1y9a^{I@9e0_W9bu)YvfVv`=E7u+{u;_oCw31{eIt9TABClPUua>ZhSkBbMwug%g67K~qOUS>m#l<(g* zLQ-YjeW=QB--o3HXYH`GSv65_yMx2iwwk9Vq=48pA_2=|u9L8DAR{DV?di?))L+tnfmWnaWIF1#%vdzF^%d_EDS= zcHtP|lI7MzDT`7iGs2Ac%^6HI=xO7O4L}{R-~ra%V+p-9*3p)@Ln%+M%XKnn^bqj# z^Cik73k#{4%jFzmZPu)h&>bX3%}2kpjBFo5MZ^TpBdn1a?>BV#gwo3QCzr2JxpI~7Vb&4LKhw|2Li+^AE>)em0jQ8DUzJqFcd)SC0PhefS!9^ zk8pI~A#+(E=xT0&#Y6gaI|JKWE_Fkzm3(ETIoeGBV2KBIm?05$!`5{o-*{*Zst4`I z0(z9mZ!Xs((Ap!iY$_*W!9n6O9WBx(Ub@_6HZ0%% z2?hB->+{H-WiG}U(;#`5teYE&?QqczV+eGx>_SWjO}?WTbgfEge#$v6D)$hY+rb4fQIa(XlplK^B$+ z5eG@#1T)N1KNTY7YuV)4Ae*od)s%joK0|b+7X@1SVNyJ5xvYW

+|jI3?!uhp3*Trflc)8v_0 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

E~jMBqcP&t*(#)xX5MTaXtoqB^Zh| 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 vI7G)1K^9ga{ts;*vJAc*8N_bQV|6ag9 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�Da!{!h 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 z `f>bu{4bY}3kzn$OQzW1xI>eQ)Ir%s(Zb?Ve%&Hnda2j2Iew_mh~ORmxEFO`>) z{bpp>ra!={R7I>|jhtZQ&y?T)Dn}_he?E+ca+z#r=UC=UE>_X{O*SD!Mj1|A(m0kPd(;^pX|r_uBUx_v1Y( zdi*2&W>B2>^6`B?fiA-Buqi7Q@@4}| z^Ia_g_o378bNurIe>WmrPR)>aaPq#u#60sa*U5Ss zDlV3@f}&91%Pq$#hATrJ)+chrAb>vxjv%2xKdi?;#!<}QAUjD9US|4b^xk6!qJD|J zAr<|M>hJc(k)Qn%kq^bIcG8LDj%hL0gZ>h7xqEZ zJ@B4i&gy}ye}erL++Xv?e@S}b;62g{=*G{I>>>6laZazsez2Sr*u zhWK^1@I&Jl3y_D#FEQWWVZNWw??=^4I14zQ)7tws1kR(zM~rxY0(W5#1$aDm-`?|y z*8St>(^=#t36#Adl)DtlV-Jl#J9_d~tVOjkvlzls`hjO0dnOLi$hvi7=KGS(G}>Wq z31M9bSawbQ!ut=?Q~fbvL7j^)`ajs-fzeJOUjzqq@kecajtQtAI~==q6Czi+THz=E zr_u_|P+mUw*f|cHQ+E*?IrhPJikbc#58L<3`_S0~Q)i57E(xo-%~bQy_;aGCz6BAoh811G1!|suC*XGON%NOw_O&G2gj-3s279W*tV0Y!&;wIIyN9LZR{*J~8<2|G! z@&Or~EPTN4;V;~o@Y@wU@5(*&_k{?&`w5F3WBC&b7y&k4j}hLP1?Jr$n0W{0A{uWf z)e+^fOUqEn{fEEEDwVsRhYeNq<1k8F=j~6SiZ5UIO7RE(4f%a1bj>L^cYj+Xke{+H zGEQQ_HY#tNJQU7B>V2x#I%3)oO>YGC#9N83r|eKfO?cpZukr7`Bcb6@8C6fsqrf>W zzrZ%HK*=j`l@_=HWdGS;4MygbU$kUTpS|nY{}$yd!7e<>d_wpEw?iPB%}rBZe4XJ3 zo;yZg^Vr=2{=9x0=AuiVWFR2y`8U^o;H%HL@QrW7(~}=d7zbUx`M?F9Z1?~cf@Tlk z!Z*GH8Kogl>ax#r$>syk@`}7BDbg%yyYFH5Do1TT@N6&dl$Up0^UnHtpX23yftUCB zn%9u^#czA+Ti^DS9I}ElKX$tR`M;4p?zL>^bA_3vdG=gK6XY726+QKOMjI7UqW6`Q zUwNH*mxtd8>3B8i_${F0bDz4EM8xwmnmeD`LzcPlqk5M2-ixroq|fxE-@x-_=9$OS z_{{!d{^#qnMxJQrRGbq&tvM~Krf2Vvj&H}-yuML7UJzcj9siwAKA(l)|MkYVqqWlc zkKo6X+*$o15rNzDU+5Sf7G@%usnI3 zz0}4oyqnvx^mD!1>g}~%h?<~GOg-*6GQ$jVvo(WUr;6tN=bac(MQ7wVXR`CQ4dU_s zOXi07^_;uprL4_g^`mxf@{Akr7UPE1xjoGh3lT1gXt>a&;KW<0>EQSMm)t_tDw$HD z|D49kgDMQ(vJ_+F@>J|>oINLheMblYv*H^N8%{=8YTo_XpRrh{wegWRB=hbYvvb}5 z|IY0_PS+g=zks-{Qy>?Xl$X5V29Fl!{mu1wqDcXkQ!qQakSCW;#GvP+;!(qA=(_V< z4Bda;XRng%zG}?u2c;WSHJ0pehgA)e%0GTsRO8#ehox}-mZlT{d}#c+Qqe=>7n<*j z%=fpUVwzc~2t10yzQ4j>Na0hVK78vBi9U>wWz>fsfta8^eC@{jUx_37h>&+${(kwHf{e}!ryn@yvTY}=g1qBp$&kGgFy9fv{L-J>_5mjM z7Oh|4Plx#)LOy*3l<%E=E`AU2%<_X9=L1zq!^Sq!koe#Rf^2IVG?%YDxN)g{q^l>< zr^@;W1i^E0GEQ1r4Qso@V1+Cg@tWnHFw3qa%SATJePNd8C0V}BX8Dg{mjCr<+I*4W618eEq^3O>ht zj-Qu(_t+!tH;fvQ^ZV~HA_t}ab7rnkv%clBlxF>VKOeB{7d~&5C~DRl;mZg45hu z|JqEBBcR&osTU-b`;`3{NV)5CU zrt^BzBJM$pds1~jJFNR=SNCW_3sOX{e-mjs$|8x$;sO@YVcQ?I1kcNR;Q7apU4EZ^ zi;-Vf{#3?LJhFJX7ADti;uIEN`I&%!Klevx zg%;o51BTr)?uX7J|g-kbaPnL~-K>+t3q-kZyR+su@$7vc>yAq(w8W2Q`- zt(4Qlwh*tESiGJZqtQZCy$ApLQvCh~e&deJZJ);PugmZA<@eX{n|Dg0#>bsWtv}f) zGUw7Bz54N~uvg#pUjp7*|HHGwTOJlY=Ci>RJ_kd5o_y5ev$gq5Xz_v`wD_;+et({L zc3AhCtNV=PuZKksT6|{;pHF-!=$pUzgEOGT3wzMwy*Lr))8b@Uch1#)Mzrv-=s}B% zQuvI7`26ATp8+ji)Pojp-y726D<2H{;i#+ojA-Fu(SsJxOyTo^5TD=ty)&T2RXu2N z??gz8)v)eqSN9pwVz37m=ccf@BE;e|ziTOQMpz8>z~Y|qkQQJ3>3}b8K08>vqz4xN zv?s*kgCQ0l`<=5wi|swIsHL!24Y3&gx546XZwYDfk`RlZ`|Yzri{T!$D5S9XyAK3> zF>rRUxTXgdU${A>#fL*Ie(JaSqy={)LzU-^I}(*gR^Bf%%FKgbMHIC!CW~*rOsr4c zSKqRd8|l%e3sP;mB5c#|JYw6_c_nv%MUoZgyI7>Jm7LL1f07DixQM+j1UUte)MLHI z^bqLR?oPUDw*&qN;$waJ!jCp{)z(-e!4T)GFi{Vq6aNLeq%z5@80wC~7_HZCg;;`z!`plWqM7Y(%q6bahc0)oF;o!gy|Da; zi3(LKCv@7I+A9`QF z1BV~%-4ES$0O3gwiyl1rwd+EBc8B~*(?e5VXV?JWKJ>5HrqkV( zA!DWyQTfcU-YHw}lO=!w2;Y!22+uPGL9^8bVaaE?k_=}>s}PR8G2aWre1G#P)3PVO z75V7zb7~xSj-7_+|MEpZd^50{`FpItg`>@O>buN3g?;6{K|j6;&;cVttWR!WJhpt_ zMW6*6;?sirk=l^&_G$6ep9)~zXfb{2RVhMT2Io30PjPZih{Cz97zqt3G@0q*FwA}Y&u`h?u%LIJ8`ipFYt8E2Uw^9w!Cp(@yTg@C_3l++4d=Ohu6Jww z_3l%n8NK_Butz@h$$onGM;@^a33~V35Y}CQrJ7Q@cYo0#{e`kgzH(b1m_D|!Gk1BY>j9Q&1rY(s+Hz3M#yEnWuz*}eNmIAoKI-Oq)^ z_Pb(!?{0*dE_a#2-t9g=yo$PQO=cnTvzKHuD!wGH3d|wD_{?M=6Ry_|3tFK^v z#pQ)Ft+&mV;oiZImnCk4@2L7wz_*U7zbwDSQT6e5M^yuxkp=8IxONAyAN*Ez=eY*n zFz^XF|6DxYf62?9!LR4MT3(6+7~_4b+i;r$nAZk)D74_t^+=ol*Q)dXdg}#&BM7`0 zP+%+mUx!lw?t}l=XFB+Q{eVR}?f>;6kVa(;+5^1cuuAF^uNn+*dc9{Z)Frti$ob>@C{bAuAX=l<7Rq~Fu=!E^pWcHjPB z^HJAZN=17D=FDsTUev~uQ*)^854BU_os-mPdBf{+?~IGXLz$uDn?dJI;&H+MOP+~u zbN>$Bhj>`u5HG(cPyNVWZBj1q^cS4@&ilnrZbuAPgynw0!MD8l{dl-cbxEybL8;filK^RM>e1=0I``<*qS*ljzfks?v@b|G|JWz=I)VNS=x4HUCYpqymHii*FAc4%X1AuAYZjYY7*ao-bFAH{wF|cqPtNQ0iE^;VHUTMc~WmVj2HSZNTe>A85hT30Nk*ooQbwB&iypyldk%{{LRwdu8)+eX4GEYS} zPSod%%+TOZli9)$sExQ$Dxj^FTeiogVthPTE;q9I11wW-CjH!vQEdPEoFY9Hbei^= z#R>FC(dU)p`fkR4pVH@7n(yeOK1b2$4R%~e%jVH8`%1p&in)AK*$sWZ)LN?*>v*h} zR#u92u!qgu&fiP9{M~Wxcy65oLs?mps>{oco18xRg?QX;Jx|6pLmxn^{K_gC3%B17UbWOuRAjF-yQC2~Z*TCUb1b2I*(Or?##`^Wk3w^S}z z`4FA{l&1fhNxy1b%UyL!zvJ;y3~`+oCRv-J6H!V`OfJmt1tywvzQ|GF#2(nESwrQB zOO0ANgvAmlecT{Cn=5e6ZL4>ozAmz+S*aoJ_% zvgk2TY)TlQj@Q;?oR%ufoVYN3SA6nA31p{dage1gC$Z>o?!?qu5rV3cUw2q^#-n%) zJPTE5dpr`a6>}AgFltzK;9uQv*c(QcN{%*)Q}bY%$e*uR5MxMQIGzHJCJj7ZLd#1P z=yKFfpiQ>wNfV(2=wJ6WU@Ykt?G`xgH7@@?ZbtNA`@pP}sYpV41U>Zv!3%dhbt z*6&kw{f^encgcKDo9{c#cY1!j^He1NPJc?jt)61m57EWrJDvV3gIQ=;Svgc%D>aMt z==zEJEM_lLm|v8=2+b{r?%dU2*|}=d6&ncB&=s0D zOh!FkGKzcENKPbq6%CB;lzI*omz#%jUR@@AjG3JoPSp;wXzAP1qTq~Z^URYGmaoX|M3l;sc2ZgG#g$d&H) zf@FOg@+;Q6ZauQE*eF4haFywgWJVNyd0!nCtOnY>g71nm>I_Gsjd7?pRddI$KzSGC z2q0a)g4L>NI&xY*XZxYZy@SSW@R`W3mY_T6Y`suD0GUor9^<%dxx+pPW0^q|adJLyM7T;Tl1R3CDk7Xs>b#O1xmYQrJ5_l zNGNie{QRH-)i%*CZfdngWBDaMal^ii7k$XstK{jxwPY};5xAYa-^yaC>LbG2sfM} zEfspj(Y#Z7xu{^-mRdW9;~2GIJ%zbPtH*T28AuEzT!F>8m0Stt%s85bF+wDSkQI%N z#b`)qk};01%$drgE2$$!SAzP)z}Oi2=cAK?6#l3>kkSW|^}Nv&PH$>{%SYDUW#{+O z_~=f{R|l%is)Y`HHe3&P;-{n^d-r?T0f}~O+=3cK!xkFy3S)fsJVmKzGv8AvSx`X&$YmXa*nJ)Oxj58ymywR&$NTGe-{{Qge7* zBZCy{!^6X{{=$@9;6OCcv|PQo_O#07xOD)PrB`+7`fRzW6Zvwh0h!$kKnmXi&7J+# ztUZz{kM?3MtWCxWC7V`Q60Tzefm)c4t_>hW3$(q@!}MOQTP0LQig}7>U@$P;X_NLN zMaOd4=&jS0TB{k!kbHG@y}(Hm3vTz>#Hrm)D}70U@!TMh>1G zAp9P$j?1H6N4WKa9S3F|G4dmtFZ${p$v<8_WyAMFjP@;2E4NcIb)JS_$89e*TSD)L@g1nKglK@+IV zHfD<|ku&msY-|}S*;u?cSAc|Rf;U%S@W&b{sUjIK3OXgv=Ys8u={c;j!mSD&OqhgK z*~QGJbKd_a`xI7~OwY}Gb{mlI4PX45&HM3rJ3jBh=Y#nC0zMzd=Rtgq$&T09*y7>E zQU&(f=3=gO0_DokCnYt{#qMJ9HLYBEky|bKoa~TE&wSJ8GrO-~*ZX#!pFYL;OvNoa z8^|osJWLr5^A}B2TxJ(z2*F0PMBN6O4%R)Iipj3hD2tt&8XaDN>Fgsom7=c%eRC<- zfFdrI;ZlP_Tk0vs%Pq)H6}+l=inbQi2V~ZACs5jK=`^k(yUDgpq6P{cGBl7^!HZo} z;D_2?Y&KtAgHS=O)mTLh6y~g(oD7~{ZC+Ex3fJh2qTLx#Qpq$oaZwomx%G=ZB5Im; zvVft2O~c?8kh1x0s)jinWw1%V)M_?ClUg0NjA8-1?SLRVzcF?Rq`WK{%dlu1ht4gA zQ0SttLe%P|Y900yVo+IWKxH46xr#Nk0XFnV;j8Gfxv&Z3bLG;K*{=Yd1!YGd!335S zm@NY&bFC(LI4S7oLm!KkvmLYrYp_b&o9z5z`O{>>PPP3t3X_uZ>-XA;*}jtRZ2raE zy;S99VXj`so(CSmC15c(sow z`Ad~NG$r~fm|+HeXg$W(GMgqGm5dHf8A*OW4+%zm61cjENkdB99Xi9Yy>hG3lE%iG z*rCG{v^dn^xE}by=b=)-2HAEZE4r1kJNJ%{SL=6+gdkpCUW`skBbKE#fp5sEty(7_ z*h$1bN4{A$JBai*?e`L1V9yc%vL&uVBMA1l~N{z^F zIFN9)4eqc$M0T=D0kU-As1sE{_9(ff2jN_3iivL(SmHr;QF9Q-w6cj>8xKm6p-8jJ zg8}II3yB#n7R{I1WuaIrVsV8z%o_Qu2N8?*&TKK3?~}n(o4qvACzAD_S^e*|`lLeG zB0sb_aX5+x{d@NLp?w`D-Vf*zRNO=-%A;kx?TI=d>B2kG;5q8+>}!_M?lTWd)f4RC za2KWK`VH5L*o~w2O{J!3J|;l|mbktYJh+Mo$U;f;sHBT#n6|2f$r0{+r6r zuBGrVFm0u}m_z03@pMJYNf%hZO)4+2lLqgIuN}8Sabl}(cF@#44D2dGbW+p}^t&~I zqtYQp#|X4jc0|=dLTkW6z!63?OW7&0+uxC_ZDjE;GlZI1$u9a!x>=hk2^U1PCxA0v zTdY^@Zx+8GG9WGAVNA2#`Y-A4AN-C#{r!J_{qnf^K4o(x_72nEb5-#-l_%?{1hS2= zcOh}awHCTWqgbpE#!e^VO?l4%$oKPHtlFg=WS_I3f-dfjb-GjbYN};%%!+;o4V7kwkhL?!ltwYq^NtLjP+mWf|D2&1%R~I zl@}^>FOPn?tys3rarCh~1_MA3q5y!`06bYsf%HVr$_?sXxjvAFMbsb-#AS_!CeudR z3t1FYWbs4t_kkp`CiJ!C`an`URQ{fReTV%CwXY^QPuiae{~v}KnoGi2I1$1-5N^iI z(;xrS8IgO_>lAVIDhv#0wydxU#iiEDiU@Il@<)l4m@o&4WEFlk)b{f!rk4IsYdqPS zy&;uZd-7foNFI~%+-v-iU{YASKeHP93KGHlSI^-Nl zC|!IKagxG7GR+P1*@nqP24V%HS`bToB+_tY%1Z#xg*k;`EqI+Bv*4qAJL!;76Wv?< zXcHhr59#f6Lvc-XZ*B2_XgZ|uH<@2;(zVV%qg@{COUAOz9*O?fX>$R&7NGO38QE#Z zuAP4!vaxqcne7MP&R4vH?9=+x|C^4$-^adVi@;-cp zdK_+}>LvhtDr~jpr~qxyu3=uyJGJIU3>H=fM4M=#6FrI}qsf*fEmD$hsotdFTdz21 zZP-uQ?d3|e20OQ_%2Kv-14WHj7oRP)t1CUh(T<*WQHrz_Ik!|_cRF^hFh$0I-?vD| zj`etC6!@^g<}p#{;6rUzC2OSuETVQ9)=YFwc+t>`$@ManU@kJ$U^-}E7+rH8Y@;uy zdvag!F&0G@_XZBuNI(mNvtN4QUp6AIC+?tF3cRzYC30zOY_7PrA7q$>8qb~{gJH4- z=S)&V{ROy#A+HiUqF>%PU(g>SfiYbLgX^ZT_ANo+7(XY3DcVk8|fK&1da}7mb^8_Pfn~ zsPCsw>G%2G`NpJ&^_~9B-aoS2R=SC4tsrM(2Pt!3u7KgZ1_v|QQ>*acD+WLI;LJ`X z9z+V@*yOS~HmZjkkIEqyHnm&@1zj?LEzPA7)!E5Bn@H}o#(RBmtpf@cjDg_Y_M zPRc-uz^Eg3@d4%q>!Y7@=pX6Z>HILtyO7n=sC zq$cI3mpbILRnpHesc(8IjoX~MSNSG-F?Hv#yAGjm&F~p^cuo&sWBQZ%2T824*_hhx zqqwWu!*@U~IUg%KvZ&vH8oZLzv?jvUmD{!MCCbgWol~cz<(UPHB6xQid7r4q!Y6)x z_5?F36n#~lR-t+N=hof1roah}cEnkC84Y60Seh__5o@wT-U>V{1)9^JE8*wX)8>>4tq zaH;X@pHc=e1FQo-$_YwY2BEEG@jUfmNGX9ZsSFO5uR`rpwb2d*DQ^%3wRI0l;Ds3N zYiU6OoKWX$z=PCPaA`1Pc=9^#Yx8lMGx<%!_|?U4%F87=!)L2kSU+g1Pt2Use6O_M zfz9D~|zpsxQ5Utic85Je&(|n^qd^;ZsPAur9$TMFos6S zL}9QTw_x(`qi^a$b!=>HeP6DbJKSm(#enVhp+s83K^5tou#WR^H98Os1w~BU^_NQ( z7(~VP?`1YPcYwnqqH%LZ zt`?wL*nIBiPMa#wlJ$<(TeR$;OCIBoD4zAzJE(Cdgrpoy+j;FAU#8b;M}Yo!JjSt}LHN5Wd&V8nv} z082A?QLv~}ztNvk6%&WTib^;|s5x*F_uAzl`F%l@92~eHB3n1B4uEZz<{?hPB1Bv& zO-}SeVG}CBk4O(8Xi?6inpN`4AG4q{wI3?3Nqh1Ug{(VVgrq*5!9H^QASlC#sT~b({->(BV_z*bKJR$ zXo8)WfRWdNr@G)-W*@V)f*)ma^Il9$ADW&y;3mUneVxR%qf4t!beqJVL{Z_Egq%3S zU~S}%$BFtKOLIEYVZH@JbrGJ~@u1QY+<_q|?Kd3UqxDi*Zbc8js60uKvVCqqB`=5} z3rR&Ric`g}vPnz}Gx~89cLn^+?eYRec&z^7CFwfT+c#oRr(|i75^>6O|$XCCp z=ZWokiKsB1_)FL^XQqHi|8YHb2$FifxWdgrp2+57v;YqA6c*!+L!N=Dk+v?x3!!vh z#ombTa%^6?br<#qAgg$uFF6qa6%gT?EDt(QSmpQRr68D9UgllS#l8b~3XHsB#z=Cj z3#(~!+rEhHx0AP>k}S0kdFR^}2!!JU@oE-F7k7@uiH;A|y#jTe;)<{1daEMi3N*q& ze=Ph58S;Vuyz*l-s37Kpu8U~{!E7vWj2V}p7<;WlxtFy{%^s!F_2rAu0vT*)y0TpD zS~kQpRZbdi5h$91~rYihK|8%jg<;*nRI=w z+$21RD?Ad2Wo}E{Qec9FHGPyFHBcaF{dT%?tQE_xHAc+pP&NXCH{yfpq3q%qkuQi1 z>?6?sllW&`3>daChKt-Eg|<{GmtIS$w!#Gb^V8N!`Fa&Yvsp(FEwF^m!+bs<9N(-|*K+0cv6yf% z=&^Jg63Y_9k2PU)$wSSn+ZXCFyB$X+lA1ffW0kfTEmdIXn(Rnuj2KaYwK^h&e;wec zvK%0m#K`a}=~Uj!V%n7y_hE~Er^^{77Ywg|r=2I8+h@PW~nA2|BN zp0OVq`Rli?Pu(Jhg@naZ@`#7F-OIEoRjO*U?-oLcd_RkjEw`7Ns|z?hm{SnkooD(Kr;CCU~whe(=5HDDw z0ZX{xg0N11<(DH^@X#Sqk9ryrgMLPsx{3<8dw!XyFl~==%M5dAw5*^0G~U41M6daPJH5t%||}@#OB98W!AA^=?Ua5M!39;A(W$$Xvg%-{)ivw>r@~^ zjM?mHM}%dWLsLWHaPiQHQm`a9>90Yv4W5$K4bWUn?uXe$P67)S+v8Dq<`2nPUg$q; zrj8_5fq&iMRm5V82*Lf9m$_pAy^FdiGIEpv@NQ8K$Y`r6;PDmwhH-BFY_L_=uCnwj z&@^W|z?@$yR*sc$B9Mj(x@hOH$H7UC(cw(72+Y=AZkb`gHCM8BFITY!6{~Xxu;8tv z;6C-;cNoblIgpfH8ls4W5fBHGWMBvXG$LfZEmx0rtQN~P{Ee>J6J4_!pe|7zN2vl`gNq1Jht&&%d5lxNx8p=R+_P#qM*STe!1}S+uuE45}g$9I$Y#=&>LpZb?$m)2Ikz=T@ zIWQvF7&4aItrT-Sch7O?$v**q?)j*^$47`V@VUKynwfNEHy2Mx98VzB&L9Jvx-}`-6orv3ZTuu zEI1P`yFCqFJb^(1;gJPtJC>TYGS~@YNFpjgyUu}+j$^&3u9h5Fz&op|%*08fhhaQH z%v#hj_llHpvP@cVR3o&yTr!GL&_|Ukiu`J|lrI7xcbP~@CG4T=$Z zWJ_BH1UqWVOEa(RP4ySF7fNJjZIRA;J9GvW+jGDo43U-Fn_wp!=7 z+p$zjCAwi*)Az~|dvmRVWb|Q7AdCkqQV4l`>A$T0fDT-&!@Pj}N?L;&*b2&&-%QuM zOnP;JlR-DIirRqCqcp}pUHpu3& z6Ox9wB(2RR4!RKQAw-stxY~@DVTBYAl!cZOY>W6hzRh`Py8cRc zF)+3GSWhk|d6lw4=chrpOgys5MV%A8l*Wz3LbA%&EUY+G66_6^;q;F={h9z2LY@se zZUz7C-I3oeoa7CmHmqe1(e`0ER6;mC^L3_t5sdezH`F~T!ES2Gv>`5pL5D%z7e6e? z0paG@9lxb{kb12(>P1P@w%AWIsS3rB>KGhZxL|Wc4y1^Whc+L(sC453vPQJ?CmQ8M zqmz4Jxzr@EMSP)lSo)ud6w8!j@lo05@kWfQd8SdahD)YL(zt1za{^sDs_X79+=saw}$<3+7Qpp_*6t zg<=y7V*k}C|iL&WYKcswCy$~&}n&W_ddj3#+ZEZ#9^)CGumhXpysO5Iy9eEva4dX6C zj~DgabeBZ?U^_991QU>3po;|cr5oDNyZ!y(-YP+mh=f!`8>{o=+}w3wGg;-(_FfMa(7p`a+tXmd7u7d(4A98s}^8(Lj< zcj)LqNyNlS{3g-OX1LypL`QQ>vi^H){lH2Kv$JlR)Atrxm}3gPRKQY+Fr@^q$0JB4 z(S6*S_xN@U^E0}FHZ?2**j#K@psj2MFf_N@5NA4BLgEZ?!I)PNEbj;p)gLj(MQg@R zDC6u7z+6LHvR|KZi$#^>E(rYj^#=V_jiEcx@2&zBkABiLx5 z#?9>}7z~YxPxjg{?`pbrjgeFcee13QJghVahlyB#6-8$3hFvi&9)Zp6SQXbat>D5| zMQHIT1&2*!2D5aH;Ea2`vWz&<(cHr1qEI5@`^5!#4f3cVZ1)H=)<82B=TTvPb#Xt# zt3~s36NgQHI0EA)!TREnR&%ksym*_|y*NjYErj^fmy;#bS!$ZnMvi2(N7awza!&lg zupc&Z-3gM3F_XE`njIGw^hO524_ zgA8^_Xpk?f$O3>r24{0QP&28+2x_7d0kbk?CNDsSj(qJ%{E~QdWMo9<`0R4Ye2lP@ z1<1liDUUdj%hh;J&jOGS%!p71>IYi$^PcbY#oZYf&#e zSUy1`UAn*eJ+ig|fEMMw-ht?v9Q^SVd?;Y*mzeuJ{)K)|C?$mga>3UUG1ld4BD`Lsi4IW@?G;q*`97FnI)FO};j#hwE z<3re&^2Y!e45KRMRBYw~jCpt4s4zB6gBa30J_z+hca>!+tn)gj{dlm=hs@6Zlz=O+ z@0ou@Hkqv;=+c!X`JiW13d%bi60#bz!&8P!L)pB<@nR-%Z@ggZ3oBH%pPB7M-3}#B zChrP^C|NkdEZOKR$>{9?$-+QG+y`-fD zX2`_OYbOFB;x0dGt&lqxYFI5owb0Z3zNpy2x4L4;uHT0EazJF(u+lLD z;vfX}3Gsw->v_^WjTgo$RSQmOK0ZElku%89pP2EeVe0eCWst!WQ2`Yk9sKfrk->xL zQ(@6gU>SIMWbjG{RB-rkL}g1`8A~E;Jt}0C%OFEiHbsT3@_msZf#_4g$ZPbc-;RU} zl2SqIG3Ub(6W$VBoW}@Zw|1QScef!F11EU%HhnVXJ?>V(lHmC zEz0nkm63!%B&S`<%Wy>(Z&$K!jQqCr6}jtPnqGr;M7YvC>1{sA8k#B|a$8l`hg;@Q7`4K0fJ_Rv9YKvR*Xtu`8%$E%{jH`PB|xS z)O@Ix@DFCxFBjj7_BS~ACK=iccj0;2_Pjg~=Hut#lKGR-$TFHWJ&St*&EcB>htzqm zTD82s57*QqQlZ3ZKT?S>WZ^&wO+l{t+pCv5j$v*=SkFnad!kV0 zyV+7+3@*t}Iv%X?)qEvagZDv`zcIGpQ@b8fNfKxi5Gd|p4%ckEhgrDlp@e2TjB}e} z<;qJbJ|3+>gTi9p6<{Lz!96FXi8Ab2NdmEEg3Ajuf@fe7JOdd6;5J-fA}zMfnk~b) z4f}v13SyPjAj)Cl!YO6Ghgbv7rDb?7Ozs_vk51xh4AYoM!`cKi7`RCw z8yA#Z(H_sCcFY=>nZ%9*yNu#Phc7Tb)*oU~VJI?0H>g+FX{ph0GgQxbupI7EXuSbC zY>givhlY({H6=vcY2fN`_zAJy3s|$loXKNttbC2}tITD%7AUiI%_r`gm?f8UjaAT3 z^82J3`+on)JAZH50TX@FSlJiOb)k-SrVlX%KkOJBuEN}xbdRl*i*;8k@2T?ozk#Sb zx$+oHHio3)tVkoID`9BF>qh`z?2KAUTA$)43$Ht7nk&sXS@4z+yQ_dBatI`_H56UJ zu)QvsgUILVH1S-*X{zOH-rSr7Rt$C(?+y&cqBsg zC}_0WXmohgq(E;%BsMHmRo{(ds~ZdhgZ?tEoioozY*<0_JiEFM<0;%Or(^@8j*Ybl zn^G-ac!^mXw^5i*5@fZ%_|u(AkVBH`bc=&)re+6Vae+%EbEevhyK`k)kk%RSd@)tw z(L-&tNj9Atjm7Rw6c0w!4h9-YUd&b!#a^7uvCf8lnYAa@baT)bh2RCJ124uugC)9O z&QE#=9&mW4?e##(ZoP#s#{d?qWd)1hiDiSk&_O2>04x&mAXx_{SvdofypujaiDQH$KYOaKq;uaEvujmzCt)YC>tmu{$KnN zl*>R`@a|O4p!k(yQxNBgXm9PDkG5@VAhFy%!Na()33o0fTa4He){+AadjF^~nx}YH z=rgcN-K^CBzv;!0Xu5?jJMpvJQq~?DXvhQaxk0@+daI6yLn4>rLJPNqvCH&qhw>}) zaRU!aY4Tr(^0ueU(K6~5uDFy7$BporU|~5$&Xgh<18944<)sBnr3*d)MnsyxsEqa} zCIQvu2A5#q<94wQO8Zt^XkB7MwnW+M=xB?gFy{dILW3~|=|VV1PmFkL*~F$>$ndFl zw!K%a19g**YaRHOXz|dN8Ie*u^G{pk>`)Dmboi-&c9Iz4(riWZh%SEPR3$-n$q$8< zX1V}-umIVd!X_3z=(D_ZvtJY&!%&<>VLmiHzp!}l$f12xbD8)+S^@iI*|moNrW%Ju z17bX3pgBx19_}v5op}^mSR@(7w%aO}NYH@p=FMkD`q^ zF{;f(e%K$Gne3z7kcAGMuyV(U1(ZU#1|fWi*pK_F# zEXcFcL17@=y}T9CDxQxoMe|dW3)4qtd_EopyY;1P<~cjwMZHomL{|xwNv3&#LLscQR-Djf{D$-93K|{ zeAv%nb14)&K)2%z&6K*Ek?;Db4@M9ZTB1YETdfv4mo|*d#SRA^VVZGhlo6}KI(VOU zeDvhGYmW&HPTt1b%VaGAH0-RepR9!x-Zg~(*HTOXZYQ`Lp*?m^D z;aJrS^&zqC!ARIjv7}$dIHZz+=FgzAK(-@{uCjiA2IY9%q*W=Ns9`u_#7JxpTM(jF z)v4&}=;}DS9ZtTwp0tB^5QWix?*)dWeaYP|c|#Rch+*F-&AhjnIk1-ENiD>8DwmI9 z1H38QPFP@Jd#@@Q26CWwuDRxoj~*;3GEdN?03{RHRFCh6<(11;XyXtR;=c%`-0A|7 zDm`fX!%%cg$b^2&twD+f!VZfXCeMJbvpJm0gMqt-q~_`&4Pi=ycN9^t92;9ayeJnc zFTx8hS6(DWSe4;~z2O?z!_^-gTC1r!qJdo0SeM8D5ylU^78_75|7=FAr`i14lwVx- zuMXxK_RQ~407qBS}5sklsv7O}XH zA7a-yQEt`|bRJ=_ZksqXy$|0D(Y_-`_a2&x<`?D=l0BN7oi)Gq9yxL-+JAIra^c8a zv~OyDa&CH-)3#mJXg2pWH9Ijk!K_^Q$RGR4@D}c=I5D?R z5~3dktp9}12k`lMd_IZ~$!nR4S~NTWVK5hifd)I{tYG>e$S1Z+SmLoaBJtEQ6&v0J z7_r5Hssc%m%9LQTWY8`i5g>R7NMu-?IkIqhjO}*%;pVHgb!-kXr^NVu_e~p{FWEt_NL_|6zOv@cSe_>Gt6OQ*GT^8ew3> z2&NRo5q&+v2Zu6UVc7-&u`=N7(O50yRrF`c>m=1#^zlU8=Eno@nJfj`Tc2p zzY5>{{2cP~^Cf&nQRX%HTs@_qaeUu}&k20m+6nQBt_GRREW$YnjiGde)m>*a=}?~H zQ%3O_0kW22SfLoFtAP&DLjm@f#O!1t*>}^(oj8s!_ftzU>_dIP4?}lydjQc%+u>_A zdxvXp_*9567m7|GGbwmA;aI>o+)M7}dmxK{8Thgs@+_IbHcZ@7X|f_00A6`Hn4)n? zGrNR=Jh5kQBBPlu@yc`VGyRc{cG@XQD)msWU$D*s-V#yO@0XR1{gSRH?3yI1YF0h% z{nN9awk}Epibn^bBjc}TQn8dp#ms&LU-ydQ8kCcI5kw7IerC-)Bh_dBDHK`j1T2}^ zUa#LX%0bA9F3M5YGa9V)6ZW{dPys8LBHiQ1s?x&wg${$0wVEO^MxK|jNjN!D0Bsbi z9YkCJCa7V6=%Bh>rA#|r9o+s&+i85FUmY|{Vjf`j(S#)pjma4D0iR)|iFOksBmQO0 zi&S))DxS_hj|C5B#Jy?a5Ao?xHxw zG#j5aDBn<~jULN+PnO1^{8Qc85X7@VE6O5Q85ezBw<@sA0F6Ni?eU;qE^#`+5n*bI zCfgsK$m`2z8J_@4i-2*NN;6aY2=(yt##so(GEp*hB;z!_Pj`259ig=3^lOJ*#teGM zItq1KlX0*v(fk7lV{6Ulve@V5686h;rj*WBVs~))KuX?iNcPo3TjIruK`#n`g`4b` zP(4W1f}B?m6re=1Tf|DvQBPek$;h$AlS&%=2F8^gHjhP)lr_3&dVdNBf3F|p`-Lsbg!-rlx}6E!P%X$nTf+R=V8bq_-e0DG&6O3v~PNT z_Rz$g(bOFaa}&O~E`nXovzSG*bJIuWrWfvv7Vey#f@gKEutToODZ;Opar$uUg7|#* zYM0^LEj16a3jf(GRcwQP6RID^S^g65qMKBoqjZN8t3PKcewK8H7^q{?979+c5%k*Ppx{cRT7_S*5f)V2KdLE2`C83nr!FKL0Vp`h z^%@)$m_?R=f>Hx4C>PBmhu@y$z7Mpf!-XHNMAnTTS^XjNTgQ7oyk#StFWc_=03M!L z1M;N1GzvE1mH5hm(pdE3H*9Q<;dA91H#YwopR3-yvH8F8`IjHm=biU%Y`*7B8=D_N z8b9O6o5$xZ`1~q9e}>P|w`^>_5}$YA^MCO9cW;GV^lclP|A^1`{K&@UFXQ=Ue0~F; z=e}cO^B<5l{G%J2tN45spRc`rWAj|3pN|jUe-LTc|JcT6zxy#d>Y|h8+kDykHKVrs z+l>D)_HRIjD7sx;EUf-uHhDc@sq;8Etb&z0qMc)@fXI-me}p9j2TW zo@I^}aPbSanNnZ`0G6H5Nf)g;0fI zh_NN$DAOz+S=RGmK>^JN6Am)i+?q|w;2ecVCyS4qz8u7j*f|@)72Y;V6N8(a67q{m z&?{);a^a83JIl*|vNAEWg1sWoFEFLo=5;KG16Vjw!;RTN+(gQI;lLSU#UQl7_a|o|)!>OmR-MBNg zQ-L|YlM*^8{Ccc^2<%GSbIPnxwsks`uUFCS-3rfDUDbZQ@JBD!JJxt8=L!L3zZ^J* zB=yJxBLY~D`v*ROzlt>2DZ?Er*e2?W19pb7#~WxT{V|Lx_a=w7@FsrXmFb%>MltW}0Vjd5U z;0~Fc*9~bt3toX4$sjO$z%!yn?^_t55Zh&8?JKQJR{%pG6mZiz@7TfG5J?7gw2cIhw#`>3qkIDg zd`%=Na8gs92DS~1jP7b|8`y=s5TZCEUl2wbjf2OX;p4ULv5vFR)x6D{TWa75C)}bt zqdS1a2y{sQFRm5J<0byy$v<~Ql#7s6NHf3gv_I}(hB^K@6ab30iJ*$MsrZ3*1iiO$ z8=fH%@Df8De`Tm3&3w-{5vj7-7#O`C%@iItKV=x0gb}=(AY0+@ZTvE9HtduPz&DMD&H;PzjOwR_T%~{q-r1wlevPTN_Ut&3K4WvCX5#3 z4}XpTaQG#u%rL^*3(+ymCsk+~i-#BCRamSy7jrEQ(8J-{$2s2g{cL8KyRXncWv4kH zZMYFiPTF-OIM2(o)Jay)%fo?}^Ipbi59gP#!0fI0=Bx*B=QNJJPK98+*Vj(>QNYU& zaHt>z=ifg%%J-?)DSsCF!-O6=p}!3MT|y8%FFP+=X4F9r>Ro>zhxK6Mp(NQz2~()+ zyOe^&?UPkURN=i4cI=D15jkR<{}3exk}J|Lp6b)>9b1_J#HF9@5yS+<$^pv(^S?n$ z7lhY9xm*~=WlQ*ic&p<)8E$TtR9pb%KP@30Mi*?7V@BXXLHDpytx6&y-X4&jgoOus zuMoWMq@fg}mRNj9FO5?Ov`lD6`;Ol&Js%Ze`vEuR-MDjj^!k?$j||^95*2E^xf-Qs zy?d*P-Oi_X-*iVf&hXkqK&!l-q0rfp6sX2Gz-tz>Q{!?Da)ZxU>`Kj4V}y~vyM?V4 zMp(jMZ~$&Jz|xsVm&A~({wQb%jw&-|Bi3hh=u;dQjKkm05>Dt=yts7UNp@`nvXpYnQA# zsPBo%&f2bIUc=;!ptV()FmNy$p}??apn^kNWtqzXvDE5y;W%No1Uew+aAad+%%XB= z$nbeb)hOp)ER>+e1aE+_u8VT@d<-{2_co#boQ)WkY7?5L5qf0P4D`a<7zbR6EAch_ z0f2x#jKE{KomOMvu{lkmkWeNG`0424>Puy1sooVPc)R|g(cbg*Oe#+x4%$;%Sa!&z zTZm=~4@b6`o|Bz0X$%d=_EeMIUv%wo^*fj?KTd${SC4wK{%9{RH(=3M)By_ca{Wp3 zJ$9*~P{G0<@3dWedCZvwZaq+%q5Y7tWOZc_Zm&=IQT77X)^PrlBbA<|A`(S)!=QzG zyK8|Qa1wQhaw5;!Yq72X%!~B@yO@5n&8c0G(`+ACTM?^q6!k8bPJ~26M zGg)A!K5yp0IHn4()bIaH`%Tf6roIJx7l<9&$^Ie4yY7K`n_=#ZNnhox6N9X6{09RV zu08aDAu2{^6Oj$aZk%c1u^z3zj*&uFZ)U{o*8UopY7QwbUh1Yc#>Lr`gwMM+au-@tHe3iN6O9OhmH><_=HE-~j%`(RD5z~$8WTxB{PmVDnGz5{a zei5DAGKN3K@EWdinuzA3ndtUNdf?5!{N(13;qzX6ejcA+$LC>u{urOX!sko)@ZB<` z9yko^nrI&YLQ$BHj;vL1rXg3qW^UnD2B*NPjp4MHODA}Ao=?O%$h9mcgMCyw=8E~d zt30=f0OA##Jc;J@Zbyh%vz8-2{rX3r-24nazl+c3@c9Bh{}Z3n`1}h#=YH(T&1d1m zylm+H(h1&j2#e5gJP%tCqV;3##v2X~7olp+&&=ICFnrxIvrB%MRZ7iP0aqiAAek!h zA-FB4l4yTIL)U76W6B*yysfc#_iD3Q8@uM3a?2`GpljYwhMruJF=pzq@twu3KUU0QnokSWK>zUHQhI*PzVy?-^Le)ll+} z?VGRRh_@oUb`9Mii1u3Pn$;m`&II;rljf|M_sa+tfqyKIja*(T6mz4Py)$??w=(1! zpVZTqk4D{8M#2-Oi>E;5TEh@=ExsdGwB*(ULswJ3rMDI|4cShjW5XN$5Tq+Qg7>Ul zB$*0L%xD83XuE*0F9?Eo-Ud4oL)OH70Gi!*WLC>d(SzaRZQ&zFLp-lWeT0%EhqyL6 zR?=?61zp-Zwiiq%pbM@Mn>n~P;n{fN*b3McQ%-XjjV6iY8$jfnXvIV(Ccb3+7^sj{ zv4J+m3o(d2!rh?7V>{v<(VlpZ{2qvR4qp#}Dqqn6%nOvP@_sYv8sTU%z{YG3ngfjZyUOboq<8 zyaYDjYA=T-5a1|L=idmgNdwd`wcyK3l&VM_`#Kg{v8q@ImZXz>nhqL{$vyF?h}Xq4 z@8CeWHHHt{t-r9T9N!agF=hMiON$}7b*U0(aA9ROlwgvD=4 zb)a*RXW!zQ8O&mcivy!|6VlZ*t`Geyt#5t);F~{x%M<5}zw6c`Umx6a!MKHFzRlO2 zCVgi7&}08?bm7?Jd-&qf=jA78-}ZaL6mVam{d<)5?^KCdSyJ-aE4@8sD#DTyysRL& z0yp{^3hSF0E;45hPfh4D@P@-`3rktHP5F_e{B$1$!}TrD)he9^DX2l?plVjd_3JCO z25(xFAG}Z-7b{}z)+`>VHE;>zK?LOwQ(R`cx4`PkdpXMy4BBgSz{12|Dd4^w`vT7E zl?aR>^NOq07$@np2}ZIJCP6Z>03)^|ewnK>$81LsQC1o6wsqWND!1RP>mGy1J*e}R zZSzHjzNDnLI;gnJ44OM~al*}@iy7Y%BHoRP<{?gUWj6JeZAY=D;pkAY0-Fi-NwLu; za6G?7!XX_!IDDJ~nL5Cd+_)a57<&M1B-W7l><*|w_^YsT@xtV+r~KOC#6^~3s#m<^ zwZFMY)83U^zzrm&aM0~+xnEDxerY)5?GiL(3e>QE_yjJSyOi-_*fj{s^iVW;!QQeB`hj2{#2j$I7IKDMK|&ab12GoK!yB^_=*xnWJdYWM4o(h4(T6UxqZanIM1Em= z526#OyKaG0YLizPc@k*yYy5)?cTBwO^DnyivwQBC`1Z9O-*we9KSFu_y(hl#OB0{^ zh0pJP;g^4P&%JBS|M=n$)W?f|cKaWG=*8c@CtCRYUCaOFpZ4C=*!xR`cU?LDdw0J2 z;-C1;w@;xLsG~qXk^fFF(K^o`*YC)DpWbunj(rRNdil0f`u&3OuRfT6;h+EXA)Bww zpUjj$X}USp*Oe;$^o2xGBH*3B_vBtmBg`45$roBij< z0XU6dK2HaLjx{K%UOgyBWV)9M^Y4Xi+hEDLzMB9gGlum4OpjK#9)#k=#i8%bv)5lhz10{b`~u`+*2kF1s!C|79q0?pdOvW{U`?ihxMi`dfgn z7rdXaB7;ce`2|kSYc+YmsIb}Sa1mo$3z0xDDJ0>~Lb!+L&kDRV!HMm}amQS_Affqa zkYf~T?v*DgTc`k0?z!KU1n_1rJ`H_YJKyNTkVB);4^v$f@JD-p*6Yh^bWQU0frrhU z*57~cclqyYqK`-83lg7y+N+|SKdC$?IkI@v*2V7>{*0GD0o&hkKVtshPXF!Z|HkKQ z_?-8>f4liye4dX_jL#50-JERt@tfA%{PB%eV&E%OYpf2pCNp1 z`9bgpzCVZ0>+$<9@%^Ov&F5a9pGV%0;qxFqzk?5PvHybpBx~QAbQANW_?Kb@6JvPS zs^r59IxKSfv#sV9i|UvvckO!{SIg$x+I_3g@&+18(oBT5x6ZzKo;oX{sW_VCO4EKO(TzHy}{YPysn(Wn@tV9d4sCUF;lIt z5w8F=CAOCU%LmS`$R^NOjHL)@#CeWqR?%=oG%+WBkcb;n+?dNPVJ}s(z_XIBH$@A@ z#%VV@ELin%?#zRvWCI!G!Z60RWQ(V(vi!54+7qfb&DK7X2z<~+L^bg@BC&qwrZ17t zH5v$4DxNvgCFlzrGQix9?H+7bDF2D4fz@rW^#`8>Vk=Q?Yc2S3v=|tS`-pg>JDF0a z#c$rUV;KhYni3B#SJ-l_}lgt;?+fQ@9>#y$r8A9thl$uAiMLtkmBs& z=JQA1RfVX2tP3_h-hKgg%tq43Q>4&0an>Z)}fYj_&v#cvV<9Cx@# zs3)|tFS(FWuB&{o_zFK_WQ*mlM{|ApeBGqYK!o;(@OuNFtX^ zJkp?Di@gU`7Fn;_#w-^$RC-D%MGPRr3b5hf!Q?S~sO3zA;hMasb8uR`uJ~cum?1*NT&mX5b}x2 z5DGZ(zCcfUwkR-JTZ_ClL5BN(f8&u zq%svF7GynbQhIs85|ntJ`URk%T$vuJAiYpZY*9_T?x!Uyl- zIKn=i#~mFt)lnwo(4dIdem6@xFl2Hk3_9|;SI+%>S`2RJ<$z#MtB>w&?*?;x-;5gN z8*Q`)+Imz8{W`WXRZQ4d#-YAA%GueGOVglnbIQ%4xn%e8ne%7qG@Nh>&w>{ecjH5D z=}o3?2UdF19LJ=n!X^XHMqpV1F>L4gu$pvxMHrY_+QBu=ZkQ#s%*G)Y&EXdozzP3O zm{~jx)6MQ#@NA)IJ9~r?&@pkyT>&up8uy}sm1tmjYyhEemUrN2{ z$U8$FTw*|7T3Zp_88vjOeXuA;JR}pUWOfvKGPG(4peFUnm_b72pqG76yQf+63(}AQcbZuxspw z8-`rs4wJY8i7KRlueC$O;^2UI@$^Ti!J!rQ1R}@=V13TRO7QLFc0+%6iJooyp6S+; z<~!SO%*{-r``{j1B?7vb~awq)Ci3Imrg)sbO%i>sp*Xk{Emq>rQFji@yLDZLWD@ zVDWS?(un`sQJ64SWFe-5NHDdSwdWItg;b-`iRMX&T3Z59|4VA-!nJoU1e*9yAIH^Y z5-`pc#ZW;+F+C203yq;6!Zw32P%uMKuQd4%*#RIwyngLQpRjJW*SMW_p_4ArIrN8X zVgU%1S3|fS^Z@PKI;$O-O!~|DBC$fK8A}Zk44)_@R!b2G%)8LU1O);i><2Cr1sNTK zARazSD3d2$lhxk~-pK{+zl3YtppfelDET0t#B>BXhrNGj(3sjxitR9x&UBifDJKft z-WhHb!L_G5{9Xk~cjU|bTd2-do2GB2pCz%PF9kWecrdYClfPsNCb_|1leg+EA`svW zWXsgc&7{_rI{#^t zp$Euu##~v>+abc4M)1(QCDP6OYab`@T~FA|F<9sPZT#tMuZD-DXl6a;keFd8$U-nH zJ)^0^V8IF-w)*MdA_O^UqHH5hM!1KUC-msKkNBu}gQ4Y=UfCQQwU-ZZ!Y02vKq~EF z`fQdsi%Uxz@p=*G2?QW;=9MEw8Bme}Riahl`FjdI(lCR4~i}az|Y~)HD#?yg` zgSPzkd9EXWdK5{}aIH;~2e{Z8trLWk^9;)a129|FUVoffPgZkjuLqqSEF;xPC%e0m zOtM~`Wbgzx=>tRxGERgExK90YhWKsoj+{F9IreG8N@fnl9`X=dXOa0b{pMkpX25tW zEbDPP3EGq?jz+4Gw4$*v477}PkFg*~1XbBcqQYm;Z0GYCvlC^^=VA$Sfu0;WaIgeU z#t4nhvvPhtIvO!ZRv8~Pkrem|q^-cPV-sDUXb05L4B0aH@TeF$y=@Ow8;vAllTd}y z*bIFf-qRz<6bfw()tWA_d7vC1E;uR5+{T0n+bUPexTZ(|^E%}T++|CrT$7@5G|}vL z&)i~sYZX3lY7`kfCc#9;ydpYS99|iYuh_9#EZ5=$$Y@+%YwSF6;tJe-bekNS*6d^g zF-^jAsu5j)um)Jt<&_SFA}&5FJ3mFY{mFPaTH4}}gxl71oCL~c(A#mYWBx?8y6G@W z-->iwm@C{t26Y@VlktKqe8j4X6zD(pr&W%aA}Gy59NmIE(1KDaHfsor%9H}L{=A2n z(WzAN?si2B@Kw+1@KO+Q%2&LbJ0ADQ_60G6CYDZOjfq+o@5U~qY(+CWH8ej3@gI}- zob6%c#pWz505av{nono@)nyG}5PqoMiLZ9OIYHAiYoV?erm-He#b_R>$!-tYkajR} za3I5W5!4}SV!Ru+fCN4?Mn8odzAeeI73c&6>pGFPKXtq)4of?r0dzA$w-SOig3@{_$`v|QT~sJiwi-=_3k`-)1h{+0%7d)w6CG;>iGPN%Vw zP%*Z3P&>B2nJZC|U8>8WWH)`^SzqQTQQes|℞ulfVb=y;9d0u0+^TnUq@@Z61nh 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
at end. + for(WrapList::const_iterator i = wrappers.begin(); i != wrappers.end(); ++i) + { + printf("@section %s\n\n(See %s for class documentation)\n\n
", (*i).first.c_str(), (*i).first.c_str());
+    (*i).second->logOptions();
+    puts("
\n"); + fprintf(stderr, "genCommandLineOptionDocs: Added %s to docs/options/all_options.dox\n", (*i).first.c_str()); + } + puts("*/"); + fputs("genCommandLineOptionDocs: Wrote docs/options/all_options.dox\n", stderr); + + + /* Write docs/options/ */ + for(WrapList::const_iterator i = wrappers.begin(); i != wrappers.end(); ++i) + { + std::string filename("docs/options/"); + filename += (*i).first + "_options"; + redirectStdout(filename.c_str()); + (*i).second->logOptions(); + fprintf(stderr, "genCommandLineOptionDocs: Wrote %s\n", filename.c_str()); + } + + /* Write CommandLineOptions.txt.in */ + redirectStdout("CommandLineOptions.txt.in"); +#ifdef FOR_ARIA + puts("\nARIA @ARIA_VERSION@\n"); +#elif defined(FOR_ARNETWORKING) + puts("\nArNetworking @ARIA_VERSION@\n"); +#endif + printf("Summary of command line options\n\n%s", EXPLANATION); + + for(WrapList::const_iterator i = wrappers.begin(); i != wrappers.end(); ++i) + { + puts(""); + puts((*i).first.c_str()); + for(std::string::size_type c = 0; c < (*i).first.size(); ++c) + fputc('-', stdout); + puts(""); + (*i).second->logOptions(); + } + puts("\n"); + fputs("genCommandLineOptionDocs: Wrote CommandLineOptions.txt.in\n", stderr); + + Aria::exit(0); +} diff --git a/Legacy/Aria/utils/genCommandLineOptionDocs.vcxproj b/Legacy/Aria/utils/genCommandLineOptionDocs.vcxproj new file mode 100644 index 0000000..3a9aada --- /dev/null +++ b/Legacy/Aria/utils/genCommandLineOptionDocs.vcxproj @@ -0,0 +1,91 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + + + + {1ADA6255-2D8A-4FB8-B342-B93A806C80CF} + Win32Proj + genCommandLineOptionDocs + + + + Application + true + Unicode + + + Application + false + true + Unicode + + + + + + + + + + + + + true + $(SolutionDir)\bin\ + ..\obj\genCommandLineOptionDocs-$(Configuration)-VC10\ + $(ProjectName)Debug + + + false + $(SolutionDir)\bin\ + ..\obj\genCommandLineOptionDocs-$(Configuration)-VC10\ + + + + NotUsing + Level3 + Disabled + FOR_ARIA;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + ..\include + + + Console + true + ..\lib + AriaDebugVC10.lib + + + + + Level3 + NotUsing + MaxSpeed + true + true + FOR_ARIA;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + ..\include + + + Console + true + true + true + ..\lib + AriaVC10.lib + + + + + + \ No newline at end of file diff --git a/Legacy/Aria/utils/genCommandLineOptionDocsForArNetworking.vcxproj b/Legacy/Aria/utils/genCommandLineOptionDocsForArNetworking.vcxproj new file mode 100644 index 0000000..4c4da4e --- /dev/null +++ b/Legacy/Aria/utils/genCommandLineOptionDocsForArNetworking.vcxproj @@ -0,0 +1,91 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + + + + Win32Proj + genCommandLineOptionDocsForArNetworking + + + + Application + true + Unicode + + + Application + false + true + Unicode + + + + + + + + + + + + + true + $(SolutionDir)\bin\ + ..\obj\genCommandLineOptionDocsForArNetworking-$(Configuration)-VC10\ + $(ProjectName)Debug + + + false + $(SolutionDir)\bin\ + ..\obj\genCommandLineOptionDocsForArNetworking-$(Configuration)-VC10\ + $(ProjectName) + + + + NotUsing + Level3 + Disabled + FOR_ARNETWORKING;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + ..\include;..\ArNetworking\include + + + Console + true + ..\lib + AriaDebugVC10.lib;ArNetworkingDebugVC10.lib + + + + + Level3 + NotUsing + MaxSpeed + true + true + FOR_ARNETWORKING;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + ..\include;..\ArNetworking\include + + + Console + true + true + true + ..\lib + AriaVC10.lib;ArNetworkingVC10.lib + + + + + + \ No newline at end of file diff --git a/Legacy/Aria/utils/makeParams b/Legacy/Aria/utils/makeParams new file mode 100755 index 0000000000000000000000000000000000000000..fc66624c0cc46816f9fd8a79d76ce18b769bbc36 GIT binary patch literal 14872 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 literal 0 HcmV?d00001 diff --git a/Legacy/Aria/utils/makeParams.cpp b/Legacy/Aria/utils/makeParams.cpp new file mode 100644 index 0000000..f762c04 --- /dev/null +++ b/Legacy/Aria/utils/makeParams.cpp @@ -0,0 +1,91 @@ +/* +Adept MobileRobots Robotics Interface for Applications (ARIA) +Copyright (C) 2004, 2005 ActivMedia Robotics LLC +Copyright (C) 2006, 2007, 2008, 2009, 2010 MobileRobots Inc. +Copyright (C) 2011, 2012, 2013 Adept Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +If you wish to redistribute ARIA under different terms, contact +Adept MobileRobots for information about a commercial version of ARIA at +robots@mobilerobots.com or +Adept MobileRobots, 10 Columbia Drive, Amherst, NH 03031; +1-603-881-7960 +*/ +#include "ariaOSDef.h" +#include +#include "Aria.h" +#include "ArRobotTypes.h" + + +void makePref(ArRobotParams *param) +{ + param->save(); +} + +int main() +{ + Aria::init(); + //ArLog::init(ArLog::StdOut, ArLog::Verbose); + + makePref(new ArRobotAmigo); + makePref(new ArRobotAmigoSh); + makePref(new ArRobotP2AT); + makePref(new ArRobotP2AT8); + makePref(new ArRobotP2IT); + makePref(new ArRobotP2DX); + makePref(new ArRobotP2CE); + makePref(new ArRobotP2DXe); + makePref(new ArRobotP2DF); + makePref(new ArRobotP2D8); + makePref(new ArRobotP2PB); + makePref(new ArRobotP2PP); + makePref(new ArRobotPerfPB); + makePref(new ArRobotPion1M); + makePref(new ArRobotPion1X); + makePref(new ArRobotPionAT); + makePref(new ArRobotPsos1X); + makePref(new ArRobotPsos1M); + makePref(new ArRobotPsos43M); + makePref(new ArRobotPowerBot); + makePref(new ArRobotP2AT8Plus); + makePref(new ArRobotP2D8Plus); + makePref(new ArRobotPerfPBPlus); + makePref(new ArRobotP3AT); + makePref(new ArRobotP3DX); + makePref(new ArRobotP3DXSH); + makePref(new ArRobotP3ATSH); + makePref(new ArRobotP3ATIWSH); + makePref(new ArRobotPatrolBotSH); + makePref(new ArRobotPeopleBotSH); + makePref(new ArRobotPowerBotSH); + makePref(new ArRobotWheelchairSH); + makePref(new ArRobotSeekur); + makePref(new ArRobotPowerBotSHuARCS); + makePref(new ArRobotMT400); + makePref(new ArRobotResearchPB); + makePref(new ArRobotSeekurJr); + makePref(new ArRobotP3DXSH_lms1xx); + makePref(new ArRobotP3ATSH_lms1xx); + makePref(new ArRobotPeopleBotSH_lms1xx); + makePref(new ArRobotP3DXSH_lms500); + makePref(new ArRobotP3ATSH_lms500); + makePref(new ArRobotPeopleBotSH_lms500); + makePref(new ArRobotPowerBotSH_lms500); + makePref(new ArRobotResearchPB_lms500); + makePref(new ArRobotPioneerLX); + + Aria::shutdown(); + return(0); +} diff --git a/Legacy/Aria/utils/makeParams.vcproj b/Legacy/Aria/utils/makeParams.vcproj new file mode 100644 index 0000000..aa340b2 --- /dev/null +++ b/Legacy/Aria/utils/makeParams.vcproj @@ -0,0 +1,175 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Legacy/Aria/utils/makeParams.vcxproj b/Legacy/Aria/utils/makeParams.vcxproj new file mode 100644 index 0000000..8be1af4 --- /dev/null +++ b/Legacy/Aria/utils/makeParams.vcxproj @@ -0,0 +1,91 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + + + + {54F7CFCE-18A5-44C7-894D-9C4814F1209F} + Win32Proj + makeParams + + + + Application + true + Unicode + + + Application + false + true + Unicode + + + + + + + + + + + + + true + $(SolutionDir)\bin\ + obj\makeParams-$(Configuration)-VC10\ + $(ProjectName)Debug + + + false + $(SolutionDir)\bin + obj\makeParams-$(Configuration)-VC10\ + + + + NotUsing + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + ..\include;%(AdditionalIncludeDirectories) + + + Console + true + AriaDebugVC10.lib + ..\lib + + + + + Level3 + NotUsing + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + ..\include;%(AdditionalIncludeDirectories) + + + Console + true + true + true + AriaVC10.lib + ..\lib + + + + + + \ No newline at end of file diff --git a/Legacy/Aria/version.txt b/Legacy/Aria/version.txt new file mode 100644 index 0000000..4b2963e --- /dev/null +++ b/Legacy/Aria/version.txt @@ -0,0 +1,5 @@ +ARIA Version 2.8.0 +August 22, 2013 +Adept MobileRobots +Linux +gcc-4.6.3 diff --git a/Legacy/Dockerfile b/Legacy/Dockerfile new file mode 100644 index 0000000..dae1d8f --- /dev/null +++ b/Legacy/Dockerfile @@ -0,0 +1,11 @@ +FROM irth7/ros:hydro as build + +RUN apt-get update && apt-get install -y ros-hydro-tf ros-hydro-dynamic-reconfigure ros-hydro-nav-msgs ros-hydro-hokuyo-node && rm -rf /var/lib/apt/lists/* +COPY ws_linux /home/lab1_5/ws/ws_linux +ADD Aria /usr/local/Aria +COPY entrypoint.sh /entrypoint.sh + +ENV ROS_MASTER_URI=http://10.104.16.29:11311 +ENV ARIA_PORT=/dev/ttyS0 + +ENTRYPOINT ["/entrypoint.sh"] diff --git a/Legacy/entrypoint.sh b/Legacy/entrypoint.sh new file mode 100755 index 0000000..e07590b --- /dev/null +++ b/Legacy/entrypoint.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env bash +export LD_LIBRARY_PATH=/usr/local/Aria/lib:$LD_LIBRARY_PATH +source /opt/ros/hydro/setup.bash +source /home/lab1_5//ws/ws_linux/devel/setup.bash + +[[ -v PIONIER_ID ]] || { + echo + echo '!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'; + echo 'Please set the $PIONIER_ID environment variable.'; + echo '!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'; + exit -1; +} +[[ -v ROS_NAMESPACE ]] || export ROS_NAMESPACE=/PIONIER$PIONIER_ID + + +echo +echo +echo "ENVIRONMENT CONFIG" +env | grep -e ROS_MASTER_URI -e ARIA_PORT -e PIONIER_ID -e ROS_NAMESPACE | sed 's/^/ - /' +echo +echo + +set -x + +rosrun rosaria RosAria _port:=$ARIA_PORT _tf_prefix:=PIONIER${PIONIER_ID} & +rosrun hokuyo_node hokuyo_node _frame_id:="laser${PIONIER_ID}" diff --git a/Legacy/ws_linux/.catkin_workspace b/Legacy/ws_linux/.catkin_workspace new file mode 100644 index 0000000..52fd97e --- /dev/null +++ b/Legacy/ws_linux/.catkin_workspace @@ -0,0 +1 @@ +# This file currently only serves to mark the location of a catkin workspace for tool integration diff --git a/Legacy/ws_linux/build/CATKIN_IGNORE b/Legacy/ws_linux/build/CATKIN_IGNORE new file mode 100644 index 0000000..e69de29 diff --git a/Legacy/ws_linux/build/CMakeCache.txt b/Legacy/ws_linux/build/CMakeCache.txt new file mode 100644 index 0000000..b1bab60 --- /dev/null +++ b/Legacy/ws_linux/build/CMakeCache.txt @@ -0,0 +1,572 @@ +# This is the CMakeCache file. +# For build in directory: /home/lab1_5/ws/ws_linux/build +# It was generated by CMake: /usr/bin/cmake +# You can edit this file to change values found and used by cmake. +# If you do not want to change any of the values, simply exit the editor. +# If you do want to change a value, simply edit, save, and exit the editor. +# The syntax for the file is as follows: +# KEY:TYPE=VALUE +# KEY is the name of a variable in the cache. +# TYPE is a hint to GUI's for the type of VALUE, DO NOT EDIT TYPE!. +# VALUE is the current value for the KEY. + +######################## +# EXTERNAL cache entries +######################## + +//Build shared libraries (DLLs). +BUILD_SHARED_LIBS:BOOL=ON + +//The directory containing a CMake configuration file for Boost. +Boost_DIR:PATH=Boost_DIR-NOTFOUND + +//Path to a file. +Boost_INCLUDE_DIR:PATH=/usr/include + +//Boost library directory +Boost_LIBRARY_DIRS:FILEPATH=/usr/lib + +//The Boost THREAD library +Boost_THREAD_LIBRARY:FILEPATH=/usr/lib/libboost_thread-mt.so + +//Boost thread library (debug) +Boost_THREAD_LIBRARY_DEBUG:FILEPATH=/usr/lib/libboost_thread-mt.so + +//Boost thread library (release) +Boost_THREAD_LIBRARY_RELEASE:FILEPATH=/usr/lib/libboost_thread-mt.so + +//List of ';' separated packages to exclude +CATKIN_BLACKLIST_PACKAGES:STRING= + +//catkin devel space +CATKIN_DEVEL_PREFIX:PATH=/home/lab1_5/ws/ws_linux/devel + +//Catkin enable testing +CATKIN_ENABLE_TESTING:BOOL=ON + +//Catkin skip testing +CATKIN_SKIP_TESTING:BOOL=OFF + +//List of ';' separated packages to build +CATKIN_WHITELIST_PACKAGES:STRING= + +//Path to a program. +CMAKE_AR:FILEPATH=/usr/bin/ar + +//Choose the type of build, options are: None(CMAKE_CXX_FLAGS or +// CMAKE_C_FLAGS used) Debug Release RelWithDebInfo MinSizeRel. +CMAKE_BUILD_TYPE:STRING= + +//Enable/Disable color output during build. +CMAKE_COLOR_MAKEFILE:BOOL=ON + +//CXX compiler. +CMAKE_CXX_COMPILER:FILEPATH=/usr/bin/c++ + +//Flags used by the compiler during all build types. +CMAKE_CXX_FLAGS:STRING= + +//Flags used by the compiler during debug builds. +CMAKE_CXX_FLAGS_DEBUG:STRING=-g + +//Flags used by the compiler during release minsize builds. +CMAKE_CXX_FLAGS_MINSIZEREL:STRING=-Os -DNDEBUG + +//Flags used by the compiler during release builds (/MD /Ob1 /Oi +// /Ot /Oy /Gs will produce slightly less optimized but smaller +// files). +CMAKE_CXX_FLAGS_RELEASE:STRING=-O3 -DNDEBUG + +//Flags used by the compiler during Release with Debug Info builds. +CMAKE_CXX_FLAGS_RELWITHDEBINFO:STRING=-O2 -g + +//C compiler. +CMAKE_C_COMPILER:FILEPATH=/usr/bin/gcc + +//Flags used by the compiler during all build types. +CMAKE_C_FLAGS:STRING= + +//Flags used by the compiler during debug builds. +CMAKE_C_FLAGS_DEBUG:STRING=-g + +//Flags used by the compiler during release minsize builds. +CMAKE_C_FLAGS_MINSIZEREL:STRING=-Os -DNDEBUG + +//Flags used by the compiler during release builds (/MD /Ob1 /Oi +// /Ot /Oy /Gs will produce slightly less optimized but smaller +// files). +CMAKE_C_FLAGS_RELEASE:STRING=-O3 -DNDEBUG + +//Flags used by the compiler during Release with Debug Info builds. +CMAKE_C_FLAGS_RELWITHDEBINFO:STRING=-O2 -g + +//Flags used by the linker. +CMAKE_EXE_LINKER_FLAGS:STRING=' ' + +//Flags used by the linker during debug builds. +CMAKE_EXE_LINKER_FLAGS_DEBUG:STRING= + +//Flags used by the linker during release minsize builds. +CMAKE_EXE_LINKER_FLAGS_MINSIZEREL:STRING= + +//Flags used by the linker during release builds. +CMAKE_EXE_LINKER_FLAGS_RELEASE:STRING= + +//Flags used by the linker during Release with Debug Info builds. +CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO:STRING= + +//Enable/Disable output of compile commands during generation. +CMAKE_EXPORT_COMPILE_COMMANDS:BOOL=OFF + +//Install path prefix, prepended onto install directories. +CMAKE_INSTALL_PREFIX:PATH=/home/lab1_5/ws/ws_linux/install + +//Path to a program. +CMAKE_LINKER:FILEPATH=/usr/bin/ld + +//Path to a program. +CMAKE_MAKE_PROGRAM:FILEPATH=/usr/bin/make + +//Flags used by the linker during the creation of modules. +CMAKE_MODULE_LINKER_FLAGS:STRING=' ' + +//Flags used by the linker during debug builds. +CMAKE_MODULE_LINKER_FLAGS_DEBUG:STRING= + +//Flags used by the linker during release minsize builds. +CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL:STRING= + +//Flags used by the linker during release builds. +CMAKE_MODULE_LINKER_FLAGS_RELEASE:STRING= + +//Flags used by the linker during Release with Debug Info builds. +CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO:STRING= + +//Path to a program. +CMAKE_NM:FILEPATH=/usr/bin/nm + +//Path to a program. +CMAKE_OBJCOPY:FILEPATH=/usr/bin/objcopy + +//Path to a program. +CMAKE_OBJDUMP:FILEPATH=/usr/bin/objdump + +//Value Computed by CMake +CMAKE_PROJECT_NAME:STATIC=Project + +//Path to a program. +CMAKE_RANLIB:FILEPATH=/usr/bin/ranlib + +//Flags used by the linker during the creation of dll's. +CMAKE_SHARED_LINKER_FLAGS:STRING=' ' + +//Flags used by the linker during debug builds. +CMAKE_SHARED_LINKER_FLAGS_DEBUG:STRING= + +//Flags used by the linker during release minsize builds. +CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL:STRING= + +//Flags used by the linker during release builds. +CMAKE_SHARED_LINKER_FLAGS_RELEASE:STRING= + +//Flags used by the linker during Release with Debug Info builds. +CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO:STRING= + +//If set, runtime paths are not added when using shared libraries. +CMAKE_SKIP_RPATH:BOOL=NO + +//Path to a program. +CMAKE_STRIP:FILEPATH=/usr/bin/strip + +//If true, cmake will use relative paths in makefiles and projects. +CMAKE_USE_RELATIVE_PATHS:BOOL=OFF + +//If this value is on, makefiles will be generated without the +// .SILENT directive, and all commands will be echoed to the console +// during the make. This is useful for debugging only. With Visual +// Studio IDE projects all commands are done without /nologo. +CMAKE_VERBOSE_MAKEFILE:BOOL=FALSE + +//Path to a program. +DOXYGEN_EXECUTABLE:FILEPATH=/usr/bin/doxygen + +//Doxygen found +DOXYGEN_FOUND:BOOL=TRUE + +//Path to a program. +EMPY_EXECUTABLE:FILEPATH=/usr/bin/empy + +//Path to a file. +GTEST_INCLUDE_DIR:PATH=/usr/include + +//Path to a library. +GTEST_LIBRARY:FILEPATH=GTEST_LIBRARY-NOTFOUND + +//Path to a library. +GTEST_LIBRARY_DEBUG:FILEPATH=GTEST_LIBRARY_DEBUG-NOTFOUND + +//Path to a library. +GTEST_MAIN_LIBRARY:FILEPATH=GTEST_MAIN_LIBRARY-NOTFOUND + +//Path to a library. +GTEST_MAIN_LIBRARY_DEBUG:FILEPATH=GTEST_MAIN_LIBRARY_DEBUG-NOTFOUND + +//lsb_release executable was found +LSB_FOUND:BOOL=TRUE + +//Path to a program. +LSB_RELEASE_EXECUTABLE:FILEPATH=/usr/bin/lsb_release + +//Path to a program. +NOSETESTS:FILEPATH=/usr/bin/nosetests + +//Path to a program. +PYTHON_EXECUTABLE:FILEPATH=/usr/bin/python + +//Specify specific Python version to use ('major.minor' or 'major') +PYTHON_VERSION:STRING= + +//Value Computed by CMake +Project_BINARY_DIR:STATIC=/home/lab1_5/ws/ws_linux/build + +//Value Computed by CMake +Project_SOURCE_DIR:STATIC=/home/lab1_5/ws/ws_linux/src + +//Path to a library. +RT_LIBRARY:FILEPATH=/usr/lib/x86_64-linux-gnu/librt.so + +//Enable debian style python package layout +SETUPTOOLS_DEB_LAYOUT:BOOL=ON + +//LSB Distrib tag +UBUNTU:BOOL=TRUE + +//LSB Distrib - codename tag +UBUNTU_PRECISE:BOOL=TRUE + +//Path to a file. +_CATKIN_GTEST_INCLUDE:FILEPATH=/usr/include/gtest/gtest.h + +//Path to a file. +_CATKIN_GTEST_SRC:FILEPATH=/usr/src/gtest/src/gtest.cc + +//The directory containing a CMake configuration file for actionlib. +actionlib_DIR:PATH=/opt/ros/hydro/share/actionlib/cmake + +//The directory containing a CMake configuration file for actionlib_msgs. +actionlib_msgs_DIR:PATH=/opt/ros/hydro/share/actionlib_msgs/cmake + +//The directory containing a CMake configuration file for catkin. +catkin_DIR:PATH=/opt/ros/hydro/share/catkin/cmake + +//The directory containing a CMake configuration file for cpp_common. +cpp_common_DIR:PATH=/opt/ros/hydro/share/cpp_common/cmake + +//The directory containing a CMake configuration file for dynamic_reconfigure. +dynamic_reconfigure_DIR:PATH=/opt/ros/hydro/share/dynamic_reconfigure/cmake + +//The directory containing a CMake configuration file for gencpp. +gencpp_DIR:PATH=/opt/ros/hydro/share/gencpp/cmake + +//The directory containing a CMake configuration file for genlisp. +genlisp_DIR:PATH=/opt/ros/hydro/share/genlisp/cmake + +//The directory containing a CMake configuration file for genmsg. +genmsg_DIR:PATH=/opt/ros/hydro/share/genmsg/cmake + +//The directory containing a CMake configuration file for genpy. +genpy_DIR:PATH=/opt/ros/hydro/share/genpy/cmake + +//The directory containing a CMake configuration file for geometry_msgs. +geometry_msgs_DIR:PATH=/opt/ros/hydro/share/geometry_msgs/cmake + +//Value Computed by CMake +gtest_BINARY_DIR:STATIC=/home/lab1_5/ws/ws_linux/build/gtest + +//Dependencies for the target +gtest_LIB_DEPENDS:STATIC=general;-lpthread; + +//Value Computed by CMake +gtest_SOURCE_DIR:STATIC=/usr/src/gtest + +//Build gtest's sample programs. +gtest_build_samples:BOOL=OFF + +//Build all of gtest's own tests. +gtest_build_tests:BOOL=OFF + +//Disable uses of pthreads in gtest. +gtest_disable_pthreads:BOOL=OFF + +//Use shared (DLL) run-time lib even when Google Test is built +// as static lib. +gtest_force_shared_crt:BOOL=OFF + +//Dependencies for the target +gtest_main_LIB_DEPENDS:STATIC=general;-lpthread;general;gtest; + +//Path to a library. +lib:FILEPATH=/opt/ros/hydro/lib/libxmlrpcpp.so + +//The directory containing a CMake configuration file for message_filters. +message_filters_DIR:PATH=/opt/ros/hydro/share/message_filters/cmake + +//The directory containing a CMake configuration file for message_generation. +message_generation_DIR:PATH=/opt/ros/hydro/share/message_generation/cmake + +//The directory containing a CMake configuration file for message_runtime. +message_runtime_DIR:PATH=/opt/ros/hydro/share/message_runtime/cmake + +//The directory containing a CMake configuration file for nav_msgs. +nav_msgs_DIR:PATH=/opt/ros/hydro/share/nav_msgs/cmake + +//Value Computed by CMake +rosaria_BINARY_DIR:STATIC=/home/lab1_5/ws/ws_linux/build/rosaria + +//The directory containing a CMake configuration file for rosaria. +rosaria_DIR:PATH=/home/lab1_5/ws/ws_linux/devel/share/rosaria/cmake + +//Value Computed by CMake +rosaria_SOURCE_DIR:STATIC=/home/lab1_5/ws/ws_linux/src/rosaria + +//Value Computed by CMake +rosaria_msgs_BINARY_DIR:STATIC=/home/lab1_5/ws/ws_linux/build/rosaria_msgs + +//Value Computed by CMake +rosaria_msgs_SOURCE_DIR:STATIC=/home/lab1_5/ws/ws_linux/src/rosaria_msgs + +//The directory containing a CMake configuration file for rosconsole. +rosconsole_DIR:PATH=/opt/ros/hydro/share/rosconsole/cmake + +//The directory containing a CMake configuration file for roscpp. +roscpp_DIR:PATH=/opt/ros/hydro/share/roscpp/cmake + +//The directory containing a CMake configuration file for roscpp_serialization. +roscpp_serialization_DIR:PATH=/opt/ros/hydro/share/roscpp_serialization/cmake + +//The directory containing a CMake configuration file for roscpp_traits. +roscpp_traits_DIR:PATH=/opt/ros/hydro/share/roscpp_traits/cmake + +//The directory containing a CMake configuration file for rosgraph. +rosgraph_DIR:PATH=/opt/ros/hydro/share/rosgraph/cmake + +//The directory containing a CMake configuration file for rosgraph_msgs. +rosgraph_msgs_DIR:PATH=/opt/ros/hydro/share/rosgraph_msgs/cmake + +//The directory containing a CMake configuration file for rospy. +rospy_DIR:PATH=/opt/ros/hydro/share/rospy/cmake + +//The directory containing a CMake configuration file for rostime. +rostime_DIR:PATH=/opt/ros/hydro/share/rostime/cmake + +//Value Computed by CMake +safety_BINARY_DIR:STATIC=/home/lab1_5/ws/ws_linux/build/safety + +//Value Computed by CMake +safety_SOURCE_DIR:STATIC=/home/lab1_5/ws/ws_linux/src/safety + +//The directory containing a CMake configuration file for sensor_msgs. +sensor_msgs_DIR:PATH=/opt/ros/hydro/share/sensor_msgs/cmake + +//The directory containing a CMake configuration file for std_msgs. +std_msgs_DIR:PATH=/opt/ros/hydro/share/std_msgs/cmake + +//The directory containing a CMake configuration file for tf2. +tf2_DIR:PATH=/opt/ros/hydro/share/tf2/cmake + +//The directory containing a CMake configuration file for tf2_msgs. +tf2_msgs_DIR:PATH=/opt/ros/hydro/share/tf2_msgs/cmake + +//The directory containing a CMake configuration file for tf2_py. +tf2_py_DIR:PATH=/opt/ros/hydro/share/tf2_py/cmake + +//The directory containing a CMake configuration file for tf2_ros. +tf2_ros_DIR:PATH=/opt/ros/hydro/share/tf2_ros/cmake + +//The directory containing a CMake configuration file for tf. +tf_DIR:PATH=/opt/ros/hydro/share/tf/cmake + +//Value Computed by CMake +videostream_BINARY_DIR:STATIC=/home/lab1_5/ws/ws_linux/build/videostream + +//Value Computed by CMake +videostream_SOURCE_DIR:STATIC=/home/lab1_5/ws/ws_linux/src/videostream + +//The directory containing a CMake configuration file for xmlrpcpp. +xmlrpcpp_DIR:PATH=/opt/ros/hydro/share/xmlrpcpp/cmake + + +######################## +# INTERNAL cache entries +######################## + +//ADVANCED property for variable: Boost_INCLUDE_DIR +Boost_INCLUDE_DIR-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: Boost_LIBRARY_DIRS +Boost_LIBRARY_DIRS-ADVANCED:INTERNAL=1 +//The library version string for boost libraries +Boost_LIB_VERSION:INTERNAL=1_46_1 +//Whether the Boost THREAD library found +Boost_THREAD_FOUND:INTERNAL=ON +//ADVANCED property for variable: Boost_THREAD_LIBRARY +Boost_THREAD_LIBRARY-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: Boost_THREAD_LIBRARY_DEBUG +Boost_THREAD_LIBRARY_DEBUG-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: Boost_THREAD_LIBRARY_RELEASE +Boost_THREAD_LIBRARY_RELEASE-ADVANCED:INTERNAL=1 +//The version number for boost libraries +Boost_VERSION:INTERNAL=104601 +//catkin environment +CATKIN_ENV:INTERNAL=/home/lab1_5/ws/ws_linux/build/catkin_generated/env_cached.sh +CATKIN_TEST_RESULTS_DIR:INTERNAL=/home/lab1_5/ws/ws_linux/build/test_results +//ADVANCED property for variable: CMAKE_AR +CMAKE_AR-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_BUILD_TOOL +CMAKE_BUILD_TOOL-ADVANCED:INTERNAL=1 +//What is the target build tool cmake is generating for. +CMAKE_BUILD_TOOL:INTERNAL=/usr/bin/make +//This is the directory where this CMakeCache.txt was created +CMAKE_CACHEFILE_DIR:INTERNAL=/home/lab1_5/ws/ws_linux/build +//Major version of cmake used to create the current loaded cache +CMAKE_CACHE_MAJOR_VERSION:INTERNAL=2 +//Minor version of cmake used to create the current loaded cache +CMAKE_CACHE_MINOR_VERSION:INTERNAL=8 +//Patch version of cmake used to create the current loaded cache +CMAKE_CACHE_PATCH_VERSION:INTERNAL=7 +//ADVANCED property for variable: CMAKE_COLOR_MAKEFILE +CMAKE_COLOR_MAKEFILE-ADVANCED:INTERNAL=1 +//Path to CMake executable. +CMAKE_COMMAND:INTERNAL=/usr/bin/cmake +//Path to cpack program executable. +CMAKE_CPACK_COMMAND:INTERNAL=/usr/bin/cpack +//Path to ctest program executable. +CMAKE_CTEST_COMMAND:INTERNAL=/usr/bin/ctest +//ADVANCED property for variable: CMAKE_CXX_COMPILER +CMAKE_CXX_COMPILER-ADVANCED:INTERNAL=1 +CMAKE_CXX_COMPILER_WORKS:INTERNAL=1 +//ADVANCED property for variable: CMAKE_CXX_FLAGS +CMAKE_CXX_FLAGS-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_CXX_FLAGS_DEBUG +CMAKE_CXX_FLAGS_DEBUG-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_CXX_FLAGS_MINSIZEREL +CMAKE_CXX_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_CXX_FLAGS_RELEASE +CMAKE_CXX_FLAGS_RELEASE-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_CXX_FLAGS_RELWITHDEBINFO +CMAKE_CXX_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_C_COMPILER +CMAKE_C_COMPILER-ADVANCED:INTERNAL=1 +CMAKE_C_COMPILER_WORKS:INTERNAL=1 +//ADVANCED property for variable: CMAKE_C_FLAGS +CMAKE_C_FLAGS-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_C_FLAGS_DEBUG +CMAKE_C_FLAGS_DEBUG-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_C_FLAGS_MINSIZEREL +CMAKE_C_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_C_FLAGS_RELEASE +CMAKE_C_FLAGS_RELEASE-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_C_FLAGS_RELWITHDEBINFO +CMAKE_C_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1 +//Result of TRY_COMPILE +CMAKE_DETERMINE_CXX_ABI_COMPILED:INTERNAL=TRUE +//Result of TRY_COMPILE +CMAKE_DETERMINE_C_ABI_COMPILED:INTERNAL=TRUE +//Executable file format +CMAKE_EXECUTABLE_FORMAT:INTERNAL=ELF +//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS +CMAKE_EXE_LINKER_FLAGS-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_DEBUG +CMAKE_EXE_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_MINSIZEREL +CMAKE_EXE_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_RELEASE +CMAKE_EXE_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO +CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_EXPORT_COMPILE_COMMANDS +CMAKE_EXPORT_COMPILE_COMMANDS-ADVANCED:INTERNAL=1 +//Name of generator. +CMAKE_GENERATOR:INTERNAL=Unix Makefiles +//Have library pthreads +CMAKE_HAVE_PTHREADS_CREATE:INTERNAL= +//Have library pthread +CMAKE_HAVE_PTHREAD_CREATE:INTERNAL=1 +//Have include CMAKE_HAVE_PTHREAD_H +CMAKE_HAVE_PTHREAD_H:INTERNAL=1 +//Start directory with the top level CMakeLists.txt file for this +// project +CMAKE_HOME_DIRECTORY:INTERNAL=/home/lab1_5/ws/ws_linux/src +//Install .so files without execute permission. +CMAKE_INSTALL_SO_NO_EXE:INTERNAL=1 +//ADVANCED property for variable: CMAKE_LINKER +CMAKE_LINKER-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_MAKE_PROGRAM +CMAKE_MAKE_PROGRAM-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS +CMAKE_MODULE_LINKER_FLAGS-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_DEBUG +CMAKE_MODULE_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL +CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_RELEASE +CMAKE_MODULE_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO +CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_NM +CMAKE_NM-ADVANCED:INTERNAL=1 +//number of local generators +CMAKE_NUMBER_OF_LOCAL_GENERATORS:INTERNAL=6 +//ADVANCED property for variable: CMAKE_OBJCOPY +CMAKE_OBJCOPY-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_OBJDUMP +CMAKE_OBJDUMP-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_RANLIB +CMAKE_RANLIB-ADVANCED:INTERNAL=1 +//Path to CMake installation. +CMAKE_ROOT:INTERNAL=/usr/share/cmake-2.8 +//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS +CMAKE_SHARED_LINKER_FLAGS-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_DEBUG +CMAKE_SHARED_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL +CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_RELEASE +CMAKE_SHARED_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO +CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_SKIP_RPATH +CMAKE_SKIP_RPATH-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_STRIP +CMAKE_STRIP-ADVANCED:INTERNAL=1 +//uname command +CMAKE_UNAME:INTERNAL=/bin/uname +//ADVANCED property for variable: CMAKE_USE_RELATIVE_PATHS +CMAKE_USE_RELATIVE_PATHS-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_VERBOSE_MAKEFILE +CMAKE_VERBOSE_MAKEFILE-ADVANCED:INTERNAL=1 +//Details about finding PythonInterp +FIND_PACKAGE_MESSAGE_DETAILS_PythonInterp:INTERNAL=[/usr/bin/python][v2.7.3()] +//Details about finding Threads +FIND_PACKAGE_MESSAGE_DETAILS_Threads:INTERNAL=[TRUE][v()] +GTEST_FROM_SOURCE_FOUND:INTERNAL=TRUE +GTEST_FROM_SOURCE_INCLUDE_DIRS:INTERNAL=/usr/include +GTEST_FROM_SOURCE_LIBRARIES:INTERNAL=gtest +GTEST_FROM_SOURCE_LIBRARY_DIRS:INTERNAL=/home/lab1_5/ws/ws_linux/build/gtest +GTEST_FROM_SOURCE_MAIN_LIBRARIES:INTERNAL=gtest_main +//ADVANCED property for variable: GTEST_INCLUDE_DIR +GTEST_INCLUDE_DIR-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: GTEST_LIBRARY +GTEST_LIBRARY-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: GTEST_LIBRARY_DEBUG +GTEST_LIBRARY_DEBUG-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: GTEST_MAIN_LIBRARY +GTEST_MAIN_LIBRARY-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: GTEST_MAIN_LIBRARY_DEBUG +GTEST_MAIN_LIBRARY_DEBUG-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: PYTHON_EXECUTABLE +PYTHON_EXECUTABLE-ADVANCED:INTERNAL=1 +//This needs to be in PYTHONPATH when 'setup.py install' is called. +// And it needs to match. But setuptools won't tell us where +// it will install things. +PYTHON_INSTALL_DIR:INTERNAL=lib/python2.7/dist-packages + diff --git a/Legacy/ws_linux/build/CMakeFiles/CMakeCCompiler.cmake b/Legacy/ws_linux/build/CMakeFiles/CMakeCCompiler.cmake new file mode 100644 index 0000000..657f5b0 --- /dev/null +++ b/Legacy/ws_linux/build/CMakeFiles/CMakeCCompiler.cmake @@ -0,0 +1,49 @@ +SET(CMAKE_C_COMPILER "/usr/bin/gcc") +SET(CMAKE_C_COMPILER_ARG1 "") +SET(CMAKE_C_COMPILER_ID "GNU") +SET(CMAKE_C_PLATFORM_ID "Linux") + +SET(CMAKE_AR "/usr/bin/ar") +SET(CMAKE_RANLIB "/usr/bin/ranlib") +SET(CMAKE_LINKER "/usr/bin/ld") +SET(CMAKE_COMPILER_IS_GNUCC 1) +SET(CMAKE_C_COMPILER_LOADED 1) +SET(CMAKE_COMPILER_IS_MINGW ) +SET(CMAKE_COMPILER_IS_CYGWIN ) +IF(CMAKE_COMPILER_IS_CYGWIN) + SET(CYGWIN 1) + SET(UNIX 1) +ENDIF(CMAKE_COMPILER_IS_CYGWIN) + +SET(CMAKE_C_COMPILER_ENV_VAR "CC") + +IF(CMAKE_COMPILER_IS_MINGW) + SET(MINGW 1) +ENDIF(CMAKE_COMPILER_IS_MINGW) +SET(CMAKE_C_COMPILER_ID_RUN 1) +SET(CMAKE_C_SOURCE_FILE_EXTENSIONS c) +SET(CMAKE_C_IGNORE_EXTENSIONS h;H;o;O;obj;OBJ;def;DEF;rc;RC) +SET(CMAKE_C_LINKER_PREFERENCE 10) + +# Save compiler ABI information. +SET(CMAKE_C_SIZEOF_DATA_PTR "8") +SET(CMAKE_C_COMPILER_ABI "ELF") +SET(CMAKE_C_LIBRARY_ARCHITECTURE "x86_64-linux-gnu") + +IF(CMAKE_C_SIZEOF_DATA_PTR) + SET(CMAKE_SIZEOF_VOID_P "${CMAKE_C_SIZEOF_DATA_PTR}") +ENDIF(CMAKE_C_SIZEOF_DATA_PTR) + +IF(CMAKE_C_COMPILER_ABI) + SET(CMAKE_INTERNAL_PLATFORM_ABI "${CMAKE_C_COMPILER_ABI}") +ENDIF(CMAKE_C_COMPILER_ABI) + +IF(CMAKE_C_LIBRARY_ARCHITECTURE) + SET(CMAKE_LIBRARY_ARCHITECTURE "x86_64-linux-gnu") +ENDIF() + +SET(CMAKE_C_HAS_ISYSROOT "") + + +SET(CMAKE_C_IMPLICIT_LINK_LIBRARIES "c") +SET(CMAKE_C_IMPLICIT_LINK_DIRECTORIES "/usr/lib/gcc/x86_64-linux-gnu/4.6;/usr/lib/x86_64-linux-gnu;/usr/lib;/lib/x86_64-linux-gnu;/lib") diff --git a/Legacy/ws_linux/build/CMakeFiles/CMakeCXXCompiler.cmake b/Legacy/ws_linux/build/CMakeFiles/CMakeCXXCompiler.cmake new file mode 100644 index 0000000..f62d04d --- /dev/null +++ b/Legacy/ws_linux/build/CMakeFiles/CMakeCXXCompiler.cmake @@ -0,0 +1,50 @@ +SET(CMAKE_CXX_COMPILER "/usr/bin/c++") +SET(CMAKE_CXX_COMPILER_ARG1 "") +SET(CMAKE_CXX_COMPILER_ID "GNU") +SET(CMAKE_CXX_PLATFORM_ID "Linux") + +SET(CMAKE_AR "/usr/bin/ar") +SET(CMAKE_RANLIB "/usr/bin/ranlib") +SET(CMAKE_LINKER "/usr/bin/ld") +SET(CMAKE_COMPILER_IS_GNUCXX 1) +SET(CMAKE_CXX_COMPILER_LOADED 1) +SET(CMAKE_COMPILER_IS_MINGW ) +SET(CMAKE_COMPILER_IS_CYGWIN ) +IF(CMAKE_COMPILER_IS_CYGWIN) + SET(CYGWIN 1) + SET(UNIX 1) +ENDIF(CMAKE_COMPILER_IS_CYGWIN) + +SET(CMAKE_CXX_COMPILER_ENV_VAR "CXX") + +IF(CMAKE_COMPILER_IS_MINGW) + SET(MINGW 1) +ENDIF(CMAKE_COMPILER_IS_MINGW) +SET(CMAKE_CXX_COMPILER_ID_RUN 1) +SET(CMAKE_CXX_IGNORE_EXTENSIONS inl;h;hpp;HPP;H;o;O;obj;OBJ;def;DEF;rc;RC) +SET(CMAKE_CXX_SOURCE_FILE_EXTENSIONS C;M;c++;cc;cpp;cxx;m;mm;CPP) +SET(CMAKE_CXX_LINKER_PREFERENCE 30) +SET(CMAKE_CXX_LINKER_PREFERENCE_PROPAGATES 1) + +# Save compiler ABI information. +SET(CMAKE_CXX_SIZEOF_DATA_PTR "8") +SET(CMAKE_CXX_COMPILER_ABI "ELF") +SET(CMAKE_CXX_LIBRARY_ARCHITECTURE "x86_64-linux-gnu") + +IF(CMAKE_CXX_SIZEOF_DATA_PTR) + SET(CMAKE_SIZEOF_VOID_P "${CMAKE_CXX_SIZEOF_DATA_PTR}") +ENDIF(CMAKE_CXX_SIZEOF_DATA_PTR) + +IF(CMAKE_CXX_COMPILER_ABI) + SET(CMAKE_INTERNAL_PLATFORM_ABI "${CMAKE_CXX_COMPILER_ABI}") +ENDIF(CMAKE_CXX_COMPILER_ABI) + +IF(CMAKE_CXX_LIBRARY_ARCHITECTURE) + SET(CMAKE_LIBRARY_ARCHITECTURE "x86_64-linux-gnu") +ENDIF() + +SET(CMAKE_CXX_HAS_ISYSROOT "") + + +SET(CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "stdc++;m;c") +SET(CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES "/usr/lib/gcc/x86_64-linux-gnu/4.6;/usr/lib/x86_64-linux-gnu;/usr/lib;/lib/x86_64-linux-gnu;/lib") diff --git a/Legacy/ws_linux/build/CMakeFiles/CMakeDetermineCompilerABI_C.bin b/Legacy/ws_linux/build/CMakeFiles/CMakeDetermineCompilerABI_C.bin new file mode 100755 index 0000000000000000000000000000000000000000..dc21ec4e8374e81c953da6449000e248b553d721 GIT binary patch literal 8413 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 ignore + arg [--sysroot=/] ==> ignore + arg [--build-id] ==> ignore + arg [--no-add-needed] ==> ignore + arg [--as-needed] ==> ignore + arg [--eh-frame-hdr] ==> ignore + arg [-m] ==> ignore + arg [elf_x86_64] ==> ignore + arg [--hash-style=gnu] ==> ignore + arg [-export-dynamic] ==> ignore + arg [-dynamic-linker] ==> ignore + arg [/lib64/ld-linux-x86-64.so.2] ==> ignore + arg [-zrelro] ==> ignore + arg [-o] ==> ignore + arg [cmTryCompileExec] ==> ignore + arg [/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crt1.o] ==> ignore + arg [/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crti.o] ==> ignore + arg [/usr/lib/gcc/x86_64-linux-gnu/4.6/crtbegin.o] ==> ignore + arg [-L/usr/lib/gcc/x86_64-linux-gnu/4.6] ==> dir [/usr/lib/gcc/x86_64-linux-gnu/4.6] + arg [-L/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu] ==> dir [/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu] + arg [-L/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../../lib] ==> dir [/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../../lib] + arg [-L/lib/x86_64-linux-gnu] ==> dir [/lib/x86_64-linux-gnu] + arg [-L/lib/../lib] ==> dir [/lib/../lib] + arg [-L/usr/lib/x86_64-linux-gnu] ==> dir [/usr/lib/x86_64-linux-gnu] + arg [-L/usr/lib/../lib] ==> dir [/usr/lib/../lib] + arg [-L/usr/lib/gcc/x86_64-linux-gnu/4.6/../../..] ==> dir [/usr/lib/gcc/x86_64-linux-gnu/4.6/../../..] + arg [CMakeFiles/cmTryCompileExec.dir/CMakeCCompilerABI.c.o] ==> ignore + arg [-lgcc] ==> lib [gcc] + arg [--as-needed] ==> ignore + arg [-lgcc_s] ==> lib [gcc_s] + arg [--no-as-needed] ==> ignore + arg [-lc] ==> lib [c] + arg [-lgcc] ==> lib [gcc] + arg [--as-needed] ==> ignore + arg [-lgcc_s] ==> lib [gcc_s] + arg [--no-as-needed] ==> ignore + arg [/usr/lib/gcc/x86_64-linux-gnu/4.6/crtend.o] ==> ignore + arg [/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crtn.o] ==> ignore + remove lib [gcc] + remove lib [gcc_s] + remove lib [gcc] + remove lib [gcc_s] + collapse dir [/usr/lib/gcc/x86_64-linux-gnu/4.6] ==> [/usr/lib/gcc/x86_64-linux-gnu/4.6] + collapse dir [/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu] ==> [/usr/lib/x86_64-linux-gnu] + collapse dir [/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../../lib] ==> [/usr/lib] + collapse dir [/lib/x86_64-linux-gnu] ==> [/lib/x86_64-linux-gnu] + collapse dir [/lib/../lib] ==> [/lib] + collapse dir [/usr/lib/x86_64-linux-gnu] ==> [/usr/lib/x86_64-linux-gnu] + collapse dir [/usr/lib/../lib] ==> [/usr/lib] + collapse dir [/usr/lib/gcc/x86_64-linux-gnu/4.6/../../..] ==> [/usr/lib] + implicit libs: [c] + implicit dirs: [/usr/lib/gcc/x86_64-linux-gnu/4.6;/usr/lib/x86_64-linux-gnu;/usr/lib;/lib/x86_64-linux-gnu;/lib] + + +Determining if the CXX compiler works passed with the following output: +Change Dir: /home/lab1_5/ws/ws_linux/build/CMakeFiles/CMakeTmp + +Run Build Command:/usr/bin/make "cmTryCompileExec/fast" +/usr/bin/make -f CMakeFiles/cmTryCompileExec.dir/build.make CMakeFiles/cmTryCompileExec.dir/build +make[1]: Wejście do katalogu `/home/lab1_5/ws/ws_linux/build/CMakeFiles/CMakeTmp' +/usr/bin/cmake -E cmake_progress_report /home/lab1_5/ws/ws_linux/build/CMakeFiles/CMakeTmp/CMakeFiles 1 +Building CXX object CMakeFiles/cmTryCompileExec.dir/testCXXCompiler.cxx.o +/usr/bin/c++ -o CMakeFiles/cmTryCompileExec.dir/testCXXCompiler.cxx.o -c /home/lab1_5/ws/ws_linux/build/CMakeFiles/CMakeTmp/testCXXCompiler.cxx +Linking CXX executable cmTryCompileExec +/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTryCompileExec.dir/link.txt --verbose=1 +/usr/bin/c++ CMakeFiles/cmTryCompileExec.dir/testCXXCompiler.cxx.o -o cmTryCompileExec -rdynamic +make[1]: Opuszczenie katalogu `/home/lab1_5/ws/ws_linux/build/CMakeFiles/CMakeTmp' + + +Detecting CXX compiler ABI info compiled with the following output: +Change Dir: /home/lab1_5/ws/ws_linux/build/CMakeFiles/CMakeTmp + +Run Build Command:/usr/bin/make "cmTryCompileExec/fast" +/usr/bin/make -f CMakeFiles/cmTryCompileExec.dir/build.make CMakeFiles/cmTryCompileExec.dir/build +make[1]: Wejście do katalogu `/home/lab1_5/ws/ws_linux/build/CMakeFiles/CMakeTmp' +/usr/bin/cmake -E cmake_progress_report /home/lab1_5/ws/ws_linux/build/CMakeFiles/CMakeTmp/CMakeFiles 1 +Building CXX object CMakeFiles/cmTryCompileExec.dir/CMakeCXXCompilerABI.cpp.o +/usr/bin/c++ -o CMakeFiles/cmTryCompileExec.dir/CMakeCXXCompilerABI.cpp.o -c /usr/share/cmake-2.8/Modules/CMakeCXXCompilerABI.cpp +Linking CXX executable cmTryCompileExec +/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTryCompileExec.dir/link.txt --verbose=1 +/usr/bin/c++ -v CMakeFiles/cmTryCompileExec.dir/CMakeCXXCompilerABI.cpp.o -o cmTryCompileExec -rdynamic +Using built-in specs. +COLLECT_GCC=/usr/bin/c++ +COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.6/lto-wrapper +Target: x86_64-linux-gnu +Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 4.6.3-1ubuntu5' --with-bugurl=file:///usr/share/doc/gcc-4.6/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.6 --enable-shared --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.6 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --enable-plugin --enable-objc-gc --disable-werror --with-arch-32=i686 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu +Thread model: posix +gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5) +COMPILER_PATH=/usr/lib/gcc/x86_64-linux-gnu/4.6/:/usr/lib/gcc/x86_64-linux-gnu/4.6/:/usr/lib/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/4.6/:/usr/lib/gcc/x86_64-linux-gnu/ +LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/4.6/:/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../:/lib/:/usr/lib/ +COLLECT_GCC_OPTIONS='-v' '-o' 'cmTryCompileExec' '-rdynamic' '-shared-libgcc' '-mtune=generic' '-march=x86-64' + /usr/lib/gcc/x86_64-linux-gnu/4.6/collect2 --sysroot=/ --build-id --no-add-needed --as-needed --eh-frame-hdr -m elf_x86_64 --hash-style=gnu -export-dynamic -dynamic-linker /lib64/ld-linux-x86-64.so.2 -z relro -o cmTryCompileExec /usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crt1.o /usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/4.6/crtbegin.o -L/usr/lib/gcc/x86_64-linux-gnu/4.6 -L/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/4.6/../../.. CMakeFiles/cmTryCompileExec.dir/CMakeCXXCompilerABI.cpp.o -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/lib/gcc/x86_64-linux-gnu/4.6/crtend.o /usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crtn.o +make[1]: Opuszczenie katalogu `/home/lab1_5/ws/ws_linux/build/CMakeFiles/CMakeTmp' + + +Parsed CXX implicit link information from above output: + link line regex: [^( *|.*[/\])(ld|ld|collect2)[^/\]*( |$)] + ignore line: [Change Dir: /home/lab1_5/ws/ws_linux/build/CMakeFiles/CMakeTmp] + ignore line: [] + ignore line: [Run Build Command:/usr/bin/make "cmTryCompileExec/fast"] + ignore line: [/usr/bin/make -f CMakeFiles/cmTryCompileExec.dir/build.make CMakeFiles/cmTryCompileExec.dir/build] + ignore line: [make[1]: Wejście do katalogu `/home/lab1_5/ws/ws_linux/build/CMakeFiles/CMakeTmp'] + ignore line: [/usr/bin/cmake -E cmake_progress_report /home/lab1_5/ws/ws_linux/build/CMakeFiles/CMakeTmp/CMakeFiles 1] + ignore line: [Building CXX object CMakeFiles/cmTryCompileExec.dir/CMakeCXXCompilerABI.cpp.o] + ignore line: [/usr/bin/c++ -o CMakeFiles/cmTryCompileExec.dir/CMakeCXXCompilerABI.cpp.o -c /usr/share/cmake-2.8/Modules/CMakeCXXCompilerABI.cpp] + ignore line: [Linking CXX executable cmTryCompileExec] + ignore line: [/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTryCompileExec.dir/link.txt --verbose=1] + ignore line: [/usr/bin/c++ -v CMakeFiles/cmTryCompileExec.dir/CMakeCXXCompilerABI.cpp.o -o cmTryCompileExec -rdynamic ] + ignore line: [Using built-in specs.] + ignore line: [COLLECT_GCC=/usr/bin/c++] + ignore line: [COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.6/lto-wrapper] + ignore line: [Target: x86_64-linux-gnu] + ignore line: [Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 4.6.3-1ubuntu5' --with-bugurl=file:///usr/share/doc/gcc-4.6/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.6 --enable-shared --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.6 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --enable-plugin --enable-objc-gc --disable-werror --with-arch-32=i686 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu] + ignore line: [Thread model: posix] + ignore line: [gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5) ] + ignore line: [COMPILER_PATH=/usr/lib/gcc/x86_64-linux-gnu/4.6/:/usr/lib/gcc/x86_64-linux-gnu/4.6/:/usr/lib/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/4.6/:/usr/lib/gcc/x86_64-linux-gnu/] + ignore line: [LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/4.6/:/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../:/lib/:/usr/lib/] + ignore line: [COLLECT_GCC_OPTIONS='-v' '-o' 'cmTryCompileExec' '-rdynamic' '-shared-libgcc' '-mtune=generic' '-march=x86-64'] + link line: [ /usr/lib/gcc/x86_64-linux-gnu/4.6/collect2 --sysroot=/ --build-id --no-add-needed --as-needed --eh-frame-hdr -m elf_x86_64 --hash-style=gnu -export-dynamic -dynamic-linker /lib64/ld-linux-x86-64.so.2 -z relro -o cmTryCompileExec /usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crt1.o /usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/4.6/crtbegin.o -L/usr/lib/gcc/x86_64-linux-gnu/4.6 -L/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/4.6/../../.. CMakeFiles/cmTryCompileExec.dir/CMakeCXXCompilerABI.cpp.o -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/lib/gcc/x86_64-linux-gnu/4.6/crtend.o /usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crtn.o] + arg [/usr/lib/gcc/x86_64-linux-gnu/4.6/collect2] ==> ignore + arg [--sysroot=/] ==> ignore + arg [--build-id] ==> ignore + arg [--no-add-needed] ==> ignore + arg [--as-needed] ==> ignore + arg [--eh-frame-hdr] ==> ignore + arg [-m] ==> ignore + arg [elf_x86_64] ==> ignore + arg [--hash-style=gnu] ==> ignore + arg [-export-dynamic] ==> ignore + arg [-dynamic-linker] ==> ignore + arg [/lib64/ld-linux-x86-64.so.2] ==> ignore + arg [-zrelro] ==> ignore + arg [-o] ==> ignore + arg [cmTryCompileExec] ==> ignore + arg [/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crt1.o] ==> ignore + arg [/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crti.o] ==> ignore + arg [/usr/lib/gcc/x86_64-linux-gnu/4.6/crtbegin.o] ==> ignore + arg [-L/usr/lib/gcc/x86_64-linux-gnu/4.6] ==> dir [/usr/lib/gcc/x86_64-linux-gnu/4.6] + arg [-L/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu] ==> dir [/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu] + arg [-L/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../../lib] ==> dir [/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../../lib] + arg [-L/lib/x86_64-linux-gnu] ==> dir [/lib/x86_64-linux-gnu] + arg [-L/lib/../lib] ==> dir [/lib/../lib] + arg [-L/usr/lib/x86_64-linux-gnu] ==> dir [/usr/lib/x86_64-linux-gnu] + arg [-L/usr/lib/../lib] ==> dir [/usr/lib/../lib] + arg [-L/usr/lib/gcc/x86_64-linux-gnu/4.6/../../..] ==> dir [/usr/lib/gcc/x86_64-linux-gnu/4.6/../../..] + arg [CMakeFiles/cmTryCompileExec.dir/CMakeCXXCompilerABI.cpp.o] ==> ignore + arg [-lstdc++] ==> lib [stdc++] + arg [-lm] ==> lib [m] + arg [-lgcc_s] ==> lib [gcc_s] + arg [-lgcc] ==> lib [gcc] + arg [-lc] ==> lib [c] + arg [-lgcc_s] ==> lib [gcc_s] + arg [-lgcc] ==> lib [gcc] + arg [/usr/lib/gcc/x86_64-linux-gnu/4.6/crtend.o] ==> ignore + arg [/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crtn.o] ==> ignore + remove lib [gcc_s] + remove lib [gcc] + remove lib [gcc_s] + remove lib [gcc] + collapse dir [/usr/lib/gcc/x86_64-linux-gnu/4.6] ==> [/usr/lib/gcc/x86_64-linux-gnu/4.6] + collapse dir [/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu] ==> [/usr/lib/x86_64-linux-gnu] + collapse dir [/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../../lib] ==> [/usr/lib] + collapse dir [/lib/x86_64-linux-gnu] ==> [/lib/x86_64-linux-gnu] + collapse dir [/lib/../lib] ==> [/lib] + collapse dir [/usr/lib/x86_64-linux-gnu] ==> [/usr/lib/x86_64-linux-gnu] + collapse dir [/usr/lib/../lib] ==> [/usr/lib] + collapse dir [/usr/lib/gcc/x86_64-linux-gnu/4.6/../../..] ==> [/usr/lib] + implicit libs: [stdc++;m;c] + implicit dirs: [/usr/lib/gcc/x86_64-linux-gnu/4.6;/usr/lib/x86_64-linux-gnu;/usr/lib;/lib/x86_64-linux-gnu;/lib] + + +Determining if files pthread.h exist passed with the following output: +Change Dir: /home/lab1_5/ws/ws_linux/build/CMakeFiles/CMakeTmp + +Run Build Command:/usr/bin/make "cmTryCompileExec/fast" +/usr/bin/make -f CMakeFiles/cmTryCompileExec.dir/build.make CMakeFiles/cmTryCompileExec.dir/build +make[1]: Wejście do katalogu `/home/lab1_5/ws/ws_linux/build/CMakeFiles/CMakeTmp' +/usr/bin/cmake -E cmake_progress_report /home/lab1_5/ws/ws_linux/build/CMakeFiles/CMakeTmp/CMakeFiles 1 +Building C object CMakeFiles/cmTryCompileExec.dir/CheckIncludeFiles.c.o +/usr/bin/gcc -o CMakeFiles/cmTryCompileExec.dir/CheckIncludeFiles.c.o -c /home/lab1_5/ws/ws_linux/build/CMakeFiles/CMakeTmp/CheckIncludeFiles.c +Linking C executable cmTryCompileExec +/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTryCompileExec.dir/link.txt --verbose=1 +/usr/bin/gcc CMakeFiles/cmTryCompileExec.dir/CheckIncludeFiles.c.o -o cmTryCompileExec -rdynamic +make[1]: Opuszczenie katalogu `/home/lab1_5/ws/ws_linux/build/CMakeFiles/CMakeTmp' + + +Determining if the function pthread_create exists in the pthread passed with the following output: +Change Dir: /home/lab1_5/ws/ws_linux/build/CMakeFiles/CMakeTmp + +Run Build Command:/usr/bin/make "cmTryCompileExec/fast" +/usr/bin/make -f CMakeFiles/cmTryCompileExec.dir/build.make CMakeFiles/cmTryCompileExec.dir/build +make[1]: Wejście do katalogu `/home/lab1_5/ws/ws_linux/build/CMakeFiles/CMakeTmp' +/usr/bin/cmake -E cmake_progress_report /home/lab1_5/ws/ws_linux/build/CMakeFiles/CMakeTmp/CMakeFiles 1 +Building C object CMakeFiles/cmTryCompileExec.dir/CheckFunctionExists.c.o +/usr/bin/gcc -DCHECK_FUNCTION_EXISTS=pthread_create -o CMakeFiles/cmTryCompileExec.dir/CheckFunctionExists.c.o -c /usr/share/cmake-2.8/Modules/CheckFunctionExists.c +Linking C executable cmTryCompileExec +/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTryCompileExec.dir/link.txt --verbose=1 +/usr/bin/gcc -DCHECK_FUNCTION_EXISTS=pthread_create CMakeFiles/cmTryCompileExec.dir/CheckFunctionExists.c.o -o cmTryCompileExec -rdynamic -lpthread +make[1]: Opuszczenie katalogu `/home/lab1_5/ws/ws_linux/build/CMakeFiles/CMakeTmp' + + diff --git a/Legacy/ws_linux/build/CMakeFiles/CMakeRuleHashes.txt b/Legacy/ws_linux/build/CMakeFiles/CMakeRuleHashes.txt new file mode 100644 index 0000000..3ee6f83 --- /dev/null +++ b/Legacy/ws_linux/build/CMakeFiles/CMakeRuleHashes.txt @@ -0,0 +1,84 @@ +# Hashes of file build rules. +e080c3e5e73febe4e2068a93a5b2cb0a /home/lab1_5/ws/ws_linux/devel/include/rosaria/BumperState.h +7dc242583ade1b73ff19968b1227c636 /home/lab1_5/ws/ws_linux/devel/include/rosaria/RosAriaConfig.h +fe6d554df5d5446de5d0e8aa70c9ebac /home/lab1_5/ws/ws_linux/devel/include/rosaria_msgs/RestrictionsMsg.h +dc0ca9717dbbdf4c0bc913c3a482eb29 /home/lab1_5/ws/ws_linux/devel/include/rosaria_msgs/RobotInfoMsg.h +be683fc2dc7472661d81a9ac81d360e4 /home/lab1_5/ws/ws_linux/devel/include/videostream/ip_get.h +41fd248b70dbf81470620287c5bb47ab /home/lab1_5/ws/ws_linux/devel/lib/python2.7/dist-packages/rosaria/msg/_BumperState.py +7234d80da6a4bd403e7b61286e186130 /home/lab1_5/ws/ws_linux/devel/lib/python2.7/dist-packages/rosaria/msg/__init__.py +a0478ebd217c1233c0bf3a6624904d03 /home/lab1_5/ws/ws_linux/devel/lib/python2.7/dist-packages/rosaria_msgs/msg/_RestrictionsMsg.py +7b9a6628a49150579963f568dd643d9f /home/lab1_5/ws/ws_linux/devel/lib/python2.7/dist-packages/rosaria_msgs/msg/_RobotInfoMsg.py +58ca1c3cb3cca0f0415e1e1e523d7061 /home/lab1_5/ws/ws_linux/devel/lib/python2.7/dist-packages/rosaria_msgs/msg/__init__.py +9caf6c700275b8d0568355f454924a17 /home/lab1_5/ws/ws_linux/devel/lib/python2.7/dist-packages/videostream/srv/__init__.py +698e659c14887bb043b91ded9cab18d5 /home/lab1_5/ws/ws_linux/devel/lib/python2.7/dist-packages/videostream/srv/_ip_get.py +e18ad45c8276c68e05c1b1ed420e4561 /home/lab1_5/ws/ws_linux/devel/share/common-lisp/ros/rosaria/msg/BumperState.lisp +a9f69f91ee132907f33873cb052cf015 /home/lab1_5/ws/ws_linux/devel/share/common-lisp/ros/rosaria_msgs/msg/RestrictionsMsg.lisp +6ba5ea70e359ebd796f7543566ae3db2 /home/lab1_5/ws/ws_linux/devel/share/common-lisp/ros/rosaria_msgs/msg/RobotInfoMsg.lisp +77b69422e50c2944789978515dce4c72 /home/lab1_5/ws/ws_linux/devel/share/common-lisp/ros/videostream/srv/ip_get.lisp +8099a92a7968e95953b230635467d9bf CMakeFiles/clean_test_results +548b6dc829b8c3b7b051e5fc0b33c85f CMakeFiles/doxygen +548b6dc829b8c3b7b051e5fc0b33c85f CMakeFiles/run_tests +548b6dc829b8c3b7b051e5fc0b33c85f CMakeFiles/tests +ecb60bf5b43b0dc8aa686e69b54fe939 rosaria/CMakeFiles/actionlib_generate_messages_cpp +ecb60bf5b43b0dc8aa686e69b54fe939 rosaria/CMakeFiles/actionlib_generate_messages_lisp +ecb60bf5b43b0dc8aa686e69b54fe939 rosaria/CMakeFiles/actionlib_generate_messages_py +ecb60bf5b43b0dc8aa686e69b54fe939 rosaria/CMakeFiles/actionlib_msgs_generate_messages_cpp +ecb60bf5b43b0dc8aa686e69b54fe939 rosaria/CMakeFiles/actionlib_msgs_generate_messages_lisp +ecb60bf5b43b0dc8aa686e69b54fe939 rosaria/CMakeFiles/actionlib_msgs_generate_messages_py +ecb60bf5b43b0dc8aa686e69b54fe939 rosaria/CMakeFiles/dynamic_reconfigure_gencfg +ecb60bf5b43b0dc8aa686e69b54fe939 rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_cpp +ecb60bf5b43b0dc8aa686e69b54fe939 rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_lisp +ecb60bf5b43b0dc8aa686e69b54fe939 rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_py +ecb60bf5b43b0dc8aa686e69b54fe939 rosaria/CMakeFiles/nav_msgs_generate_messages_cpp +ecb60bf5b43b0dc8aa686e69b54fe939 rosaria/CMakeFiles/nav_msgs_generate_messages_lisp +ecb60bf5b43b0dc8aa686e69b54fe939 rosaria/CMakeFiles/nav_msgs_generate_messages_py +ecb60bf5b43b0dc8aa686e69b54fe939 rosaria/CMakeFiles/rosaria_gencfg +ecb60bf5b43b0dc8aa686e69b54fe939 rosaria/CMakeFiles/rosaria_gencpp +ecb60bf5b43b0dc8aa686e69b54fe939 rosaria/CMakeFiles/rosaria_generate_messages +ecb60bf5b43b0dc8aa686e69b54fe939 rosaria/CMakeFiles/rosaria_generate_messages_cpp +ecb60bf5b43b0dc8aa686e69b54fe939 rosaria/CMakeFiles/rosaria_generate_messages_lisp +ecb60bf5b43b0dc8aa686e69b54fe939 rosaria/CMakeFiles/rosaria_generate_messages_py +ecb60bf5b43b0dc8aa686e69b54fe939 rosaria/CMakeFiles/rosaria_genlisp +ecb60bf5b43b0dc8aa686e69b54fe939 rosaria/CMakeFiles/rosaria_genpy +ecb60bf5b43b0dc8aa686e69b54fe939 rosaria/CMakeFiles/roscpp_generate_messages_cpp +ecb60bf5b43b0dc8aa686e69b54fe939 rosaria/CMakeFiles/roscpp_generate_messages_lisp +ecb60bf5b43b0dc8aa686e69b54fe939 rosaria/CMakeFiles/roscpp_generate_messages_py +ecb60bf5b43b0dc8aa686e69b54fe939 rosaria/CMakeFiles/rosgraph_msgs_generate_messages_cpp +ecb60bf5b43b0dc8aa686e69b54fe939 rosaria/CMakeFiles/rosgraph_msgs_generate_messages_lisp +ecb60bf5b43b0dc8aa686e69b54fe939 rosaria/CMakeFiles/rosgraph_msgs_generate_messages_py +ecb60bf5b43b0dc8aa686e69b54fe939 rosaria/CMakeFiles/sensor_msgs_generate_messages_cpp +ecb60bf5b43b0dc8aa686e69b54fe939 rosaria/CMakeFiles/sensor_msgs_generate_messages_lisp +ecb60bf5b43b0dc8aa686e69b54fe939 rosaria/CMakeFiles/sensor_msgs_generate_messages_py +ecb60bf5b43b0dc8aa686e69b54fe939 rosaria/CMakeFiles/tf2_msgs_generate_messages_cpp +ecb60bf5b43b0dc8aa686e69b54fe939 rosaria/CMakeFiles/tf2_msgs_generate_messages_lisp +ecb60bf5b43b0dc8aa686e69b54fe939 rosaria/CMakeFiles/tf2_msgs_generate_messages_py +ecb60bf5b43b0dc8aa686e69b54fe939 rosaria/CMakeFiles/tf_generate_messages_cpp +ecb60bf5b43b0dc8aa686e69b54fe939 rosaria/CMakeFiles/tf_generate_messages_lisp +ecb60bf5b43b0dc8aa686e69b54fe939 rosaria/CMakeFiles/tf_generate_messages_py +884736c1cf2e8d12735b52fbf36c0bfb rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_cpp +884736c1cf2e8d12735b52fbf36c0bfb rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_lisp +884736c1cf2e8d12735b52fbf36c0bfb rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_py +884736c1cf2e8d12735b52fbf36c0bfb rosaria_msgs/CMakeFiles/rosaria_msgs_gencpp +884736c1cf2e8d12735b52fbf36c0bfb rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages +884736c1cf2e8d12735b52fbf36c0bfb rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_cpp +884736c1cf2e8d12735b52fbf36c0bfb rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_lisp +884736c1cf2e8d12735b52fbf36c0bfb rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_py +884736c1cf2e8d12735b52fbf36c0bfb rosaria_msgs/CMakeFiles/rosaria_msgs_genlisp +884736c1cf2e8d12735b52fbf36c0bfb rosaria_msgs/CMakeFiles/rosaria_msgs_genpy +884736c1cf2e8d12735b52fbf36c0bfb rosaria_msgs/CMakeFiles/std_msgs_generate_messages_cpp +884736c1cf2e8d12735b52fbf36c0bfb rosaria_msgs/CMakeFiles/std_msgs_generate_messages_lisp +884736c1cf2e8d12735b52fbf36c0bfb rosaria_msgs/CMakeFiles/std_msgs_generate_messages_py +73ee8551314fa7957542f8683693dbc9 safety/CMakeFiles/safety_gencpp +73ee8551314fa7957542f8683693dbc9 safety/CMakeFiles/safety_generate_messages +73ee8551314fa7957542f8683693dbc9 safety/CMakeFiles/safety_generate_messages_cpp +73ee8551314fa7957542f8683693dbc9 safety/CMakeFiles/safety_generate_messages_lisp +73ee8551314fa7957542f8683693dbc9 safety/CMakeFiles/safety_generate_messages_py +73ee8551314fa7957542f8683693dbc9 safety/CMakeFiles/safety_genlisp +73ee8551314fa7957542f8683693dbc9 safety/CMakeFiles/safety_genpy +b5d05b5f28673d7881e1997c5e4843e8 videostream/CMakeFiles/videostream_gencpp +b5d05b5f28673d7881e1997c5e4843e8 videostream/CMakeFiles/videostream_generate_messages +b5d05b5f28673d7881e1997c5e4843e8 videostream/CMakeFiles/videostream_generate_messages_cpp +b5d05b5f28673d7881e1997c5e4843e8 videostream/CMakeFiles/videostream_generate_messages_lisp +b5d05b5f28673d7881e1997c5e4843e8 videostream/CMakeFiles/videostream_generate_messages_py +b5d05b5f28673d7881e1997c5e4843e8 videostream/CMakeFiles/videostream_genlisp +b5d05b5f28673d7881e1997c5e4843e8 videostream/CMakeFiles/videostream_genpy diff --git a/Legacy/ws_linux/build/CMakeFiles/CMakeSystem.cmake b/Legacy/ws_linux/build/CMakeFiles/CMakeSystem.cmake new file mode 100644 index 0000000..18a2889 --- /dev/null +++ b/Legacy/ws_linux/build/CMakeFiles/CMakeSystem.cmake @@ -0,0 +1,15 @@ + + +SET(CMAKE_SYSTEM "Linux-3.14.17-xenomai-2.6.4") +SET(CMAKE_SYSTEM_NAME "Linux") +SET(CMAKE_SYSTEM_VERSION "3.14.17-xenomai-2.6.4") +SET(CMAKE_SYSTEM_PROCESSOR "x86_64") + +SET(CMAKE_HOST_SYSTEM "Linux-3.14.17-xenomai-2.6.4") +SET(CMAKE_HOST_SYSTEM_NAME "Linux") +SET(CMAKE_HOST_SYSTEM_VERSION "3.14.17-xenomai-2.6.4") +SET(CMAKE_HOST_SYSTEM_PROCESSOR "x86_64") + +SET(CMAKE_CROSSCOMPILING "FALSE") + +SET(CMAKE_SYSTEM_LOADED 1) diff --git a/Legacy/ws_linux/build/CMakeFiles/CompilerIdC/CMakeCCompilerId.c b/Legacy/ws_linux/build/CMakeFiles/CompilerIdC/CMakeCCompilerId.c new file mode 100644 index 0000000..936ae30 --- /dev/null +++ b/Legacy/ws_linux/build/CMakeFiles/CompilerIdC/CMakeCCompilerId.c @@ -0,0 +1,232 @@ +#ifdef __cplusplus +# error "A C++ compiler has been selected for C." +#endif + +#if defined(__18CXX) +# define ID_VOID_MAIN +#endif + +#if defined(__INTEL_COMPILER) || defined(__ICC) +# define COMPILER_ID "Intel" + +#elif defined(__clang__) +# define COMPILER_ID "Clang" + +#elif defined(__BORLANDC__) +# define COMPILER_ID "Borland" + +#elif defined(__WATCOMC__) +# define COMPILER_ID "Watcom" + +#elif defined(__SUNPRO_C) +# define COMPILER_ID "SunPro" + +#elif defined(__HP_cc) +# define COMPILER_ID "HP" + +#elif defined(__DECC) +# define COMPILER_ID "Compaq" + +#elif defined(__IBMC__) +# if defined(__COMPILER_VER__) +# define COMPILER_ID "zOS" +# elif __IBMC__ >= 800 +# define COMPILER_ID "XL" +# else +# define COMPILER_ID "VisualAge" +# endif + +#elif defined(__PGI) +# define COMPILER_ID "PGI" + +#elif defined(__PATHSCALE__) +# define COMPILER_ID "PathScale" + +#elif defined(_CRAYC) +# define COMPILER_ID "Cray" + +#elif defined(__TI_COMPILER_VERSION__) +# define COMPILER_ID "TI_DSP" + +#elif defined(__TINYC__) +# define COMPILER_ID "TinyCC" + +#elif defined(__SCO_VERSION__) +# define COMPILER_ID "SCO" + +#elif defined(__GNUC__) +# define COMPILER_ID "GNU" + +#elif defined(_MSC_VER) +# define COMPILER_ID "MSVC" + +#elif defined(__ADSPBLACKFIN__) || defined(__ADSPTS__) || defined(__ADSP21000__) +/* Analog Devices C++ compiler for Blackfin, TigerSHARC and + SHARC (21000) DSPs */ +# define COMPILER_ID "ADSP" + +/* IAR Systems compiler for embedded systems. + http://www.iar.com + Not supported yet by CMake +#elif defined(__IAR_SYSTEMS_ICC__) +# define COMPILER_ID "IAR" */ + +/* sdcc, the small devices C compiler for embedded systems, + http://sdcc.sourceforge.net */ +#elif defined(SDCC) +# define COMPILER_ID "SDCC" + +#elif defined(_SGI_COMPILER_VERSION) || defined(_COMPILER_VERSION) +# define COMPILER_ID "MIPSpro" + +/* This compiler is either not known or is too old to define an + identification macro. Try to identify the platform and guess that + it is the native compiler. */ +#elif defined(__sgi) +# define COMPILER_ID "MIPSpro" + +#elif defined(__hpux) || defined(__hpua) +# define COMPILER_ID "HP" + +#else /* unknown compiler */ +# define COMPILER_ID "" + +#endif + +/* Construct the string literal in pieces to prevent the source from + getting matched. Store it in a pointer rather than an array + because some compilers will just produce instructions to fill the + array rather than assigning a pointer to a static array. */ +char const* info_compiler = "INFO" ":" "compiler[" COMPILER_ID "]"; + +/* Identify known platforms by name. */ +#if defined(__linux) || defined(__linux__) || defined(linux) +# define PLATFORM_ID "Linux" + +#elif defined(__CYGWIN__) +# define PLATFORM_ID "Cygwin" + +#elif defined(__MINGW32__) +# define PLATFORM_ID "MinGW" + +#elif defined(__APPLE__) +# define PLATFORM_ID "Darwin" + +#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32) +# define PLATFORM_ID "Windows" + +#elif defined(__FreeBSD__) || defined(__FreeBSD) +# define PLATFORM_ID "FreeBSD" + +#elif defined(__NetBSD__) || defined(__NetBSD) +# define PLATFORM_ID "NetBSD" + +#elif defined(__OpenBSD__) || defined(__OPENBSD) +# define PLATFORM_ID "OpenBSD" + +#elif defined(__sun) || defined(sun) +# define PLATFORM_ID "SunOS" + +#elif defined(_AIX) || defined(__AIX) || defined(__AIX__) || defined(__aix) || defined(__aix__) +# define PLATFORM_ID "AIX" + +#elif defined(__sgi) || defined(__sgi__) || defined(_SGI) +# define PLATFORM_ID "IRIX" + +#elif defined(__hpux) || defined(__hpux__) +# define PLATFORM_ID "HP-UX" + +#elif defined(__HAIKU) || defined(__HAIKU__) || defined(_HAIKU) +# define PLATFORM_ID "Haiku" +/* Haiku also defines __BEOS__ so we must + put it prior to the check for __BEOS__ +*/ + +#elif defined(__BeOS) || defined(__BEOS__) || defined(_BEOS) +# define PLATFORM_ID "BeOS" + +#elif defined(__QNX__) || defined(__QNXNTO__) +# define PLATFORM_ID "QNX" + +#elif defined(__tru64) || defined(_tru64) || defined(__TRU64__) +# define PLATFORM_ID "Tru64" + +#elif defined(__riscos) || defined(__riscos__) +# define PLATFORM_ID "RISCos" + +#elif defined(__sinix) || defined(__sinix__) || defined(__SINIX__) +# define PLATFORM_ID "SINIX" + +#elif defined(__UNIX_SV__) +# define PLATFORM_ID "UNIX_SV" + +#elif defined(__bsdos__) +# define PLATFORM_ID "BSDOS" + +#elif defined(_MPRAS) || defined(MPRAS) +# define PLATFORM_ID "MP-RAS" + +#elif defined(__osf) || defined(__osf__) +# define PLATFORM_ID "OSF1" + +#elif defined(_SCO_SV) || defined(SCO_SV) || defined(sco_sv) +# define PLATFORM_ID "SCO_SV" + +#elif defined(__ultrix) || defined(__ultrix__) || defined(_ULTRIX) +# define PLATFORM_ID "ULTRIX" + +#elif defined(__XENIX__) || defined(_XENIX) || defined(XENIX) +# define PLATFORM_ID "Xenix" + +#else /* unknown platform */ +# define PLATFORM_ID "" + +#endif + +/* For windows compilers MSVC and Intel we can determine + the architecture of the compiler being used. This is because + the compilers do not have flags that can change the architecture, + but rather depend on which compiler is being used +*/ +#if defined(_WIN32) && defined(_MSC_VER) +# if defined(_M_IA64) +# define ARCHITECTURE_ID "IA64" + +# elif defined(_M_X64) || defined(_M_AMD64) +# define ARCHITECTURE_ID "x64" + +# elif defined(_M_IX86) +# define ARCHITECTURE_ID "X86" + +# else /* unknown architecture */ +# define ARCHITECTURE_ID "" +# endif + +#else +# define ARCHITECTURE_ID "" +#endif + +/* Construct the string literal in pieces to prevent the source from + getting matched. Store it in a pointer rather than an array + because some compilers will just produce instructions to fill the + array rather than assigning a pointer to a static array. */ +char const* info_platform = "INFO" ":" "platform[" PLATFORM_ID "]"; +char const* info_arch = "INFO" ":" "arch[" ARCHITECTURE_ID "]"; + + + +/*--------------------------------------------------------------------------*/ + +#ifdef ID_VOID_MAIN +void main() {} +#else +int main(int argc, char* argv[]) +{ + int require = 0; + require += info_compiler[argc]; + require += info_platform[argc]; + require += info_arch[argc]; + (void)argv; + return require; +} +#endif diff --git a/Legacy/ws_linux/build/CMakeFiles/CompilerIdC/a.out b/Legacy/ws_linux/build/CMakeFiles/CompilerIdC/a.out new file mode 100755 index 0000000000000000000000000000000000000000..ec9b7d5ef3fc79a2450bc3b303688d16d9b90fe0 GIT binary patch literal 8472 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 Gw%}jt)KHKB literal 0 HcmV?d00001 diff --git a/Legacy/ws_linux/build/CMakeFiles/CompilerIdCXX/CMakeCXXCompilerId.cpp b/Legacy/ws_linux/build/CMakeFiles/CompilerIdCXX/CMakeCXXCompilerId.cpp new file mode 100644 index 0000000..7414ddf --- /dev/null +++ b/Legacy/ws_linux/build/CMakeFiles/CompilerIdCXX/CMakeCXXCompilerId.cpp @@ -0,0 +1,215 @@ +/* This source file must have a .cpp extension so that all C++ compilers + recognize the extension without flags. Borland does not know .cxx for + example. */ +#ifndef __cplusplus +# error "A C compiler has been selected for C++." +#endif + +#if defined(__COMO__) +# define COMPILER_ID "Comeau" + +#elif defined(__INTEL_COMPILER) || defined(__ICC) +# define COMPILER_ID "Intel" + +#elif defined(__clang__) +# define COMPILER_ID "Clang" + +#elif defined(__BORLANDC__) +# define COMPILER_ID "Borland" + +#elif defined(__WATCOMC__) +# define COMPILER_ID "Watcom" + +#elif defined(__SUNPRO_CC) +# define COMPILER_ID "SunPro" + +#elif defined(__HP_aCC) +# define COMPILER_ID "HP" + +#elif defined(__DECCXX) +# define COMPILER_ID "Compaq" + +#elif defined(__IBMCPP__) +# if defined(__COMPILER_VER__) +# define COMPILER_ID "zOS" +# elif __IBMCPP__ >= 800 +# define COMPILER_ID "XL" +# else +# define COMPILER_ID "VisualAge" +# endif + +#elif defined(__PGI) +# define COMPILER_ID "PGI" + +#elif defined(__PATHSCALE__) +# define COMPILER_ID "PathScale" + +#elif defined(_CRAYC) +# define COMPILER_ID "Cray" + +#elif defined(__TI_COMPILER_VERSION__) +# define COMPILER_ID "TI_DSP" + +#elif defined(__SCO_VERSION__) +# define COMPILER_ID "SCO" + +#elif defined(__GNUC__) +# define COMPILER_ID "GNU" + +#elif defined(_MSC_VER) +# define COMPILER_ID "MSVC" + +#elif defined(__ADSPBLACKFIN__) || defined(__ADSPTS__) || defined(__ADSP21000__) +/* Analog Devices C++ compiler for Blackfin, TigerSHARC and + SHARC (21000) DSPs */ +# define COMPILER_ID "ADSP" + +#elif defined(_SGI_COMPILER_VERSION) || defined(_COMPILER_VERSION) +# define COMPILER_ID "MIPSpro" + +/* This compiler is either not known or is too old to define an + identification macro. Try to identify the platform and guess that + it is the native compiler. */ +#elif defined(__sgi) +# define COMPILER_ID "MIPSpro" + +#elif defined(__hpux) || defined(__hpua) +# define COMPILER_ID "HP" + +#else /* unknown compiler */ +# define COMPILER_ID "" + +#endif + +/* Construct the string literal in pieces to prevent the source from + getting matched. Store it in a pointer rather than an array + because some compilers will just produce instructions to fill the + array rather than assigning a pointer to a static array. */ +char const* info_compiler = "INFO" ":" "compiler[" COMPILER_ID "]"; + +/* Identify known platforms by name. */ +#if defined(__linux) || defined(__linux__) || defined(linux) +# define PLATFORM_ID "Linux" + +#elif defined(__CYGWIN__) +# define PLATFORM_ID "Cygwin" + +#elif defined(__MINGW32__) +# define PLATFORM_ID "MinGW" + +#elif defined(__APPLE__) +# define PLATFORM_ID "Darwin" + +#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32) +# define PLATFORM_ID "Windows" + +#elif defined(__FreeBSD__) || defined(__FreeBSD) +# define PLATFORM_ID "FreeBSD" + +#elif defined(__NetBSD__) || defined(__NetBSD) +# define PLATFORM_ID "NetBSD" + +#elif defined(__OpenBSD__) || defined(__OPENBSD) +# define PLATFORM_ID "OpenBSD" + +#elif defined(__sun) || defined(sun) +# define PLATFORM_ID "SunOS" + +#elif defined(_AIX) || defined(__AIX) || defined(__AIX__) || defined(__aix) || defined(__aix__) +# define PLATFORM_ID "AIX" + +#elif defined(__sgi) || defined(__sgi__) || defined(_SGI) +# define PLATFORM_ID "IRIX" + +#elif defined(__hpux) || defined(__hpux__) +# define PLATFORM_ID "HP-UX" + +#elif defined(__HAIKU) || defined(__HAIKU__) || defined(_HAIKU) +# define PLATFORM_ID "Haiku" +/* Haiku also defines __BEOS__ so we must + put it prior to the check for __BEOS__ +*/ + +#elif defined(__BeOS) || defined(__BEOS__) || defined(_BEOS) +# define PLATFORM_ID "BeOS" + +#elif defined(__QNX__) || defined(__QNXNTO__) +# define PLATFORM_ID "QNX" + +#elif defined(__tru64) || defined(_tru64) || defined(__TRU64__) +# define PLATFORM_ID "Tru64" + +#elif defined(__riscos) || defined(__riscos__) +# define PLATFORM_ID "RISCos" + +#elif defined(__sinix) || defined(__sinix__) || defined(__SINIX__) +# define PLATFORM_ID "SINIX" + +#elif defined(__UNIX_SV__) +# define PLATFORM_ID "UNIX_SV" + +#elif defined(__bsdos__) +# define PLATFORM_ID "BSDOS" + +#elif defined(_MPRAS) || defined(MPRAS) +# define PLATFORM_ID "MP-RAS" + +#elif defined(__osf) || defined(__osf__) +# define PLATFORM_ID "OSF1" + +#elif defined(_SCO_SV) || defined(SCO_SV) || defined(sco_sv) +# define PLATFORM_ID "SCO_SV" + +#elif defined(__ultrix) || defined(__ultrix__) || defined(_ULTRIX) +# define PLATFORM_ID "ULTRIX" + +#elif defined(__XENIX__) || defined(_XENIX) || defined(XENIX) +# define PLATFORM_ID "Xenix" + +#else /* unknown platform */ +# define PLATFORM_ID "" + +#endif + +/* For windows compilers MSVC and Intel we can determine + the architecture of the compiler being used. This is because + the compilers do not have flags that can change the architecture, + but rather depend on which compiler is being used +*/ +#if defined(_WIN32) && defined(_MSC_VER) +# if defined(_M_IA64) +# define ARCHITECTURE_ID "IA64" + +# elif defined(_M_X64) || defined(_M_AMD64) +# define ARCHITECTURE_ID "x64" + +# elif defined(_M_IX86) +# define ARCHITECTURE_ID "X86" + +# else /* unknown architecture */ +# define ARCHITECTURE_ID "" +# endif + +#else +# define ARCHITECTURE_ID "" +#endif + +/* Construct the string literal in pieces to prevent the source from + getting matched. Store it in a pointer rather than an array + because some compilers will just produce instructions to fill the + array rather than assigning a pointer to a static array. */ +char const* info_platform = "INFO" ":" "platform[" PLATFORM_ID "]"; +char const* info_arch = "INFO" ":" "arch[" ARCHITECTURE_ID "]"; + + + +/*--------------------------------------------------------------------------*/ + +int main(int argc, char* argv[]) +{ + int require = 0; + require += info_compiler[argc]; + require += info_platform[argc]; + (void)argv; + return require; +} diff --git a/Legacy/ws_linux/build/CMakeFiles/CompilerIdCXX/a.out b/Legacy/ws_linux/build/CMakeFiles/CompilerIdCXX/a.out new file mode 100755 index 0000000000000000000000000000000000000000..24724234ef21d6675b75238af05647fff26db3c9 GIT binary patch literal 8476 zcmeHMZ){W76+gChI zunC$FX~aiUB}A>9(A!+KP%q1QkT&2GbX!2st*MOA%@zzo#Y3WGubMQ@TJ$D4gh?oX zPw}KjMO&H`i*!U~gnHSJ4yK|C?aSUXk+huH9>VP=5HE_-^UcFh~4263+Sr?f*aq`O8*jS*Y^Ci_peR}VOm1u|Tn(Y?}Bj3Cyf2*UR^8Cpw zr4p4DesDuCqsfQQ)?@&dU^g_x% z7b(R3^ZL22b!a(q?%_2=5MPKCO#fn}aK?XIFFfVP=-dcK9=Y0ExEn6q(l6ijgbROK zIB>6A)?fa_+`R42)E|+;=aIs#zQR9x%j-YXr>|g4uIE42i%!q!{;iL@?)z z6ixq@Nb!un8^aL1($aaBTJkT;tx6YE;*SxZ@?!X=ZI-!A7r z<%n8+yYK}0W{n;fj=u1rfy29FnTg3{Dv>>bGw-AYO{SveSSCAhB0^J{!Du!%e&Qs! zHhK2YSf)8!x{K8zeI2WvL^_YOgme;zlj!4oY~1tc4*%B)CK(()uo>$fB%rss^%Zw$ZIgQ+)@0QaM_9-5 z0+m1cYU3+SMzc1(;)m|nJm(tR$D2`1`SB{!3n*7J??`7kEk|HE0?QFtj=*vRmLu?` zB7mQGl|GkhrgqgKD$@W5IyhKh*bA>EH8VSi*AjIVU>F0 zzLDu_rX5T-Fcm_33`z?vBZ|tufXK`L$_iBq@Bq^(wlDYy^Ym{)N%Zk&UnSx3cSE&D zV|k2|;$1Aa$b68?8UDW$*{?bcy?Y-&ZgBsUnXYfrlTzX>$9ktwMw2#WOK<(x`r{ZESpG0Nr7{dDH8(8bQ0fYVhZ15 z$Y5C}9yOy7NQ@g}+2};V7>}c_a1e-@nQRUXTI87+7Gj;ziDV27X0RH31ytQuJ)=34 z#^39SMA~$Q`G4j&p$3f^8LvUNhFtZ$M9xJNh%Xsm!asx=8oQ!D?ADO0o=5l;SA8{9 zvnsa@-*$b|tts5(3jK0k%aM7dgz$9;ADY{uf6=WW z2XK)AU2)dg47FYKWgdPTF`E0L4>HbqK?t(G5NG_J#sZqVqA&9`$ojG_iT@%e^jXxW zwLo}T4>Z>Iv0Og++GzL##i<9rDwv zs>(_K3494Nq|f29op)Li5@(C6_P_8mn6c~A2@a(o2kyV={{dy~`gD3jNoRehzfS&r zl%=MM|MLBkbJ!A9j!DL+=!;(;Vwv5(oWsqxD7DIXx43HirJlb!^yU9yf%Sc&$W-)% ze(ccq@_C<^9o%vseSsG-Lv=~}yIH@R^`)I6FLs6h3^UaJZULBz{-X|@!>M$rh>rWk zwq5kQZ1|oX#JuPWOuWn;!HCZB!qv?k_f^CK_=x|quF-#0J^S8HEWothQMuE;B~}0J zL2rX@ZAqaAJ(lmJz0iZ6$oH=nZ>apY*5Zx$ozm=(%6n+Edg|dTK)x?_B@aeLt1G_} zM(X0LK-T%%dRBw1-?jJ}kaf8hUt78Vsl}T?*3nwL1!R4!#ak=)7PWXA$a+?bw^!Dw zT6`U@J0o^Tg_Pj28;Y1QeTDgCv z;5^|_oxcrS@H2&XfX^`=evLTA0XPoypGWB(#HqcSqyFEs{H#Y)a`Ji)@ivTGhok<# za6QhrUFUk}{)*C|dIKyX?&G|jG++m{;|`+a(d;m+LY(YwaoB}eG?lVl1wt%q=FB|a zOvUgfFf@Glh!F`N9mX3%!|1Ew_J?dm@r-dQl^Knu47F`EqWLMH8<$kVOvD2{yLM~? zDln4qDdKj3weyVUCnipdo&H08%FMu#-h=&yaAZdERV!+bs;q<#MxRZDjvo*4{Z2R@ zh)qsnowV^aqS8A#( zi_lmuZ>Wtk?RKqeQ7{r}>ucd07;(~Zd#Y*n>r=z9*J6viYI!`DF~+0mcq#!#_%Pav zC(}kgmxx0$J(e-#zRK>I+TL3YwA!L1<+2MUad*y6tGird|8vHX#HnNs4") +set(catkin_BUILDTOOL_DEPENDS "cmake") +set(catkin_RUN_DEPENDS_python-catkin-pkg_VERSION_GTE "0.2.0") \ No newline at end of file diff --git a/Legacy/ws_linux/build/catkin_generated/env_cached.sh b/Legacy/ws_linux/build/catkin_generated/env_cached.sh new file mode 100755 index 0000000..d6be91d --- /dev/null +++ b/Legacy/ws_linux/build/catkin_generated/env_cached.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env sh +# generated from catkin/cmake/templates/env.sh.in + +if [ $# -eq 0 ] ; then + /bin/echo "Usage: env.sh COMMANDS" + /bin/echo "Calling env.sh without arguments is not supported anymore. Instead spawn a subshell and source a setup file manually." + exit 1 +fi + +# ensure to not use different shell type which was set before +CATKIN_SHELL=sh + +# source setup_cached.sh from same directory as this file +_CATKIN_SETUP_DIR=$(cd "`dirname "$0"`" > /dev/null && pwd) +. "$_CATKIN_SETUP_DIR/setup_cached.sh" +exec "$@" diff --git a/Legacy/ws_linux/build/catkin_generated/generate_cached_setup.py b/Legacy/ws_linux/build/catkin_generated/generate_cached_setup.py new file mode 100644 index 0000000..88a1cf4 --- /dev/null +++ b/Legacy/ws_linux/build/catkin_generated/generate_cached_setup.py @@ -0,0 +1,29 @@ +from __future__ import print_function +import argparse +import os +import stat +import sys + +# find the import for catkin's python package - either from source space or from an installed underlay +if os.path.exists(os.path.join('/opt/ros/hydro/share/catkin/cmake', 'catkinConfig.cmake.in')): + sys.path.insert(0, os.path.join('/opt/ros/hydro/share/catkin/cmake', '..', 'python')) +try: + from catkin.environment_cache import generate_environment_script +except ImportError: + # search for catkin package in all workspaces and prepend to path + for workspace in "/home/lab1_5/ws/ws_linux/devel;/home/lab1_5/ws/ws_xeno/devel;/home/lab1_5/ws/ws_isolated/install_isolated;/opt/ros/hydro".split(';'): + python_path = os.path.join(workspace, 'lib/python2.7/dist-packages') + if os.path.isdir(os.path.join(python_path, 'catkin')): + sys.path.insert(0, python_path) + break + from catkin.environment_cache import generate_environment_script + +code = generate_environment_script('/home/lab1_5/ws/ws_linux/devel/env.sh') + +output_filename = '/home/lab1_5/ws/ws_linux/build/catkin_generated/setup_cached.sh' +with open(output_filename, 'w') as f: + #print('Generate script for cached setup "%s"' % output_filename) + f.write('\n'.join(code)) + +mode = os.stat(output_filename).st_mode +os.chmod(output_filename, mode | stat.S_IXUSR) diff --git a/Legacy/ws_linux/build/catkin_generated/installspace/.rosinstall b/Legacy/ws_linux/build/catkin_generated/installspace/.rosinstall new file mode 100644 index 0000000..515131f --- /dev/null +++ b/Legacy/ws_linux/build/catkin_generated/installspace/.rosinstall @@ -0,0 +1,2 @@ +- setup-file: + local-name: /home/lab1_5/ws/ws_linux/install/setup.sh diff --git a/Legacy/ws_linux/build/catkin_generated/installspace/_setup_util.py b/Legacy/ws_linux/build/catkin_generated/installspace/_setup_util.py new file mode 100755 index 0000000..1ba3413 --- /dev/null +++ b/Legacy/ws_linux/build/catkin_generated/installspace/_setup_util.py @@ -0,0 +1,280 @@ +#!/usr/bin/env python + +# Software License Agreement (BSD License) +# +# Copyright (c) 2012, Willow Garage, Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following +# disclaimer in the documentation and/or other materials provided +# with the distribution. +# * Neither the name of Willow Garage, Inc. nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + +'''This file generates shell code for the setup.SHELL scripts to set environment variables''' + +from __future__ import print_function +import argparse +import copy +import errno +import os +import platform +import sys + +CATKIN_MARKER_FILE = '.catkin' + +system = platform.system() +IS_DARWIN = (system == 'Darwin') +IS_WINDOWS = (system == 'Windows') + +# subfolder of workspace prepended to CMAKE_PREFIX_PATH +ENV_VAR_SUBFOLDERS = { + 'CMAKE_PREFIX_PATH': '', + 'CPATH': 'include', + 'LD_LIBRARY_PATH' if not IS_DARWIN else 'DYLD_LIBRARY_PATH': 'lib', + 'PATH': 'bin', + 'PKG_CONFIG_PATH': 'lib/pkgconfig', + 'PYTHONPATH': 'lib/python2.7/dist-packages', +} + + +def rollback_env_variables(environ, env_var_subfolders): + ''' + Generate shell code to reset environment variables + by unrolling modifications based on all workspaces in CMAKE_PREFIX_PATH. + This does not cover modifications performed by environment hooks. + ''' + lines = [] + unmodified_environ = copy.copy(environ) + for key in sorted(env_var_subfolders.keys()): + subfolder = env_var_subfolders[key] + value = _rollback_env_variable(unmodified_environ, key, subfolder) + if value is not None: + environ[key] = value + lines.append(assignment(key, value)) + if lines: + lines.insert(0, comment('reset environment variables by unrolling modifications based on all workspaces in CMAKE_PREFIX_PATH')) + return lines + + +def _rollback_env_variable(environ, name, subfolder): + ''' + For each catkin workspace in CMAKE_PREFIX_PATH remove the first entry from env[NAME] matching workspace + subfolder. + + :param subfolder: str '' or subfoldername that may start with '/' + :returns: the updated value of the environment variable. + ''' + value = environ[name] if name in environ else '' + env_paths = [path for path in value.split(os.pathsep) if path] + value_modified = False + if subfolder: + if subfolder.startswith(os.path.sep) or (os.path.altsep and subfolder.startswith(os.path.altsep)): + subfolder = subfolder[1:] + if subfolder.endswith(os.path.sep) or (os.path.altsep and subfolder.endswith(os.path.altsep)): + subfolder = subfolder[:-1] + for ws_path in _get_workspaces(environ, include_fuerte=True, include_non_existing=True): + path_to_find = os.path.join(ws_path, subfolder) if subfolder else ws_path + path_to_remove = None + for env_path in env_paths: + env_path_clean = env_path[:-1] if env_path and env_path[-1] in [os.path.sep, os.path.altsep] else env_path + if env_path_clean == path_to_find: + path_to_remove = env_path + break + if path_to_remove: + env_paths.remove(path_to_remove) + value_modified = True + new_value = os.pathsep.join(env_paths) + return new_value if value_modified else None + + +def _get_workspaces(environ, include_fuerte=False, include_non_existing=False): + ''' + Based on CMAKE_PREFIX_PATH return all catkin workspaces. + + :param include_fuerte: The flag if paths starting with '/opt/ros/fuerte' should be considered workspaces, ``bool`` + ''' + # get all cmake prefix paths + env_name = 'CMAKE_PREFIX_PATH' + value = environ[env_name] if env_name in environ else '' + paths = [path for path in value.split(os.pathsep) if path] + # remove non-workspace paths + workspaces = [path for path in paths if os.path.isfile(os.path.join(path, CATKIN_MARKER_FILE)) or (include_fuerte and path.startswith('/opt/ros/fuerte')) or (include_non_existing and not os.path.exists(path))] + return workspaces + + +def prepend_env_variables(environ, env_var_subfolders, workspaces): + ''' + Generate shell code to prepend environment variables + for the all workspaces. + ''' + lines = [] + lines.append(comment('prepend folders of workspaces to environment variables')) + + paths = [path for path in workspaces.split(os.pathsep) if path] + + prefix = _prefix_env_variable(environ, 'CMAKE_PREFIX_PATH', paths, '') + lines.append(prepend(environ, 'CMAKE_PREFIX_PATH', prefix)) + + for key in sorted([key for key in env_var_subfolders.keys() if key != 'CMAKE_PREFIX_PATH']): + subfolder = env_var_subfolders[key] + prefix = _prefix_env_variable(environ, key, paths, subfolder) + lines.append(prepend(environ, key, prefix)) + return lines + + +def _prefix_env_variable(environ, name, paths, subfolder): + ''' + Return the prefix to prepend to the environment variable NAME, adding any path in NEW_PATHS_STR without creating duplicate or empty items. + ''' + value = environ[name] if name in environ else '' + environ_paths = [path for path in value.split(os.pathsep) if path] + checked_paths = [] + for path in paths: + if subfolder: + path = os.path.join(path, subfolder) + # exclude any path already in env and any path we already added + if path not in environ_paths and path not in checked_paths: + checked_paths.append(path) + prefix_str = os.pathsep.join(checked_paths) + if prefix_str != '' and environ_paths: + prefix_str += os.pathsep + return prefix_str + + +def assignment(key, value): + if not IS_WINDOWS: + return 'export %s="%s"' % (key, value) + else: + return 'set %s=%s' % (key, value) + + +def comment(msg): + if not IS_WINDOWS: + return '# %s' % msg + else: + return 'REM %s' % msg + + +def prepend(environ, key, prefix): + if key not in environ or not environ[key]: + return assignment(key, prefix) + if not IS_WINDOWS: + return 'export %s="%s$%s"' % (key, prefix, key) + else: + return 'set %s=%s%%%s%%' % (key, prefix, key) + + +def find_env_hooks(environ, cmake_prefix_path): + ''' + Generate shell code with found environment hooks + for the all workspaces. + ''' + lines = [] + lines.append(comment('found environment hooks in workspaces')) + + generic_env_hooks = [] + generic_env_hooks_workspace = [] + specific_env_hooks = [] + specific_env_hooks_workspace = [] + generic_env_hooks_by_filename = {} + specific_env_hooks_by_filename = {} + generic_env_hook_ext = 'bat' if IS_WINDOWS else 'sh' + specific_env_hook_ext = environ['CATKIN_SHELL'] if not IS_WINDOWS and 'CATKIN_SHELL' in environ and environ['CATKIN_SHELL'] else None + # remove non-workspace paths + workspaces = [path for path in cmake_prefix_path.split(os.pathsep) if path and os.path.isfile(os.path.join(path, CATKIN_MARKER_FILE))] + for workspace in reversed(workspaces): + env_hook_dir = os.path.join(workspace, 'etc', 'catkin', 'profile.d') + if os.path.isdir(env_hook_dir): + for filename in sorted(os.listdir(env_hook_dir)): + if filename.endswith('.%s' % generic_env_hook_ext): + # remove previous env hook with same name if present + if filename in generic_env_hooks_by_filename: + i = generic_env_hooks.index(generic_env_hooks_by_filename[filename]) + generic_env_hooks.pop(i) + generic_env_hooks_workspace.pop(i) + # append env hook + generic_env_hooks.append(os.path.join(env_hook_dir, filename)) + generic_env_hooks_workspace.append(workspace) + generic_env_hooks_by_filename[filename] = generic_env_hooks[-1] + elif specific_env_hook_ext is not None and filename.endswith('.%s' % specific_env_hook_ext): + # remove previous env hook with same name if present + if filename in specific_env_hooks_by_filename: + i = specific_env_hooks.index(specific_env_hooks_by_filename[filename]) + specific_env_hooks.pop(i) + specific_env_hooks_workspace.pop(i) + # append env hook + specific_env_hooks.append(os.path.join(env_hook_dir, filename)) + specific_env_hooks_workspace.append(workspace) + specific_env_hooks_by_filename[filename] = specific_env_hooks[-1] + env_hooks = generic_env_hooks + specific_env_hooks + env_hooks_workspace = generic_env_hooks_workspace + specific_env_hooks_workspace + count = len(env_hooks) + lines.append(assignment('_CATKIN_ENVIRONMENT_HOOKS_COUNT', count)) + for i in range(count): + lines.append(assignment('_CATKIN_ENVIRONMENT_HOOKS_%d' % i, env_hooks[i])) + lines.append(assignment('_CATKIN_ENVIRONMENT_HOOKS_%d_WORKSPACE' % i, env_hooks_workspace[i])) + return lines + + +def _parse_arguments(args=None): + parser = argparse.ArgumentParser(description='Generates code blocks for the setup.SHELL script.') + parser.add_argument('--extend', action='store_true', help='Skip unsetting previous environment variables to extend context') + return parser.parse_known_args(args=args)[0] + + +if __name__ == '__main__': + try: + try: + args = _parse_arguments() + except Exception as e: + print(e, file=sys.stderr) + sys.exit(1) + + # environment at generation time + CMAKE_PREFIX_PATH = '/home/lab1_5/ws/ws_linux/devel;/home/lab1_5/ws/ws_xeno/devel;/home/lab1_5/ws/ws_isolated/install_isolated;/home/lab1_5/ws/install_isolated;/opt/ros/hydro'.split(';') + # prepend current workspace if not already part of CPP + base_path = os.path.dirname(__file__) + if base_path not in CMAKE_PREFIX_PATH: + CMAKE_PREFIX_PATH.insert(0, base_path) + CMAKE_PREFIX_PATH = os.pathsep.join(CMAKE_PREFIX_PATH) + + environ = dict(os.environ) + lines = [] + if not args.extend: + lines += rollback_env_variables(environ, ENV_VAR_SUBFOLDERS) + lines += prepend_env_variables(environ, ENV_VAR_SUBFOLDERS, CMAKE_PREFIX_PATH) + lines += find_env_hooks(environ, CMAKE_PREFIX_PATH) + print('\n'.join(lines)) + + # need to explicitly flush the output + sys.stdout.flush() + except IOError as e: + # and catch potantial "broken pipe" if stdout is not writable + # which can happen when piping the output to a file but the disk is full + if e.errno == errno.EPIPE: + print(e, file=sys.stderr) + sys.exit(2) + raise + + sys.exit(0) diff --git a/Legacy/ws_linux/build/catkin_generated/installspace/env.sh b/Legacy/ws_linux/build/catkin_generated/installspace/env.sh new file mode 100755 index 0000000..8aa9d24 --- /dev/null +++ b/Legacy/ws_linux/build/catkin_generated/installspace/env.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env sh +# generated from catkin/cmake/templates/env.sh.in + +if [ $# -eq 0 ] ; then + /bin/echo "Usage: env.sh COMMANDS" + /bin/echo "Calling env.sh without arguments is not supported anymore. Instead spawn a subshell and source a setup file manually." + exit 1 +fi + +# ensure to not use different shell type which was set before +CATKIN_SHELL=sh + +# source setup.sh from same directory as this file +_CATKIN_SETUP_DIR=$(cd "`dirname "$0"`" > /dev/null && pwd) +. "$_CATKIN_SETUP_DIR/setup.sh" +exec "$@" diff --git a/Legacy/ws_linux/build/catkin_generated/installspace/setup.bash b/Legacy/ws_linux/build/catkin_generated/installspace/setup.bash new file mode 100644 index 0000000..ff47af8 --- /dev/null +++ b/Legacy/ws_linux/build/catkin_generated/installspace/setup.bash @@ -0,0 +1,8 @@ +#!/usr/bin/env bash +# generated from catkin/cmake/templates/setup.bash.in + +CATKIN_SHELL=bash + +# source setup.sh from same directory as this file +_CATKIN_SETUP_DIR=$(builtin cd "`dirname "${BASH_SOURCE[0]}"`" > /dev/null && pwd) +. "$_CATKIN_SETUP_DIR/setup.sh" diff --git a/Legacy/ws_linux/build/catkin_generated/installspace/setup.sh b/Legacy/ws_linux/build/catkin_generated/installspace/setup.sh new file mode 100644 index 0000000..081053d --- /dev/null +++ b/Legacy/ws_linux/build/catkin_generated/installspace/setup.sh @@ -0,0 +1,87 @@ +#!/usr/bin/env sh +# generated from catkin/cmake/template/setup.sh.in + +# Sets various environment variables and sources additional environment hooks. +# It tries it's best to undo changes from a previously sourced setup file before. +# Supported command line options: +# --extend: skips the undoing of changes from a previously sourced setup file + +# since this file is sourced either use the provided _CATKIN_SETUP_DIR +# or fall back to the destination set at configure time +: ${_CATKIN_SETUP_DIR:=/home/lab1_5/ws/ws_linux/install} +_SETUP_UTIL="$_CATKIN_SETUP_DIR/_setup_util.py" +unset _CATKIN_SETUP_DIR + +if [ ! -f "$_SETUP_UTIL" ]; then + echo "Missing Python script: $_SETUP_UTIL" + return 22 +fi + +# detect if running on Darwin platform +_UNAME=`uname -s` +_IS_DARWIN=0 +if [ "$_UNAME" = "Darwin" ]; then + _IS_DARWIN=1 +fi +unset _UNAME + +# make sure to export all environment variables +export CMAKE_PREFIX_PATH +export CPATH +if [ $_IS_DARWIN -eq 0 ]; then + export LD_LIBRARY_PATH +else + export DYLD_LIBRARY_PATH +fi +unset _IS_DARWIN +export PATH +export PKG_CONFIG_PATH +export PYTHONPATH + +# remember type of shell if not already set +if [ -z "$CATKIN_SHELL" ]; then + CATKIN_SHELL=sh +fi + +# invoke Python script to generate necessary exports of environment variables +_SETUP_TMP=`mktemp /tmp/setup.sh.XXXXXXXXXX` +if [ $? -ne 0 -o ! -f "$_SETUP_TMP" ]; then + echo "Could not create temporary file: $_SETUP_TMP" + return 1 +fi +CATKIN_SHELL=$CATKIN_SHELL "$_SETUP_UTIL" $@ > $_SETUP_TMP +_RC=$? +if [ $_RC -ne 0 ]; then + if [ $_RC -eq 2 ]; then + echo "Could not write the output of '$_SETUP_UTIL' to temporary file '$_SETUP_TMP': may be the disk if full?" + else + echo "Failed to run '\"$_SETUP_UTIL\" $@': return code $_RC" + fi + unset _RC + unset _SETUP_UTIL + rm -f $_SETUP_TMP + unset _SETUP_TMP + return 1 +fi +unset _RC +unset _SETUP_UTIL +. $_SETUP_TMP +rm -f $_SETUP_TMP +unset _SETUP_TMP + +# source all environment hooks +_i=0 +while [ $_i -lt $_CATKIN_ENVIRONMENT_HOOKS_COUNT ]; do + eval _envfile=\$_CATKIN_ENVIRONMENT_HOOKS_$_i + unset _CATKIN_ENVIRONMENT_HOOKS_$_i + eval _envfile_workspace=\$_CATKIN_ENVIRONMENT_HOOKS_${_i}_WORKSPACE + unset _CATKIN_ENVIRONMENT_HOOKS_${_i}_WORKSPACE + # set workspace for environment hook + CATKIN_ENV_HOOK_WORKSPACE=$_envfile_workspace + . "$_envfile" + unset CATKIN_ENV_HOOK_WORKSPACE + _i=$((_i + 1)) +done +unset _i + +unset _CATKIN_ENVIRONMENT_HOOKS_COUNT diff --git a/Legacy/ws_linux/build/catkin_generated/installspace/setup.zsh b/Legacy/ws_linux/build/catkin_generated/installspace/setup.zsh new file mode 100644 index 0000000..b660717 --- /dev/null +++ b/Legacy/ws_linux/build/catkin_generated/installspace/setup.zsh @@ -0,0 +1,8 @@ +#!/usr/bin/env zsh +# generated from catkin/cmake/templates/setup.zsh.in + +CATKIN_SHELL=zsh +_CATKIN_SETUP_DIR=$(builtin cd -q "`dirname "$0"`" > /dev/null && pwd) +emulate sh # emulate POSIX +. "$_CATKIN_SETUP_DIR/setup.sh" +emulate zsh # back to zsh mode diff --git a/Legacy/ws_linux/build/catkin_generated/order_packages.cmake b/Legacy/ws_linux/build/catkin_generated/order_packages.cmake new file mode 100644 index 0000000..dd1f6d1 --- /dev/null +++ b/Legacy/ws_linux/build/catkin_generated/order_packages.cmake @@ -0,0 +1,26 @@ +# generated from catkin/cmake/em/order_packages.cmake.em + +set(CATKIN_ORDERED_PACKAGES "") +set(CATKIN_ORDERED_PACKAGE_PATHS "") +set(CATKIN_ORDERED_PACKAGES_IS_META "") +set(CATKIN_ORDERED_PACKAGES_BUILD_TYPE "") +list(APPEND CATKIN_ORDERED_PACKAGES "rosaria_msgs") +list(APPEND CATKIN_ORDERED_PACKAGE_PATHS "rosaria_msgs") +list(APPEND CATKIN_ORDERED_PACKAGES_IS_META "False") +list(APPEND CATKIN_ORDERED_PACKAGES_BUILD_TYPE "catkin") +list(APPEND CATKIN_ORDERED_PACKAGES "rosaria") +list(APPEND CATKIN_ORDERED_PACKAGE_PATHS "rosaria") +list(APPEND CATKIN_ORDERED_PACKAGES_IS_META "False") +list(APPEND CATKIN_ORDERED_PACKAGES_BUILD_TYPE "catkin") +list(APPEND CATKIN_ORDERED_PACKAGES "safety") +list(APPEND CATKIN_ORDERED_PACKAGE_PATHS "safety") +list(APPEND CATKIN_ORDERED_PACKAGES_IS_META "False") +list(APPEND CATKIN_ORDERED_PACKAGES_BUILD_TYPE "catkin") +list(APPEND CATKIN_ORDERED_PACKAGES "videostream") +list(APPEND CATKIN_ORDERED_PACKAGE_PATHS "videostream") +list(APPEND CATKIN_ORDERED_PACKAGES_IS_META "False") +list(APPEND CATKIN_ORDERED_PACKAGES_BUILD_TYPE "catkin") + +set(CATKIN_MESSAGE_GENERATORS ) + +set(CATKIN_METAPACKAGE_CMAKE_TEMPLATE "/usr/lib/python2.7/dist-packages/catkin_pkg/templates/metapackage.cmake.in") diff --git a/Legacy/ws_linux/build/catkin_generated/order_packages.py b/Legacy/ws_linux/build/catkin_generated/order_packages.py new file mode 100644 index 0000000..14bb87f --- /dev/null +++ b/Legacy/ws_linux/build/catkin_generated/order_packages.py @@ -0,0 +1,5 @@ +# generated from catkin/cmake/template/order_packages.context.py.in +source_root_dir = "/home/lab1_5/ws/ws_linux/src" +whitelisted_packages = "".split(';') if "" != "" else [] +blacklisted_packages = "".split(';') if "" != "" else [] +underlay_workspaces = "/home/lab1_5/ws/ws_linux/devel;/home/lab1_5/ws/ws_xeno/devel;/home/lab1_5/ws/ws_isolated/install_isolated;/opt/ros/hydro".split(';') if "/home/lab1_5/ws/ws_linux/devel;/home/lab1_5/ws/ws_xeno/devel;/home/lab1_5/ws/ws_isolated/install_isolated;/opt/ros/hydro" != "" else [] diff --git a/Legacy/ws_linux/build/catkin_generated/setup_cached.sh b/Legacy/ws_linux/build/catkin_generated/setup_cached.sh new file mode 100755 index 0000000..acd1ad5 --- /dev/null +++ b/Legacy/ws_linux/build/catkin_generated/setup_cached.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env sh +# generated from catkin/python/catkin/environment_cache.py + +# based on a snapshot of the environment before and after calling the setup script +# it emulates the modifications of the setup script without recurring computations + +# new environment variables + +# modified environment variables +export LD_LIBRARY_PATH="/home/lab1_5/ws/ws_isolated/install_isolated/lib/typelib:/home/lab1_5/ws/ws_linux/devel/lib:/home/lab1_5/ws/ws_xeno/devel/lib:/home/lab1_5/ws/ws_isolated/install_isolated/lib:/home/lab1_5/ws/install_isolated/lib:/opt/ros/hydro/lib:/home/lab1_5/ws/ws_isolated/install_isolated/lib/typelib:/opt/ros/hydro/lib/typelib:/home/lab1_5/ws/ws_isolated/install_isolated/lib/typelib:/opt/ros/hydro/lib/typelib" +export LUA_PATH=";;/home/lab1_5/ws/ws_isolated/install_isolated/share/lua/5.1/?.lua;/home/lab1_5/ws/ws_isolated/install_isolated/share/lua/5.1/?.lua;/home/lab1_5/ws/ws_isolated/install_isolated/share/lua/5.1/?.lua" +export PWD="/home/lab1_5/ws/ws_linux/build" \ No newline at end of file diff --git a/Legacy/ws_linux/build/catkin_generated/stamps/Project/interrogate_setup_dot_py.py.stamp b/Legacy/ws_linux/build/catkin_generated/stamps/Project/interrogate_setup_dot_py.py.stamp new file mode 100644 index 0000000..26882f0 --- /dev/null +++ b/Legacy/ws_linux/build/catkin_generated/stamps/Project/interrogate_setup_dot_py.py.stamp @@ -0,0 +1,250 @@ +#!/usr/bin/env python + +# Software License Agreement (BSD License) +# +# Copyright (c) 2012, Willow Garage, Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following +# disclaimer in the documentation and/or other materials provided +# with the distribution. +# * Neither the name of Willow Garage, Inc. nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + +from __future__ import print_function +import os +import sys + +import distutils.core +try: + import setuptools +except ImportError: + pass + +from argparse import ArgumentParser + + +def _get_locations(pkgs, package_dir): + """ + based on setuptools logic and the package_dir dict, builds a dict + of location roots for each pkg in pkgs. + See http://docs.python.org/distutils/setupscript.html + + :returns: a dict {pkgname: root} for each pkgname in pkgs (and each of their parents) + """ + # package_dir contains a dict {package_name: relativepath} + # Example {'': 'src', 'foo': 'lib', 'bar': 'lib2'} + # + # '' means where to look for any package unless a parent package + # is listed so package bar.pot is expected at lib2/bar/pot, + # whereas package sup.dee is expected at src/sup/dee + # + # if package_dir does not state anything about a package, + # setuptool expects the package folder to be in the root of the + # project + locations = {} + allprefix = package_dir.get('', '') + for pkg in pkgs: + parent_location = None + splits = pkg.split('.') + # we iterate over compound name from parent to child + # so once we found parent, children just append to their parent + for key_len in range(len(splits)): + key = '.'.join(splits[:key_len + 1]) + if key not in locations: + if key in package_dir: + locations[key] = package_dir[key] + elif parent_location is not None: + locations[key] = parent_location + else: + locations[key] = allprefix + parent_location = locations[key] + return locations + + +def generate_cmake_file(package_name, version, scripts, package_dir, pkgs, modules): + """ + Generates lines to add to a cmake file which will set variables + + :param version: str, format 'int.int.int' + :param scripts: [list of str]: relative paths to scripts + :param package_dir: {modulename: path} + :pkgs: [list of str] python_packages declared in catkin package + :modules: [list of str] python modules + """ + prefix = '%s_SETUP_PY' % package_name + result = [] + result.append(r'set(%s_VERSION "%s")' % (prefix, version)) + result.append(r'set(%s_SCRIPTS "%s")' % (prefix, ';'.join(scripts))) + + # Remove packages with '.' separators. + # + # setuptools allows specifying submodules in other folders than + # their parent + # + # The symlink approach of catkin does not work with such submodules. + # In the common case, this does not matter as the submodule is + # within the containing module. We verify this assumption, and if + # it passes, we remove submodule packages. + locations = _get_locations(pkgs, package_dir) + for pkgname, location in locations.items(): + if not '.' in pkgname: + continue + splits = pkgname.split('.') + # hack: ignore write-combining setup.py files for msg and srv files + if splits[1] in ['msg', 'srv']: + continue + # check every child has the same root folder as its parent + parent_name = '.'.join(splits[:1]) + if location != locations[parent_name]: + raise RuntimeError( + "catkin_export_python does not support setup.py files that combine across multiple directories: %s in %s, %s in %s" % (pkgname, location, parent_name, locations[parent_name])) + + # If checks pass, remove all submodules + pkgs = [p for p in pkgs if '.' not in p] + + resolved_pkgs = [] + for pkg in pkgs: + resolved_pkgs += [os.path.join(locations[pkg], pkg)] + + result.append(r'set(%s_PACKAGES "%s")' % (prefix, ';'.join(pkgs))) + result.append(r'set(%s_PACKAGE_DIRS "%s")' % (prefix, ';'.join(resolved_pkgs).replace("\\", "/"))) + + # skip modules which collide with package names + filtered_modules = [] + for modname in modules: + splits = modname.split('.') + # check all parents too + equals_package = [('.'.join(splits[:-i]) in locations) for i in range(len(splits))] + if any(equals_package): + continue + filtered_modules.append(modname) + module_locations = _get_locations(filtered_modules, package_dir) + + result.append(r'set(%s_MODULES "%s")' % (prefix, ';'.join(['%s.py' % m.replace('.', '/') for m in filtered_modules]))) + result.append(r'set(%s_MODULE_DIRS "%s")' % (prefix, ';'.join([module_locations[m] for m in filtered_modules]).replace("\\", "/"))) + + return result + + +def _create_mock_setup_function(package_name, outfile): + """ + Creates a function to call instead of distutils.core.setup or + setuptools.setup, which just captures some args and writes them + into a file that can be used from cmake + + :param package_name: name of the package + :param outfile: filename that cmake will use afterwards + :returns: a function to replace disutils.core.setup and setuptools.setup + """ + + def setup(*args, **kwargs): + ''' + Checks kwargs and writes a scriptfile + ''' + if 'version' not in kwargs: + sys.stderr.write("\n*** Unable to find 'version' in setup.py of %s\n" % package_name) + raise RuntimeError("version not found in setup.py") + version = kwargs['version'] + package_dir = kwargs.get('package_dir', {}) + + pkgs = kwargs.get('packages', []) + scripts = kwargs.get('scripts', []) + modules = kwargs.get('py_modules', []) + + unsupported_args = [ + 'entry_points', + 'exclude_package_data', + 'ext_modules ', + 'ext_package', + 'include_package_data', + 'namespace_packages', + 'setup_requires', + 'use_2to3', + 'zip_safe'] + used_unsupported_args = [arg for arg in unsupported_args if arg in kwargs] + if used_unsupported_args: + sys.stderr.write("*** Arguments %s to setup() not supported in catkin devel space in setup.py of %s\n" % (used_unsupported_args, package_name)) + + result = generate_cmake_file(package_name=package_name, + version=version, + scripts=scripts, + package_dir=package_dir, + pkgs=pkgs, + modules=modules) + with open(outfile, 'w') as out: + out.write('\n'.join(result)) + + return setup + + +def main(): + """ + Script main, parses arguments and invokes Dummy.setup indirectly. + """ + parser = ArgumentParser(description='Utility to read setup.py values from cmake macros. Creates a file with CMake set commands setting variables.') + parser.add_argument('package_name', help='Name of catkin package') + parser.add_argument('setupfile_path', help='Full path to setup.py') + parser.add_argument('outfile', help='Where to write result to') + + args = parser.parse_args() + + # print("%s" % sys.argv) + # PACKAGE_NAME = sys.argv[1] + # OUTFILE = sys.argv[3] + # print("Interrogating setup.py for package %s into %s " % (PACKAGE_NAME, OUTFILE), + # file=sys.stderr) + + # print("executing %s" % args.setupfile_path) + + # be sure you're in the directory containing + # setup.py so the sys.path manipulation works, + # so the import of __version__ works + os.chdir(os.path.dirname(os.path.abspath(args.setupfile_path))) + + # patch setup() function of distutils and setuptools for the + # context of evaluating setup.py + try: + fake_setup = _create_mock_setup_function(package_name=args.package_name, + outfile=args.outfile) + + distutils_backup = distutils.core.setup + distutils.core.setup = fake_setup + try: + setuptools_backup = setuptools.setup + setuptools.setup = fake_setup + except NameError: + pass + + with open(args.setupfile_path, 'r') as fh: + exec(fh.read()) + finally: + distutils.core.setup = distutils_backup + try: + setuptools.setup = setuptools_backup + except NameError: + pass + +if __name__ == '__main__': + main() diff --git a/Legacy/ws_linux/build/catkin_generated/stamps/Project/order_packages.cmake.em.stamp b/Legacy/ws_linux/build/catkin_generated/stamps/Project/order_packages.cmake.em.stamp new file mode 100644 index 0000000..087d4d8 --- /dev/null +++ b/Legacy/ws_linux/build/catkin_generated/stamps/Project/order_packages.cmake.em.stamp @@ -0,0 +1,56 @@ +# generated from catkin/cmake/em/order_packages.cmake.em +@{ +import os +try: + from catkin_pkg.cmake import get_metapackage_cmake_template_path +except ImportError as e: + raise RuntimeError('ImportError: "from catkin_pkg.cmake import get_metapackage_cmake_template_path" failed: %s\nMake sure that you have installed "catkin_pkg", it is up to date and on the PYTHONPATH.' % e) +try: + from catkin_pkg.topological_order import topological_order +except ImportError as e: + raise RuntimeError('ImportError: "from catkin_pkg.topological_order import topological_order" failed: %s\nMake sure that you have installed "catkin_pkg", it is up to date and on the PYTHONPATH.' % e) +try: + from catkin_pkg.package import InvalidPackage +except ImportError as e: + raise RuntimeError('ImportError: "from catkin_pkg.package import InvalidPackage" failed: %s\nMake sure that you have installed "catkin_pkg", it is up to date and on the PYTHONPATH.' % e) +# vars defined in order_packages.context.py.in +try: + ordered_packages = topological_order(os.path.normpath(source_root_dir), whitelisted=whitelisted_packages, blacklisted=blacklisted_packages, underlay_workspaces=underlay_workspaces) +except InvalidPackage as e: + print('message(FATAL_ERROR "%s")' % ('%s' % e).replace('"', '\\"')) + ordered_packages = [] +fatal_error = False +}@ + +set(CATKIN_ORDERED_PACKAGES "") +set(CATKIN_ORDERED_PACKAGE_PATHS "") +set(CATKIN_ORDERED_PACKAGES_IS_META "") +set(CATKIN_ORDERED_PACKAGES_BUILD_TYPE "") +@[for path, package in ordered_packages]@ +@[if path is None]@ +message(FATAL_ERROR "Circular dependency in subset of packages:\n@package") +@{ +fatal_error = True +}@ +@[elif package.name != 'catkin']@ +list(APPEND CATKIN_ORDERED_PACKAGES "@(package.name)") +list(APPEND CATKIN_ORDERED_PACKAGE_PATHS "@(path.replace('\\','/'))") +list(APPEND CATKIN_ORDERED_PACKAGES_IS_META "@(str('metapackage' in [e.tagname for e in package.exports]))") +list(APPEND CATKIN_ORDERED_PACKAGES_BUILD_TYPE "@(str([e.content for e in package.exports if e.tagname == 'build_type'][0]) if 'build_type' in [e.tagname for e in package.exports] else 'catkin')") +@{ +deprecated = [e for e in package.exports if e.tagname == 'deprecated'] +}@ +@[if deprecated]@ +message("WARNING: Package '@(package.name)' is deprecated@(' (%s)' % deprecated[0].content if deprecated[0].content else '')") +@[end if]@ +@[end if]@ +@[end for]@ + +@[if not fatal_error]@ +@{ +message_generators = [package.name for (_, package) in ordered_packages if 'message_generator' in [e.tagname for e in package.exports]] +}@ +set(CATKIN_MESSAGE_GENERATORS @(' '.join(message_generators))) +@[end if]@ + +set(CATKIN_METAPACKAGE_CMAKE_TEMPLATE "@(get_metapackage_cmake_template_path().replace('\\','/'))") diff --git a/Legacy/ws_linux/build/catkin_generated/stamps/Project/package.xml.stamp b/Legacy/ws_linux/build/catkin_generated/stamps/Project/package.xml.stamp new file mode 100644 index 0000000..e8ce7d4 --- /dev/null +++ b/Legacy/ws_linux/build/catkin_generated/stamps/Project/package.xml.stamp @@ -0,0 +1,36 @@ + + + catkin + 0.5.89 + Low-level build system macros and infrastructure for ROS. + Dirk Thomas + BSD + + http://www.ros.org/wiki/catkin + https://github.com/ros/catkin/issues + https://github.com/ros/catkin + + Troy Straszheim + Morten Kjaergaard + Brian Gerkey + Dirk Thomas + + gtest + python-argparse + python-catkin-pkg + python-empy + python-nose + + cmake + + cmake + gtest + python-argparse + python-catkin-pkg + python-empy + python-nose + + + + + diff --git a/Legacy/ws_linux/build/catkin_make.cache b/Legacy/ws_linux/build/catkin_make.cache new file mode 100644 index 0000000..aac7dd7 --- /dev/null +++ b/Legacy/ws_linux/build/catkin_make.cache @@ -0,0 +1 @@ +rosaria:rosaria_msgs:safety:videostream diff --git a/Legacy/ws_linux/build/cmake_install.cmake b/Legacy/ws_linux/build/cmake_install.cmake new file mode 100644 index 0000000..1e91845 --- /dev/null +++ b/Legacy/ws_linux/build/cmake_install.cmake @@ -0,0 +1,108 @@ +# Install script for directory: /home/lab1_5/ws/ws_linux/src + +# Set the install prefix +IF(NOT DEFINED CMAKE_INSTALL_PREFIX) + SET(CMAKE_INSTALL_PREFIX "/home/lab1_5/ws/ws_linux/install") +ENDIF(NOT DEFINED CMAKE_INSTALL_PREFIX) +STRING(REGEX REPLACE "/$" "" CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}") + +# Set the install configuration name. +IF(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME) + IF(BUILD_TYPE) + STRING(REGEX REPLACE "^[^A-Za-z0-9_]+" "" + CMAKE_INSTALL_CONFIG_NAME "${BUILD_TYPE}") + ELSE(BUILD_TYPE) + SET(CMAKE_INSTALL_CONFIG_NAME "") + ENDIF(BUILD_TYPE) + MESSAGE(STATUS "Install configuration: \"${CMAKE_INSTALL_CONFIG_NAME}\"") +ENDIF(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME) + +# Set the component getting installed. +IF(NOT CMAKE_INSTALL_COMPONENT) + IF(COMPONENT) + MESSAGE(STATUS "Install component: \"${COMPONENT}\"") + SET(CMAKE_INSTALL_COMPONENT "${COMPONENT}") + ELSE(COMPONENT) + SET(CMAKE_INSTALL_COMPONENT) + ENDIF(COMPONENT) +ENDIF(NOT CMAKE_INSTALL_COMPONENT) + +# Install shared libraries without execute permission? +IF(NOT DEFINED CMAKE_INSTALL_SO_NO_EXE) + SET(CMAKE_INSTALL_SO_NO_EXE "1") +ENDIF(NOT DEFINED CMAKE_INSTALL_SO_NO_EXE) + +IF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + + if (NOT EXISTS "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}") + file(MAKE_DIRECTORY "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}") + endif() + if (NOT EXISTS "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/.catkin") + file(WRITE "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/.catkin" "") + endif() +ENDIF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + +IF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + list(APPEND CPACK_ABSOLUTE_DESTINATION_FILES + "/home/lab1_5/ws/ws_linux/install/_setup_util.py") +FILE(INSTALL DESTINATION "/home/lab1_5/ws/ws_linux/install" TYPE PROGRAM FILES "/home/lab1_5/ws/ws_linux/build/catkin_generated/installspace/_setup_util.py") +ENDIF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + +IF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + list(APPEND CPACK_ABSOLUTE_DESTINATION_FILES + "/home/lab1_5/ws/ws_linux/install/env.sh") +FILE(INSTALL DESTINATION "/home/lab1_5/ws/ws_linux/install" TYPE PROGRAM FILES "/home/lab1_5/ws/ws_linux/build/catkin_generated/installspace/env.sh") +ENDIF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + +IF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + list(APPEND CPACK_ABSOLUTE_DESTINATION_FILES + "/home/lab1_5/ws/ws_linux/install/setup.bash") +FILE(INSTALL DESTINATION "/home/lab1_5/ws/ws_linux/install" TYPE FILE FILES "/home/lab1_5/ws/ws_linux/build/catkin_generated/installspace/setup.bash") +ENDIF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + +IF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + list(APPEND CPACK_ABSOLUTE_DESTINATION_FILES + "/home/lab1_5/ws/ws_linux/install/setup.sh") +FILE(INSTALL DESTINATION "/home/lab1_5/ws/ws_linux/install" TYPE FILE FILES "/home/lab1_5/ws/ws_linux/build/catkin_generated/installspace/setup.sh") +ENDIF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + +IF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + list(APPEND CPACK_ABSOLUTE_DESTINATION_FILES + "/home/lab1_5/ws/ws_linux/install/setup.zsh") +FILE(INSTALL DESTINATION "/home/lab1_5/ws/ws_linux/install" TYPE FILE FILES "/home/lab1_5/ws/ws_linux/build/catkin_generated/installspace/setup.zsh") +ENDIF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + +IF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + list(APPEND CPACK_ABSOLUTE_DESTINATION_FILES + "/home/lab1_5/ws/ws_linux/install/.rosinstall") +FILE(INSTALL DESTINATION "/home/lab1_5/ws/ws_linux/install" TYPE FILE FILES "/home/lab1_5/ws/ws_linux/build/catkin_generated/installspace/.rosinstall") +ENDIF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + +IF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + FILE(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/etc/catkin/profile.d" TYPE FILE FILES "/opt/ros/hydro/share/catkin/cmake/env-hooks/05.catkin_make.bash") +ENDIF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + +IF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + FILE(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/etc/catkin/profile.d" TYPE FILE FILES "/opt/ros/hydro/share/catkin/cmake/env-hooks/05.catkin_make_isolated.bash") +ENDIF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + +IF(NOT CMAKE_INSTALL_LOCAL_ONLY) + # Include the install script for each subdirectory. + INCLUDE("/home/lab1_5/ws/ws_linux/build/gtest/cmake_install.cmake") + INCLUDE("/home/lab1_5/ws/ws_linux/build/rosaria_msgs/cmake_install.cmake") + INCLUDE("/home/lab1_5/ws/ws_linux/build/rosaria/cmake_install.cmake") + INCLUDE("/home/lab1_5/ws/ws_linux/build/safety/cmake_install.cmake") + INCLUDE("/home/lab1_5/ws/ws_linux/build/videostream/cmake_install.cmake") + +ENDIF(NOT CMAKE_INSTALL_LOCAL_ONLY) + +IF(CMAKE_INSTALL_COMPONENT) + SET(CMAKE_INSTALL_MANIFEST "install_manifest_${CMAKE_INSTALL_COMPONENT}.txt") +ELSE(CMAKE_INSTALL_COMPONENT) + SET(CMAKE_INSTALL_MANIFEST "install_manifest.txt") +ENDIF(CMAKE_INSTALL_COMPONENT) + +FILE(WRITE "/home/lab1_5/ws/ws_linux/build/${CMAKE_INSTALL_MANIFEST}" "") +FOREACH(file ${CMAKE_INSTALL_MANIFEST_FILES}) + FILE(APPEND "/home/lab1_5/ws/ws_linux/build/${CMAKE_INSTALL_MANIFEST}" "${file}\n") +ENDFOREACH(file) diff --git a/Legacy/ws_linux/build/gtest/CMakeFiles/CMakeDirectoryInformation.cmake b/Legacy/ws_linux/build/gtest/CMakeFiles/CMakeDirectoryInformation.cmake new file mode 100644 index 0000000..115e889 --- /dev/null +++ b/Legacy/ws_linux/build/gtest/CMakeFiles/CMakeDirectoryInformation.cmake @@ -0,0 +1,24 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +# Relative path conversion top directories. +SET(CMAKE_RELATIVE_PATH_TOP_SOURCE "/usr/src/gtest") +SET(CMAKE_RELATIVE_PATH_TOP_BINARY "/home/lab1_5/ws/ws_linux/build") + +# Force unix paths in dependencies. +SET(CMAKE_FORCE_UNIX_PATHS 1) + +# The C and CXX include file search paths: +SET(CMAKE_C_INCLUDE_PATH + "/usr/src/gtest/include" + "/usr/src/gtest" + ) +SET(CMAKE_CXX_INCLUDE_PATH ${CMAKE_C_INCLUDE_PATH}) +SET(CMAKE_Fortran_INCLUDE_PATH ${CMAKE_C_INCLUDE_PATH}) +SET(CMAKE_ASM_INCLUDE_PATH ${CMAKE_C_INCLUDE_PATH}) + +# The C and CXX include file regular expressions for this directory. +SET(CMAKE_C_INCLUDE_REGEX_SCAN "^.*$") +SET(CMAKE_C_INCLUDE_REGEX_COMPLAIN "^$") +SET(CMAKE_CXX_INCLUDE_REGEX_SCAN ${CMAKE_C_INCLUDE_REGEX_SCAN}) +SET(CMAKE_CXX_INCLUDE_REGEX_COMPLAIN ${CMAKE_C_INCLUDE_REGEX_COMPLAIN}) diff --git a/Legacy/ws_linux/build/gtest/CMakeFiles/gtest.dir/DependInfo.cmake b/Legacy/ws_linux/build/gtest/CMakeFiles/gtest.dir/DependInfo.cmake new file mode 100644 index 0000000..39a6d5c --- /dev/null +++ b/Legacy/ws_linux/build/gtest/CMakeFiles/gtest.dir/DependInfo.cmake @@ -0,0 +1,18 @@ +# The set of languages for which implicit dependencies are needed: +SET(CMAKE_DEPENDS_LANGUAGES + "CXX" + ) +# The set of files for implicit dependencies of each language: +SET(CMAKE_DEPENDS_CHECK_CXX + "/usr/src/gtest/src/gtest-all.cc" "/home/lab1_5/ws/ws_linux/build/gtest/CMakeFiles/gtest.dir/src/gtest-all.cc.o" + ) +SET(CMAKE_CXX_COMPILER_ID "GNU") + +# Preprocessor definitions for this target. +SET(CMAKE_TARGET_DEFINITIONS + "GTEST_CREATE_SHARED_LIBRARY=1" + ) + +# Targets to which this target links. +SET(CMAKE_TARGET_LINKED_INFO_FILES + ) diff --git a/Legacy/ws_linux/build/gtest/CMakeFiles/gtest.dir/build.make b/Legacy/ws_linux/build/gtest/CMakeFiles/gtest.dir/build.make new file mode 100644 index 0000000..daf98bc --- /dev/null +++ b/Legacy/ws_linux/build/gtest/CMakeFiles/gtest.dir/build.make @@ -0,0 +1,99 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/lab1_5/ws/ws_linux/src + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/lab1_5/ws/ws_linux/build + +# Include any dependencies generated for this target. +include gtest/CMakeFiles/gtest.dir/depend.make + +# Include the progress variables for this target. +include gtest/CMakeFiles/gtest.dir/progress.make + +# Include the compile flags for this target's objects. +include gtest/CMakeFiles/gtest.dir/flags.make + +gtest/CMakeFiles/gtest.dir/src/gtest-all.cc.o: gtest/CMakeFiles/gtest.dir/flags.make +gtest/CMakeFiles/gtest.dir/src/gtest-all.cc.o: /usr/src/gtest/src/gtest-all.cc + $(CMAKE_COMMAND) -E cmake_progress_report /home/lab1_5/ws/ws_linux/build/CMakeFiles $(CMAKE_PROGRESS_1) + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Building CXX object gtest/CMakeFiles/gtest.dir/src/gtest-all.cc.o" + cd /home/lab1_5/ws/ws_linux/build/gtest && /usr/bin/c++ $(CXX_DEFINES) $(CXX_FLAGS) -Wall -Wshadow -DGTEST_HAS_PTHREAD=1 -fexceptions -Wextra -o CMakeFiles/gtest.dir/src/gtest-all.cc.o -c /usr/src/gtest/src/gtest-all.cc + +gtest/CMakeFiles/gtest.dir/src/gtest-all.cc.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing CXX source to CMakeFiles/gtest.dir/src/gtest-all.cc.i" + cd /home/lab1_5/ws/ws_linux/build/gtest && /usr/bin/c++ $(CXX_DEFINES) $(CXX_FLAGS) -Wall -Wshadow -DGTEST_HAS_PTHREAD=1 -fexceptions -Wextra -E /usr/src/gtest/src/gtest-all.cc > CMakeFiles/gtest.dir/src/gtest-all.cc.i + +gtest/CMakeFiles/gtest.dir/src/gtest-all.cc.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling CXX source to assembly CMakeFiles/gtest.dir/src/gtest-all.cc.s" + cd /home/lab1_5/ws/ws_linux/build/gtest && /usr/bin/c++ $(CXX_DEFINES) $(CXX_FLAGS) -Wall -Wshadow -DGTEST_HAS_PTHREAD=1 -fexceptions -Wextra -S /usr/src/gtest/src/gtest-all.cc -o CMakeFiles/gtest.dir/src/gtest-all.cc.s + +gtest/CMakeFiles/gtest.dir/src/gtest-all.cc.o.requires: +.PHONY : gtest/CMakeFiles/gtest.dir/src/gtest-all.cc.o.requires + +gtest/CMakeFiles/gtest.dir/src/gtest-all.cc.o.provides: gtest/CMakeFiles/gtest.dir/src/gtest-all.cc.o.requires + $(MAKE) -f gtest/CMakeFiles/gtest.dir/build.make gtest/CMakeFiles/gtest.dir/src/gtest-all.cc.o.provides.build +.PHONY : gtest/CMakeFiles/gtest.dir/src/gtest-all.cc.o.provides + +gtest/CMakeFiles/gtest.dir/src/gtest-all.cc.o.provides.build: gtest/CMakeFiles/gtest.dir/src/gtest-all.cc.o + +# Object files for target gtest +gtest_OBJECTS = \ +"CMakeFiles/gtest.dir/src/gtest-all.cc.o" + +# External object files for target gtest +gtest_EXTERNAL_OBJECTS = + +gtest/libgtest.so: gtest/CMakeFiles/gtest.dir/src/gtest-all.cc.o +gtest/libgtest.so: gtest/CMakeFiles/gtest.dir/build.make +gtest/libgtest.so: gtest/CMakeFiles/gtest.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --red --bold "Linking CXX shared library libgtest.so" + cd /home/lab1_5/ws/ws_linux/build/gtest && $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/gtest.dir/link.txt --verbose=$(VERBOSE) + +# Rule to build all files generated by this target. +gtest/CMakeFiles/gtest.dir/build: gtest/libgtest.so +.PHONY : gtest/CMakeFiles/gtest.dir/build + +gtest/CMakeFiles/gtest.dir/requires: gtest/CMakeFiles/gtest.dir/src/gtest-all.cc.o.requires +.PHONY : gtest/CMakeFiles/gtest.dir/requires + +gtest/CMakeFiles/gtest.dir/clean: + cd /home/lab1_5/ws/ws_linux/build/gtest && $(CMAKE_COMMAND) -P CMakeFiles/gtest.dir/cmake_clean.cmake +.PHONY : gtest/CMakeFiles/gtest.dir/clean + +gtest/CMakeFiles/gtest.dir/depend: + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/lab1_5/ws/ws_linux/src /usr/src/gtest /home/lab1_5/ws/ws_linux/build /home/lab1_5/ws/ws_linux/build/gtest /home/lab1_5/ws/ws_linux/build/gtest/CMakeFiles/gtest.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : gtest/CMakeFiles/gtest.dir/depend + diff --git a/Legacy/ws_linux/build/gtest/CMakeFiles/gtest.dir/cmake_clean.cmake b/Legacy/ws_linux/build/gtest/CMakeFiles/gtest.dir/cmake_clean.cmake new file mode 100644 index 0000000..015a1ee --- /dev/null +++ b/Legacy/ws_linux/build/gtest/CMakeFiles/gtest.dir/cmake_clean.cmake @@ -0,0 +1,10 @@ +FILE(REMOVE_RECURSE + "CMakeFiles/gtest.dir/src/gtest-all.cc.o" + "libgtest.pdb" + "libgtest.so" +) + +# Per-language clean rules from dependency scanning. +FOREACH(lang CXX) + INCLUDE(CMakeFiles/gtest.dir/cmake_clean_${lang}.cmake OPTIONAL) +ENDFOREACH(lang) diff --git a/Legacy/ws_linux/build/gtest/CMakeFiles/gtest.dir/depend.make b/Legacy/ws_linux/build/gtest/CMakeFiles/gtest.dir/depend.make new file mode 100644 index 0000000..37ac348 --- /dev/null +++ b/Legacy/ws_linux/build/gtest/CMakeFiles/gtest.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for gtest. +# This may be replaced when dependencies are built. diff --git a/Legacy/ws_linux/build/gtest/CMakeFiles/gtest.dir/flags.make b/Legacy/ws_linux/build/gtest/CMakeFiles/gtest.dir/flags.make new file mode 100644 index 0000000..17ff575 --- /dev/null +++ b/Legacy/ws_linux/build/gtest/CMakeFiles/gtest.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +# compile CXX with /usr/bin/c++ +CXX_FLAGS = -fPIC -I/usr/src/gtest/include -I/usr/src/gtest + +CXX_DEFINES = -Dgtest_EXPORTS -DGTEST_CREATE_SHARED_LIBRARY=1 + +# TARGET_FLAGS = -Wall -Wshadow -DGTEST_HAS_PTHREAD=1 -fexceptions -Wextra + diff --git a/Legacy/ws_linux/build/gtest/CMakeFiles/gtest.dir/link.txt b/Legacy/ws_linux/build/gtest/CMakeFiles/gtest.dir/link.txt new file mode 100644 index 0000000..d0ad740 --- /dev/null +++ b/Legacy/ws_linux/build/gtest/CMakeFiles/gtest.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fPIC -shared -Wl,-soname,libgtest.so -o libgtest.so CMakeFiles/gtest.dir/src/gtest-all.cc.o -L/home/lab1_5/ws/ws_linux/build/gtest/src -lpthread -Wl,-rpath,/home/lab1_5/ws/ws_linux/build/gtest/src diff --git a/Legacy/ws_linux/build/gtest/CMakeFiles/gtest.dir/progress.make b/Legacy/ws_linux/build/gtest/CMakeFiles/gtest.dir/progress.make new file mode 100644 index 0000000..8b1fa81 --- /dev/null +++ b/Legacy/ws_linux/build/gtest/CMakeFiles/gtest.dir/progress.make @@ -0,0 +1,2 @@ +CMAKE_PROGRESS_1 = 4 + diff --git a/Legacy/ws_linux/build/gtest/CMakeFiles/gtest_main.dir/DependInfo.cmake b/Legacy/ws_linux/build/gtest/CMakeFiles/gtest_main.dir/DependInfo.cmake new file mode 100644 index 0000000..f6a32a4 --- /dev/null +++ b/Legacy/ws_linux/build/gtest/CMakeFiles/gtest_main.dir/DependInfo.cmake @@ -0,0 +1,19 @@ +# The set of languages for which implicit dependencies are needed: +SET(CMAKE_DEPENDS_LANGUAGES + "CXX" + ) +# The set of files for implicit dependencies of each language: +SET(CMAKE_DEPENDS_CHECK_CXX + "/usr/src/gtest/src/gtest_main.cc" "/home/lab1_5/ws/ws_linux/build/gtest/CMakeFiles/gtest_main.dir/src/gtest_main.cc.o" + ) +SET(CMAKE_CXX_COMPILER_ID "GNU") + +# Preprocessor definitions for this target. +SET(CMAKE_TARGET_DEFINITIONS + "GTEST_CREATE_SHARED_LIBRARY=1" + ) + +# Targets to which this target links. +SET(CMAKE_TARGET_LINKED_INFO_FILES + "/home/lab1_5/ws/ws_linux/build/gtest/CMakeFiles/gtest.dir/DependInfo.cmake" + ) diff --git a/Legacy/ws_linux/build/gtest/CMakeFiles/gtest_main.dir/build.make b/Legacy/ws_linux/build/gtest/CMakeFiles/gtest_main.dir/build.make new file mode 100644 index 0000000..687ceb3 --- /dev/null +++ b/Legacy/ws_linux/build/gtest/CMakeFiles/gtest_main.dir/build.make @@ -0,0 +1,100 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/lab1_5/ws/ws_linux/src + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/lab1_5/ws/ws_linux/build + +# Include any dependencies generated for this target. +include gtest/CMakeFiles/gtest_main.dir/depend.make + +# Include the progress variables for this target. +include gtest/CMakeFiles/gtest_main.dir/progress.make + +# Include the compile flags for this target's objects. +include gtest/CMakeFiles/gtest_main.dir/flags.make + +gtest/CMakeFiles/gtest_main.dir/src/gtest_main.cc.o: gtest/CMakeFiles/gtest_main.dir/flags.make +gtest/CMakeFiles/gtest_main.dir/src/gtest_main.cc.o: /usr/src/gtest/src/gtest_main.cc + $(CMAKE_COMMAND) -E cmake_progress_report /home/lab1_5/ws/ws_linux/build/CMakeFiles $(CMAKE_PROGRESS_1) + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Building CXX object gtest/CMakeFiles/gtest_main.dir/src/gtest_main.cc.o" + cd /home/lab1_5/ws/ws_linux/build/gtest && /usr/bin/c++ $(CXX_DEFINES) $(CXX_FLAGS) -Wall -Wshadow -DGTEST_HAS_PTHREAD=1 -fexceptions -Wextra -o CMakeFiles/gtest_main.dir/src/gtest_main.cc.o -c /usr/src/gtest/src/gtest_main.cc + +gtest/CMakeFiles/gtest_main.dir/src/gtest_main.cc.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing CXX source to CMakeFiles/gtest_main.dir/src/gtest_main.cc.i" + cd /home/lab1_5/ws/ws_linux/build/gtest && /usr/bin/c++ $(CXX_DEFINES) $(CXX_FLAGS) -Wall -Wshadow -DGTEST_HAS_PTHREAD=1 -fexceptions -Wextra -E /usr/src/gtest/src/gtest_main.cc > CMakeFiles/gtest_main.dir/src/gtest_main.cc.i + +gtest/CMakeFiles/gtest_main.dir/src/gtest_main.cc.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling CXX source to assembly CMakeFiles/gtest_main.dir/src/gtest_main.cc.s" + cd /home/lab1_5/ws/ws_linux/build/gtest && /usr/bin/c++ $(CXX_DEFINES) $(CXX_FLAGS) -Wall -Wshadow -DGTEST_HAS_PTHREAD=1 -fexceptions -Wextra -S /usr/src/gtest/src/gtest_main.cc -o CMakeFiles/gtest_main.dir/src/gtest_main.cc.s + +gtest/CMakeFiles/gtest_main.dir/src/gtest_main.cc.o.requires: +.PHONY : gtest/CMakeFiles/gtest_main.dir/src/gtest_main.cc.o.requires + +gtest/CMakeFiles/gtest_main.dir/src/gtest_main.cc.o.provides: gtest/CMakeFiles/gtest_main.dir/src/gtest_main.cc.o.requires + $(MAKE) -f gtest/CMakeFiles/gtest_main.dir/build.make gtest/CMakeFiles/gtest_main.dir/src/gtest_main.cc.o.provides.build +.PHONY : gtest/CMakeFiles/gtest_main.dir/src/gtest_main.cc.o.provides + +gtest/CMakeFiles/gtest_main.dir/src/gtest_main.cc.o.provides.build: gtest/CMakeFiles/gtest_main.dir/src/gtest_main.cc.o + +# Object files for target gtest_main +gtest_main_OBJECTS = \ +"CMakeFiles/gtest_main.dir/src/gtest_main.cc.o" + +# External object files for target gtest_main +gtest_main_EXTERNAL_OBJECTS = + +gtest/libgtest_main.so: gtest/CMakeFiles/gtest_main.dir/src/gtest_main.cc.o +gtest/libgtest_main.so: gtest/libgtest.so +gtest/libgtest_main.so: gtest/CMakeFiles/gtest_main.dir/build.make +gtest/libgtest_main.so: gtest/CMakeFiles/gtest_main.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --red --bold "Linking CXX shared library libgtest_main.so" + cd /home/lab1_5/ws/ws_linux/build/gtest && $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/gtest_main.dir/link.txt --verbose=$(VERBOSE) + +# Rule to build all files generated by this target. +gtest/CMakeFiles/gtest_main.dir/build: gtest/libgtest_main.so +.PHONY : gtest/CMakeFiles/gtest_main.dir/build + +gtest/CMakeFiles/gtest_main.dir/requires: gtest/CMakeFiles/gtest_main.dir/src/gtest_main.cc.o.requires +.PHONY : gtest/CMakeFiles/gtest_main.dir/requires + +gtest/CMakeFiles/gtest_main.dir/clean: + cd /home/lab1_5/ws/ws_linux/build/gtest && $(CMAKE_COMMAND) -P CMakeFiles/gtest_main.dir/cmake_clean.cmake +.PHONY : gtest/CMakeFiles/gtest_main.dir/clean + +gtest/CMakeFiles/gtest_main.dir/depend: + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/lab1_5/ws/ws_linux/src /usr/src/gtest /home/lab1_5/ws/ws_linux/build /home/lab1_5/ws/ws_linux/build/gtest /home/lab1_5/ws/ws_linux/build/gtest/CMakeFiles/gtest_main.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : gtest/CMakeFiles/gtest_main.dir/depend + diff --git a/Legacy/ws_linux/build/gtest/CMakeFiles/gtest_main.dir/cmake_clean.cmake b/Legacy/ws_linux/build/gtest/CMakeFiles/gtest_main.dir/cmake_clean.cmake new file mode 100644 index 0000000..c8fe838 --- /dev/null +++ b/Legacy/ws_linux/build/gtest/CMakeFiles/gtest_main.dir/cmake_clean.cmake @@ -0,0 +1,10 @@ +FILE(REMOVE_RECURSE + "CMakeFiles/gtest_main.dir/src/gtest_main.cc.o" + "libgtest_main.pdb" + "libgtest_main.so" +) + +# Per-language clean rules from dependency scanning. +FOREACH(lang CXX) + INCLUDE(CMakeFiles/gtest_main.dir/cmake_clean_${lang}.cmake OPTIONAL) +ENDFOREACH(lang) diff --git a/Legacy/ws_linux/build/gtest/CMakeFiles/gtest_main.dir/depend.make b/Legacy/ws_linux/build/gtest/CMakeFiles/gtest_main.dir/depend.make new file mode 100644 index 0000000..1d67c1a --- /dev/null +++ b/Legacy/ws_linux/build/gtest/CMakeFiles/gtest_main.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for gtest_main. +# This may be replaced when dependencies are built. diff --git a/Legacy/ws_linux/build/gtest/CMakeFiles/gtest_main.dir/flags.make b/Legacy/ws_linux/build/gtest/CMakeFiles/gtest_main.dir/flags.make new file mode 100644 index 0000000..1363759 --- /dev/null +++ b/Legacy/ws_linux/build/gtest/CMakeFiles/gtest_main.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +# compile CXX with /usr/bin/c++ +CXX_FLAGS = -fPIC -I/usr/src/gtest/include -I/usr/src/gtest + +CXX_DEFINES = -Dgtest_main_EXPORTS -DGTEST_CREATE_SHARED_LIBRARY=1 + +# TARGET_FLAGS = -Wall -Wshadow -DGTEST_HAS_PTHREAD=1 -fexceptions -Wextra + diff --git a/Legacy/ws_linux/build/gtest/CMakeFiles/gtest_main.dir/link.txt b/Legacy/ws_linux/build/gtest/CMakeFiles/gtest_main.dir/link.txt new file mode 100644 index 0000000..b0bb4bc --- /dev/null +++ b/Legacy/ws_linux/build/gtest/CMakeFiles/gtest_main.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fPIC -shared -Wl,-soname,libgtest_main.so -o libgtest_main.so CMakeFiles/gtest_main.dir/src/gtest_main.cc.o -L/home/lab1_5/ws/ws_linux/build/gtest/src -lpthread libgtest.so -lpthread -Wl,-rpath,/home/lab1_5/ws/ws_linux/build/gtest/src:/home/lab1_5/ws/ws_linux/build/gtest diff --git a/Legacy/ws_linux/build/gtest/CMakeFiles/gtest_main.dir/progress.make b/Legacy/ws_linux/build/gtest/CMakeFiles/gtest_main.dir/progress.make new file mode 100644 index 0000000..b9ea7bd --- /dev/null +++ b/Legacy/ws_linux/build/gtest/CMakeFiles/gtest_main.dir/progress.make @@ -0,0 +1,2 @@ +CMAKE_PROGRESS_1 = 5 + diff --git a/Legacy/ws_linux/build/gtest/CMakeFiles/progress.marks b/Legacy/ws_linux/build/gtest/CMakeFiles/progress.marks new file mode 100644 index 0000000..573541a --- /dev/null +++ b/Legacy/ws_linux/build/gtest/CMakeFiles/progress.marks @@ -0,0 +1 @@ +0 diff --git a/Legacy/ws_linux/build/gtest/CTestTestfile.cmake b/Legacy/ws_linux/build/gtest/CTestTestfile.cmake new file mode 100644 index 0000000..8ac66d4 --- /dev/null +++ b/Legacy/ws_linux/build/gtest/CTestTestfile.cmake @@ -0,0 +1,6 @@ +# CMake generated Testfile for +# Source directory: /usr/src/gtest +# Build directory: /home/lab1_5/ws/ws_linux/build/gtest +# +# This file includes the relevent testing commands required for +# testing this directory and lists subdirectories to be tested as well. diff --git a/Legacy/ws_linux/build/gtest/Makefile b/Legacy/ws_linux/build/gtest/Makefile new file mode 100644 index 0000000..50fa8ae --- /dev/null +++ b/Legacy/ws_linux/build/gtest/Makefile @@ -0,0 +1,259 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +# Default target executed when no arguments are given to make. +default_target: all +.PHONY : default_target + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/lab1_5/ws/ws_linux/src + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/lab1_5/ws/ws_linux/build + +#============================================================================= +# Targets provided globally by CMake. + +# Special rule for the target edit_cache +edit_cache: + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running interactive CMake command-line interface..." + /usr/bin/cmake -i . +.PHONY : edit_cache + +# Special rule for the target edit_cache +edit_cache/fast: edit_cache +.PHONY : edit_cache/fast + +# Special rule for the target install +install: preinstall + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Install the project..." + /usr/bin/cmake -P cmake_install.cmake +.PHONY : install + +# Special rule for the target install +install/fast: preinstall/fast + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Install the project..." + /usr/bin/cmake -P cmake_install.cmake +.PHONY : install/fast + +# Special rule for the target install/local +install/local: preinstall + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Installing only the local directory..." + /usr/bin/cmake -DCMAKE_INSTALL_LOCAL_ONLY=1 -P cmake_install.cmake +.PHONY : install/local + +# Special rule for the target install/local +install/local/fast: install/local +.PHONY : install/local/fast + +# Special rule for the target install/strip +install/strip: preinstall + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Installing the project stripped..." + /usr/bin/cmake -DCMAKE_INSTALL_DO_STRIP=1 -P cmake_install.cmake +.PHONY : install/strip + +# Special rule for the target install/strip +install/strip/fast: install/strip +.PHONY : install/strip/fast + +# Special rule for the target list_install_components +list_install_components: + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Available install components are: \"Unspecified\"" +.PHONY : list_install_components + +# Special rule for the target list_install_components +list_install_components/fast: list_install_components +.PHONY : list_install_components/fast + +# Special rule for the target rebuild_cache +rebuild_cache: + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running CMake to regenerate build system..." + /usr/bin/cmake -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) +.PHONY : rebuild_cache + +# Special rule for the target rebuild_cache +rebuild_cache/fast: rebuild_cache +.PHONY : rebuild_cache/fast + +# Special rule for the target test +test: + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running tests..." + /usr/bin/ctest --force-new-ctest-process $(ARGS) +.PHONY : test + +# Special rule for the target test +test/fast: test +.PHONY : test/fast + +# The main all target +all: cmake_check_build_system + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -E cmake_progress_start /home/lab1_5/ws/ws_linux/build/CMakeFiles /home/lab1_5/ws/ws_linux/build/gtest/CMakeFiles/progress.marks + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 gtest/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/lab1_5/ws/ws_linux/build/CMakeFiles 0 +.PHONY : all + +# The main clean target +clean: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 gtest/clean +.PHONY : clean + +# The main clean target +clean/fast: clean +.PHONY : clean/fast + +# Prepare targets for installation. +preinstall: all + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 gtest/preinstall +.PHONY : preinstall + +# Prepare targets for installation. +preinstall/fast: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 gtest/preinstall +.PHONY : preinstall/fast + +# clear depends +depend: + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 1 +.PHONY : depend + +# Convenience name for target. +gtest/CMakeFiles/gtest.dir/rule: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 gtest/CMakeFiles/gtest.dir/rule +.PHONY : gtest/CMakeFiles/gtest.dir/rule + +# Convenience name for target. +gtest: gtest/CMakeFiles/gtest.dir/rule +.PHONY : gtest + +# fast build rule for target. +gtest/fast: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f gtest/CMakeFiles/gtest.dir/build.make gtest/CMakeFiles/gtest.dir/build +.PHONY : gtest/fast + +# Convenience name for target. +gtest/CMakeFiles/gtest_main.dir/rule: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 gtest/CMakeFiles/gtest_main.dir/rule +.PHONY : gtest/CMakeFiles/gtest_main.dir/rule + +# Convenience name for target. +gtest_main: gtest/CMakeFiles/gtest_main.dir/rule +.PHONY : gtest_main + +# fast build rule for target. +gtest_main/fast: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f gtest/CMakeFiles/gtest_main.dir/build.make gtest/CMakeFiles/gtest_main.dir/build +.PHONY : gtest_main/fast + +src/gtest-all.o: src/gtest-all.cc.o +.PHONY : src/gtest-all.o + +# target to build an object file +src/gtest-all.cc.o: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f gtest/CMakeFiles/gtest.dir/build.make gtest/CMakeFiles/gtest.dir/src/gtest-all.cc.o +.PHONY : src/gtest-all.cc.o + +src/gtest-all.i: src/gtest-all.cc.i +.PHONY : src/gtest-all.i + +# target to preprocess a source file +src/gtest-all.cc.i: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f gtest/CMakeFiles/gtest.dir/build.make gtest/CMakeFiles/gtest.dir/src/gtest-all.cc.i +.PHONY : src/gtest-all.cc.i + +src/gtest-all.s: src/gtest-all.cc.s +.PHONY : src/gtest-all.s + +# target to generate assembly for a file +src/gtest-all.cc.s: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f gtest/CMakeFiles/gtest.dir/build.make gtest/CMakeFiles/gtest.dir/src/gtest-all.cc.s +.PHONY : src/gtest-all.cc.s + +src/gtest_main.o: src/gtest_main.cc.o +.PHONY : src/gtest_main.o + +# target to build an object file +src/gtest_main.cc.o: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f gtest/CMakeFiles/gtest_main.dir/build.make gtest/CMakeFiles/gtest_main.dir/src/gtest_main.cc.o +.PHONY : src/gtest_main.cc.o + +src/gtest_main.i: src/gtest_main.cc.i +.PHONY : src/gtest_main.i + +# target to preprocess a source file +src/gtest_main.cc.i: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f gtest/CMakeFiles/gtest_main.dir/build.make gtest/CMakeFiles/gtest_main.dir/src/gtest_main.cc.i +.PHONY : src/gtest_main.cc.i + +src/gtest_main.s: src/gtest_main.cc.s +.PHONY : src/gtest_main.s + +# target to generate assembly for a file +src/gtest_main.cc.s: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f gtest/CMakeFiles/gtest_main.dir/build.make gtest/CMakeFiles/gtest_main.dir/src/gtest_main.cc.s +.PHONY : src/gtest_main.cc.s + +# Help Target +help: + @echo "The following are some of the valid targets for this Makefile:" + @echo "... all (the default if no target is provided)" + @echo "... clean" + @echo "... depend" + @echo "... edit_cache" + @echo "... gtest" + @echo "... gtest_main" + @echo "... install" + @echo "... install/local" + @echo "... install/strip" + @echo "... list_install_components" + @echo "... rebuild_cache" + @echo "... test" + @echo "... src/gtest-all.o" + @echo "... src/gtest-all.i" + @echo "... src/gtest-all.s" + @echo "... src/gtest_main.o" + @echo "... src/gtest_main.i" + @echo "... src/gtest_main.s" +.PHONY : help + + + +#============================================================================= +# Special targets to cleanup operation of make. + +# Special rule to run CMake to check the build system integrity. +# No rule that depends on this can have commands that come from listfiles +# because they might be regenerated. +cmake_check_build_system: + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 0 +.PHONY : cmake_check_build_system + diff --git a/Legacy/ws_linux/build/gtest/cmake_install.cmake b/Legacy/ws_linux/build/gtest/cmake_install.cmake new file mode 100644 index 0000000..98fb9dc --- /dev/null +++ b/Legacy/ws_linux/build/gtest/cmake_install.cmake @@ -0,0 +1,34 @@ +# Install script for directory: /usr/src/gtest + +# Set the install prefix +IF(NOT DEFINED CMAKE_INSTALL_PREFIX) + SET(CMAKE_INSTALL_PREFIX "/home/lab1_5/ws/ws_linux/install") +ENDIF(NOT DEFINED CMAKE_INSTALL_PREFIX) +STRING(REGEX REPLACE "/$" "" CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}") + +# Set the install configuration name. +IF(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME) + IF(BUILD_TYPE) + STRING(REGEX REPLACE "^[^A-Za-z0-9_]+" "" + CMAKE_INSTALL_CONFIG_NAME "${BUILD_TYPE}") + ELSE(BUILD_TYPE) + SET(CMAKE_INSTALL_CONFIG_NAME "") + ENDIF(BUILD_TYPE) + MESSAGE(STATUS "Install configuration: \"${CMAKE_INSTALL_CONFIG_NAME}\"") +ENDIF(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME) + +# Set the component getting installed. +IF(NOT CMAKE_INSTALL_COMPONENT) + IF(COMPONENT) + MESSAGE(STATUS "Install component: \"${COMPONENT}\"") + SET(CMAKE_INSTALL_COMPONENT "${COMPONENT}") + ELSE(COMPONENT) + SET(CMAKE_INSTALL_COMPONENT) + ENDIF(COMPONENT) +ENDIF(NOT CMAKE_INSTALL_COMPONENT) + +# Install shared libraries without execute permission? +IF(NOT DEFINED CMAKE_INSTALL_SO_NO_EXE) + SET(CMAKE_INSTALL_SO_NO_EXE "1") +ENDIF(NOT DEFINED CMAKE_INSTALL_SO_NO_EXE) + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/CMakeDirectoryInformation.cmake b/Legacy/ws_linux/build/rosaria/CMakeFiles/CMakeDirectoryInformation.cmake new file mode 100644 index 0000000..9d5fbab --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/CMakeDirectoryInformation.cmake @@ -0,0 +1,25 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +# Relative path conversion top directories. +SET(CMAKE_RELATIVE_PATH_TOP_SOURCE "/home/lab1_5/ws/ws_linux/src") +SET(CMAKE_RELATIVE_PATH_TOP_BINARY "/home/lab1_5/ws/ws_linux/build") + +# Force unix paths in dependencies. +SET(CMAKE_FORCE_UNIX_PATHS 1) + +# The C and CXX include file search paths: +SET(CMAKE_C_INCLUDE_PATH + "/home/lab1_5/ws/ws_linux/devel/include" + "/opt/ros/hydro/include" + "/usr/local/Aria/include" + ) +SET(CMAKE_CXX_INCLUDE_PATH ${CMAKE_C_INCLUDE_PATH}) +SET(CMAKE_Fortran_INCLUDE_PATH ${CMAKE_C_INCLUDE_PATH}) +SET(CMAKE_ASM_INCLUDE_PATH ${CMAKE_C_INCLUDE_PATH}) + +# The C and CXX include file regular expressions for this directory. +SET(CMAKE_C_INCLUDE_REGEX_SCAN "^.*$") +SET(CMAKE_C_INCLUDE_REGEX_COMPLAIN "^$") +SET(CMAKE_CXX_INCLUDE_REGEX_SCAN ${CMAKE_C_INCLUDE_REGEX_SCAN}) +SET(CMAKE_CXX_INCLUDE_REGEX_COMPLAIN ${CMAKE_C_INCLUDE_REGEX_COMPLAIN}) diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/RosAria.dir/CXX.includecache b/Legacy/ws_linux/build/rosaria/CMakeFiles/RosAria.dir/CXX.includecache new file mode 100644 index 0000000..294e901 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/RosAria.dir/CXX.includecache @@ -0,0 +1,3750 @@ +#IncludeRegexLine: ^[ ]*#[ ]*(include|import)[ ]*[<"]([^">]+)([">]) + +#IncludeRegexScan: ^.*$ + +#IncludeRegexComplain: ^$ + +#IncludeRegexTransform: + +/home/lab1_5/ws/ws_linux/devel/include/rosaria/BumperState.h +string +- +vector +- +map +- +ros/types.h +- +ros/serialization.h +- +ros/builtin_message_traits.h +- +ros/message_operations.h +- +std_msgs/Header.h +- + +/home/lab1_5/ws/ws_linux/devel/include/rosaria/RosAriaConfig.h +dynamic_reconfigure/config_tools.h +- +limits +- +ros/node_handle.h +- +dynamic_reconfigure/ConfigDescription.h +- +dynamic_reconfigure/ParamDescription.h +- +dynamic_reconfigure/Group.h +- +dynamic_reconfigure/config_init_mutex.h +- +boost/any.hpp +- + +/home/lab1_5/ws/ws_linux/devel/include/rosaria_msgs/RestrictionsMsg.h + +/home/lab1_5/ws/ws_linux/devel/include/rosaria_msgs/RobotInfoMsg.h +string +- +vector +- +map +- +ros/types.h +- +ros/serialization.h +- +ros/builtin_message_traits.h +- +ros/message_operations.h +- +std_msgs/UInt8.h +- +std_msgs/Float64.h +- +geometry_msgs/Twist.h +- +std_msgs/Bool.h +- +std_msgs/Bool.h +- +std_msgs/Bool.h +- + +/home/lab1_5/ws/ws_linux/src/rosaria/RosAria.cpp +stdio.h +- +math.h +- +Aria.h +- +/usr/include/Aria/Aria.h +- +ros/ros.h +/home/lab1_5/ws/ws_linux/src/rosaria/ros/ros.h +geometry_msgs/Twist.h +/home/lab1_5/ws/ws_linux/src/rosaria/geometry_msgs/Twist.h +geometry_msgs/Pose.h +/home/lab1_5/ws/ws_linux/src/rosaria/geometry_msgs/Pose.h +geometry_msgs/PoseStamped.h +/home/lab1_5/ws/ws_linux/src/rosaria/geometry_msgs/PoseStamped.h +sensor_msgs/PointCloud.h +- +sensor_msgs/PointCloud2.h +- +sensor_msgs/point_cloud_conversion.h +- +nav_msgs/Odometry.h +/home/lab1_5/ws/ws_linux/src/rosaria/nav_msgs/Odometry.h +rosaria/BumperState.h +/home/lab1_5/ws/ws_linux/src/rosaria/rosaria/BumperState.h +tf/tf.h +/home/lab1_5/ws/ws_linux/src/rosaria/tf/tf.h +tf/transform_listener.h +/home/lab1_5/ws/ws_linux/src/rosaria/tf/transform_listener.h +tf/transform_broadcaster.h +- +tf/transform_datatypes.h +/home/lab1_5/ws/ws_linux/src/rosaria/tf/transform_datatypes.h +dynamic_reconfigure/server.h +- +rosaria/RosAriaConfig.h +- +std_msgs/Float64.h +/home/lab1_5/ws/ws_linux/src/rosaria/std_msgs/Float64.h +std_msgs/Float32.h +/home/lab1_5/ws/ws_linux/src/rosaria/std_msgs/Float32.h +std_msgs/Int8.h +/home/lab1_5/ws/ws_linux/src/rosaria/std_msgs/Int8.h +std_msgs/Bool.h +/home/lab1_5/ws/ws_linux/src/rosaria/std_msgs/Bool.h +std_srvs/Empty.h +/home/lab1_5/ws/ws_linux/src/rosaria/std_srvs/Empty.h +sensor_msgs/JointState.h +/home/lab1_5/ws/ws_linux/src/rosaria/sensor_msgs/JointState.h +rosaria_msgs/RestrictionsMsg.h +/home/lab1_5/ws/ws_linux/src/rosaria/rosaria_msgs/RestrictionsMsg.h +rosaria_msgs/RobotInfoMsg.h +/home/lab1_5/ws/ws_linux/src/rosaria/rosaria_msgs/RobotInfoMsg.h +sstream +- +cstdlib +- + +/opt/ros/hydro/include/XmlRpcDecl.h +ros/macros.h +- + +/opt/ros/hydro/include/XmlRpcValue.h +XmlRpcDecl.h +/opt/ros/hydro/include/XmlRpcDecl.h +map +- +string +- +vector +- +time.h +- + +/opt/ros/hydro/include/dynamic_reconfigure/BoolParameter.h +string +- +vector +- +map +- +ros/types.h +- +ros/serialization.h +- +ros/builtin_message_traits.h +- +ros/message_operations.h +- + +/opt/ros/hydro/include/dynamic_reconfigure/Config.h +string +- +vector +- +map +- +ros/types.h +- +ros/serialization.h +- +ros/builtin_message_traits.h +- +ros/message_operations.h +- +dynamic_reconfigure/BoolParameter.h +- +dynamic_reconfigure/IntParameter.h +- +dynamic_reconfigure/StrParameter.h +- +dynamic_reconfigure/DoubleParameter.h +- +dynamic_reconfigure/GroupState.h +- + +/opt/ros/hydro/include/dynamic_reconfigure/ConfigDescription.h +string +- +vector +- +map +- +ros/types.h +- +ros/serialization.h +- +ros/builtin_message_traits.h +- +ros/message_operations.h +- +dynamic_reconfigure/Group.h +- +dynamic_reconfigure/Config.h +- +dynamic_reconfigure/Config.h +- +dynamic_reconfigure/Config.h +- + +/opt/ros/hydro/include/dynamic_reconfigure/DoubleParameter.h +string +- +vector +- +map +- +ros/types.h +- +ros/serialization.h +- +ros/builtin_message_traits.h +- +ros/message_operations.h +- + +/opt/ros/hydro/include/dynamic_reconfigure/Group.h +string +- +vector +- +map +- +ros/types.h +- +ros/serialization.h +- +ros/builtin_message_traits.h +- +ros/message_operations.h +- +dynamic_reconfigure/ParamDescription.h +- + +/opt/ros/hydro/include/dynamic_reconfigure/GroupState.h +string +- +vector +- +map +- +ros/types.h +- +ros/serialization.h +- +ros/builtin_message_traits.h +- +ros/message_operations.h +- + +/opt/ros/hydro/include/dynamic_reconfigure/IntParameter.h +string +- +vector +- +map +- +ros/types.h +- +ros/serialization.h +- +ros/builtin_message_traits.h +- +ros/message_operations.h +- + +/opt/ros/hydro/include/dynamic_reconfigure/ParamDescription.h +string +- +vector +- +map +- +ros/types.h +- +ros/serialization.h +- +ros/builtin_message_traits.h +- +ros/message_operations.h +- + +/opt/ros/hydro/include/dynamic_reconfigure/Reconfigure.h +ros/service_traits.h +- +dynamic_reconfigure/ReconfigureRequest.h +- +dynamic_reconfigure/ReconfigureResponse.h +- + +/opt/ros/hydro/include/dynamic_reconfigure/ReconfigureRequest.h +string +- +vector +- +map +- +ros/types.h +- +ros/serialization.h +- +ros/builtin_message_traits.h +- +ros/message_operations.h +- +dynamic_reconfigure/Config.h +- + +/opt/ros/hydro/include/dynamic_reconfigure/ReconfigureResponse.h +string +- +vector +- +map +- +ros/types.h +- +ros/serialization.h +- +ros/builtin_message_traits.h +- +ros/message_operations.h +- +dynamic_reconfigure/Config.h +- + +/opt/ros/hydro/include/dynamic_reconfigure/StrParameter.h +string +- +vector +- +map +- +ros/types.h +- +ros/serialization.h +- +ros/builtin_message_traits.h +- +ros/message_operations.h +- + +/opt/ros/hydro/include/dynamic_reconfigure/config_init_mutex.h +boost/thread/mutex.hpp +- + +/opt/ros/hydro/include/dynamic_reconfigure/config_tools.h +string +- +vector +- +dynamic_reconfigure/Config.h +- +dynamic_reconfigure/Group.h +- + +/opt/ros/hydro/include/dynamic_reconfigure/server.h +boost/function.hpp +- +boost/thread/recursive_mutex.hpp +- +ros/node_handle.h +- +dynamic_reconfigure/ConfigDescription.h +- +dynamic_reconfigure/Reconfigure.h +- + +/opt/ros/hydro/include/geometry_msgs/Point.h +string +- +vector +- +map +- +ros/types.h +- +ros/serialization.h +- +ros/builtin_message_traits.h +- +ros/message_operations.h +- + +/opt/ros/hydro/include/geometry_msgs/Point32.h +string +- +vector +- +map +- +ros/types.h +- +ros/serialization.h +- +ros/builtin_message_traits.h +- +ros/message_operations.h +- + +/opt/ros/hydro/include/geometry_msgs/PointStamped.h +string +- +vector +- +map +- +ros/types.h +- +ros/serialization.h +- +ros/builtin_message_traits.h +- +ros/message_operations.h +- +std_msgs/Header.h +- +geometry_msgs/Point.h +- + +/opt/ros/hydro/include/geometry_msgs/Pose.h +string +- +vector +- +map +- +ros/types.h +- +ros/serialization.h +- +ros/builtin_message_traits.h +- +ros/message_operations.h +- +geometry_msgs/Point.h +- +geometry_msgs/Quaternion.h +- + +/opt/ros/hydro/include/geometry_msgs/PoseStamped.h +string +- +vector +- +map +- +ros/types.h +- +ros/serialization.h +- +ros/builtin_message_traits.h +- +ros/message_operations.h +- +std_msgs/Header.h +- +geometry_msgs/Pose.h +- + +/opt/ros/hydro/include/geometry_msgs/PoseWithCovariance.h +string +- +vector +- +map +- +ros/types.h +- +ros/serialization.h +- +ros/builtin_message_traits.h +- +ros/message_operations.h +- +geometry_msgs/Pose.h +- + +/opt/ros/hydro/include/geometry_msgs/Quaternion.h +string +- +vector +- +map +- +ros/types.h +- +ros/serialization.h +- +ros/builtin_message_traits.h +- +ros/message_operations.h +- + +/opt/ros/hydro/include/geometry_msgs/QuaternionStamped.h +string +- +vector +- +map +- +ros/types.h +- +ros/serialization.h +- +ros/builtin_message_traits.h +- +ros/message_operations.h +- +std_msgs/Header.h +- +geometry_msgs/Quaternion.h +- + +/opt/ros/hydro/include/geometry_msgs/Transform.h +string +- +vector +- +map +- +ros/types.h +- +ros/serialization.h +- +ros/builtin_message_traits.h +- +ros/message_operations.h +- +geometry_msgs/Vector3.h +- +geometry_msgs/Quaternion.h +- + +/opt/ros/hydro/include/geometry_msgs/TransformStamped.h +string +- +vector +- +map +- +ros/types.h +- +ros/serialization.h +- +ros/builtin_message_traits.h +- +ros/message_operations.h +- +std_msgs/Header.h +- +geometry_msgs/Transform.h +- + +/opt/ros/hydro/include/geometry_msgs/Twist.h +string +- +vector +- +map +- +ros/types.h +- +ros/serialization.h +- +ros/builtin_message_traits.h +- +ros/message_operations.h +- +geometry_msgs/Vector3.h +- +geometry_msgs/Vector3.h +- + +/opt/ros/hydro/include/geometry_msgs/TwistStamped.h +string +- +vector +- +map +- +ros/types.h +- +ros/serialization.h +- +ros/builtin_message_traits.h +- +ros/message_operations.h +- +std_msgs/Header.h +- +geometry_msgs/Twist.h +- + +/opt/ros/hydro/include/geometry_msgs/TwistWithCovariance.h +string +- +vector +- +map +- +ros/types.h +- +ros/serialization.h +- +ros/builtin_message_traits.h +- +ros/message_operations.h +- +geometry_msgs/Twist.h +- + +/opt/ros/hydro/include/geometry_msgs/Vector3.h +string +- +vector +- +map +- +ros/types.h +- +ros/serialization.h +- +ros/builtin_message_traits.h +- +ros/message_operations.h +- + +/opt/ros/hydro/include/geometry_msgs/Vector3Stamped.h +string +- +vector +- +map +- +ros/types.h +- +ros/serialization.h +- +ros/builtin_message_traits.h +- +ros/message_operations.h +- +std_msgs/Header.h +- +geometry_msgs/Vector3.h +- + +/opt/ros/hydro/include/nav_msgs/Odometry.h +string +- +vector +- +map +- +ros/types.h +- +ros/serialization.h +- +ros/builtin_message_traits.h +- +ros/message_operations.h +- +std_msgs/Header.h +- +geometry_msgs/PoseWithCovariance.h +- +geometry_msgs/TwistWithCovariance.h +- + +/opt/ros/hydro/include/ros/advertise_options.h +ros/forwards.h +/opt/ros/hydro/include/ros/ros/forwards.h +ros/message_traits.h +/opt/ros/hydro/include/ros/ros/message_traits.h +common.h +/opt/ros/hydro/include/ros/common.h + +/opt/ros/hydro/include/ros/advertise_service_options.h +ros/forwards.h +/opt/ros/hydro/include/ros/ros/forwards.h +ros/service_callback_helper.h +/opt/ros/hydro/include/ros/ros/service_callback_helper.h +ros/service_traits.h +/opt/ros/hydro/include/ros/ros/service_traits.h +ros/message_traits.h +/opt/ros/hydro/include/ros/ros/message_traits.h +common.h +/opt/ros/hydro/include/ros/common.h + +/opt/ros/hydro/include/ros/assert.h +ros/console.h +/opt/ros/hydro/include/ros/ros/console.h +ros/static_assert.h +/opt/ros/hydro/include/ros/ros/static_assert.h +ros/platform.h +- +stdlib.h +- + +/opt/ros/hydro/include/ros/builtin_message_traits.h +message_traits.h +/opt/ros/hydro/include/ros/message_traits.h +ros/time.h +/opt/ros/hydro/include/ros/ros/time.h + +/opt/ros/hydro/include/ros/callback_queue.h +ros/callback_queue_interface.h +/opt/ros/hydro/include/ros/ros/callback_queue_interface.h +ros/time.h +/opt/ros/hydro/include/ros/ros/time.h +common.h +/opt/ros/hydro/include/ros/common.h +boost/shared_ptr.hpp +- +boost/thread/mutex.hpp +- +boost/thread/shared_mutex.hpp +- +boost/thread/condition_variable.hpp +- +boost/thread/tss.hpp +- +list +- +deque +- + +/opt/ros/hydro/include/ros/callback_queue_interface.h +boost/shared_ptr.hpp +- +common.h +/opt/ros/hydro/include/ros/common.h +ros/types.h +/opt/ros/hydro/include/ros/ros/types.h + +/opt/ros/hydro/include/ros/common.h +stdint.h +- +assert.h +- +stddef.h +- +string +- +ros/assert.h +/opt/ros/hydro/include/ros/ros/assert.h +ros/forwards.h +/opt/ros/hydro/include/ros/ros/forwards.h +ros/serialized_message.h +/opt/ros/hydro/include/ros/ros/serialized_message.h +boost/shared_array.hpp +- +ros/macros.h +- + +/opt/ros/hydro/include/ros/console.h +console_backend.h +/opt/ros/hydro/include/ros/console_backend.h +cstdio +- +sstream +- +ros/time.h +- +cstdarg +- +ros/macros.h +- +map +- +log4cxx/level.h +/opt/ros/hydro/include/ros/log4cxx/level.h +rosconsole/macros_generated.h +/opt/ros/hydro/include/ros/rosconsole/macros_generated.h + +/opt/ros/hydro/include/ros/console_backend.h + +/opt/ros/hydro/include/ros/datatypes.h +string +- +vector +- +map +- +set +- +list +- +boost/shared_ptr.hpp +- + +/opt/ros/hydro/include/ros/duration.h +iostream +- +math.h +- +stdexcept +- +climits +- +stdint.h +- +rostime_decl.h +/opt/ros/hydro/include/ros/rostime_decl.h + +/opt/ros/hydro/include/ros/exception.h +stdexcept +- + +/opt/ros/hydro/include/ros/exceptions.h +ros/exception.h +- + +/opt/ros/hydro/include/ros/forwards.h +string +- +vector +- +map +- +set +- +list +- +boost/shared_ptr.hpp +- +boost/weak_ptr.hpp +- +boost/function.hpp +- +ros/time.h +- +ros/macros.h +- +exceptions.h +/opt/ros/hydro/include/ros/exceptions.h +ros/datatypes.h +/opt/ros/hydro/include/ros/ros/datatypes.h + +/opt/ros/hydro/include/ros/init.h +ros/forwards.h +/opt/ros/hydro/include/ros/ros/forwards.h +ros/spinner.h +/opt/ros/hydro/include/ros/ros/spinner.h +common.h +/opt/ros/hydro/include/ros/common.h + +/opt/ros/hydro/include/ros/macros.h + +/opt/ros/hydro/include/ros/master.h +forwards.h +/opt/ros/hydro/include/ros/forwards.h +XmlRpcValue.h +/opt/ros/hydro/include/ros/XmlRpcValue.h +common.h +/opt/ros/hydro/include/ros/common.h + +/opt/ros/hydro/include/ros/message.h +ros/macros.h +/opt/ros/hydro/include/ros/ros/macros.h +ros/assert.h +/opt/ros/hydro/include/ros/ros/assert.h +string +- +string.h +- +boost/shared_ptr.hpp +- +boost/array.hpp +- +stdint.h +- + +/opt/ros/hydro/include/ros/message_event.h +ros/time.h +/opt/ros/hydro/include/ros/ros/time.h +ros/datatypes.h +- +ros/message_traits.h +- +boost/type_traits/is_void.hpp +- +boost/type_traits/is_base_of.hpp +- +boost/type_traits/is_const.hpp +- +boost/type_traits/add_const.hpp +- +boost/type_traits/remove_const.hpp +- +boost/utility/enable_if.hpp +- +boost/function.hpp +- +boost/make_shared.hpp +- + +/opt/ros/hydro/include/ros/message_forward.h +memory +- + +/opt/ros/hydro/include/ros/message_operations.h +ostream +- + +/opt/ros/hydro/include/ros/message_traits.h +message_forward.h +/opt/ros/hydro/include/ros/message_forward.h +ros/time.h +- +string +- +boost/utility/enable_if.hpp +- +boost/type_traits/remove_const.hpp +- +boost/type_traits/remove_reference.hpp +- + +/opt/ros/hydro/include/ros/names.h +forwards.h +/opt/ros/hydro/include/ros/forwards.h +common.h +/opt/ros/hydro/include/ros/common.h + +/opt/ros/hydro/include/ros/node_handle.h +ros/forwards.h +/opt/ros/hydro/include/ros/ros/forwards.h +ros/publisher.h +/opt/ros/hydro/include/ros/ros/publisher.h +ros/subscriber.h +/opt/ros/hydro/include/ros/ros/subscriber.h +ros/service_server.h +/opt/ros/hydro/include/ros/ros/service_server.h +ros/service_client.h +/opt/ros/hydro/include/ros/ros/service_client.h +ros/timer.h +/opt/ros/hydro/include/ros/ros/timer.h +ros/rate.h +/opt/ros/hydro/include/ros/ros/rate.h +ros/wall_timer.h +/opt/ros/hydro/include/ros/ros/wall_timer.h +ros/advertise_options.h +/opt/ros/hydro/include/ros/ros/advertise_options.h +ros/advertise_service_options.h +/opt/ros/hydro/include/ros/ros/advertise_service_options.h +ros/subscribe_options.h +/opt/ros/hydro/include/ros/ros/subscribe_options.h +ros/service_client_options.h +/opt/ros/hydro/include/ros/ros/service_client_options.h +ros/timer_options.h +/opt/ros/hydro/include/ros/ros/timer_options.h +ros/wall_timer_options.h +/opt/ros/hydro/include/ros/ros/wall_timer_options.h +ros/spinner.h +/opt/ros/hydro/include/ros/ros/spinner.h +ros/init.h +/opt/ros/hydro/include/ros/ros/init.h +common.h +/opt/ros/hydro/include/ros/common.h +boost/bind.hpp +- +XmlRpcValue.h +- + +/opt/ros/hydro/include/ros/param.h +forwards.h +/opt/ros/hydro/include/ros/forwards.h +common.h +/opt/ros/hydro/include/ros/common.h +XmlRpcValue.h +/opt/ros/hydro/include/ros/XmlRpcValue.h +vector +- +map +- + +/opt/ros/hydro/include/ros/parameter_adapter.h +ros/forwards.h +/opt/ros/hydro/include/ros/ros/forwards.h +ros/message_event.h +/opt/ros/hydro/include/ros/ros/message_event.h +ros/static_assert.h +- +boost/type_traits/add_const.hpp +- +boost/type_traits/remove_const.hpp +- +boost/type_traits/remove_reference.hpp +- + +/opt/ros/hydro/include/ros/platform.h +windows.h +- +stdlib.h +- +string +- + +/opt/ros/hydro/include/ros/publisher.h +ros/forwards.h +/opt/ros/hydro/include/ros/ros/forwards.h +ros/common.h +/opt/ros/hydro/include/ros/ros/common.h +ros/message.h +/opt/ros/hydro/include/ros/ros/message.h +ros/serialization.h +/opt/ros/hydro/include/ros/ros/serialization.h +boost/bind.hpp +- + +/opt/ros/hydro/include/ros/rate.h +ros/time.h +/opt/ros/hydro/include/ros/ros/time.h +rostime_decl.h +/opt/ros/hydro/include/ros/rostime_decl.h + +/opt/ros/hydro/include/ros/ros.h +ros/time.h +/opt/ros/hydro/include/ros/ros/time.h +ros/rate.h +/opt/ros/hydro/include/ros/ros/rate.h +ros/console.h +/opt/ros/hydro/include/ros/ros/console.h +ros/assert.h +/opt/ros/hydro/include/ros/ros/assert.h +ros/common.h +/opt/ros/hydro/include/ros/ros/common.h +ros/types.h +/opt/ros/hydro/include/ros/ros/types.h +ros/node_handle.h +/opt/ros/hydro/include/ros/ros/node_handle.h +ros/publisher.h +/opt/ros/hydro/include/ros/ros/publisher.h +ros/single_subscriber_publisher.h +/opt/ros/hydro/include/ros/ros/single_subscriber_publisher.h +ros/service_server.h +/opt/ros/hydro/include/ros/ros/service_server.h +ros/subscriber.h +/opt/ros/hydro/include/ros/ros/subscriber.h +ros/service.h +/opt/ros/hydro/include/ros/ros/service.h +ros/init.h +/opt/ros/hydro/include/ros/ros/init.h +ros/master.h +/opt/ros/hydro/include/ros/ros/master.h +ros/this_node.h +/opt/ros/hydro/include/ros/ros/this_node.h +ros/param.h +/opt/ros/hydro/include/ros/ros/param.h +ros/topic.h +/opt/ros/hydro/include/ros/ros/topic.h +ros/names.h +/opt/ros/hydro/include/ros/ros/names.h + +/opt/ros/hydro/include/ros/roscpp_serialization_macros.h +ros/macros.h +- + +/opt/ros/hydro/include/ros/rostime_decl.h +ros/macros.h +- + +/opt/ros/hydro/include/ros/serialization.h +roscpp_serialization_macros.h +/opt/ros/hydro/include/ros/roscpp_serialization_macros.h +ros/types.h +- +ros/time.h +- +serialized_message.h +/opt/ros/hydro/include/ros/serialized_message.h +ros/message_traits.h +/opt/ros/hydro/include/ros/ros/message_traits.h +ros/builtin_message_traits.h +/opt/ros/hydro/include/ros/ros/builtin_message_traits.h +ros/exception.h +/opt/ros/hydro/include/ros/ros/exception.h +ros/datatypes.h +/opt/ros/hydro/include/ros/ros/datatypes.h +vector +- +map +- +boost/array.hpp +- +boost/call_traits.hpp +- +boost/utility/enable_if.hpp +- +boost/mpl/and.hpp +- +boost/mpl/or.hpp +- +boost/mpl/not.hpp +- +cstring +- + +/opt/ros/hydro/include/ros/serialized_message.h +roscpp_serialization_macros.h +/opt/ros/hydro/include/ros/roscpp_serialization_macros.h +boost/shared_array.hpp +- +boost/shared_ptr.hpp +- + +/opt/ros/hydro/include/ros/service.h +string +- +ros/common.h +/opt/ros/hydro/include/ros/ros/common.h +ros/message.h +/opt/ros/hydro/include/ros/ros/message.h +ros/forwards.h +/opt/ros/hydro/include/ros/ros/forwards.h +ros/node_handle.h +/opt/ros/hydro/include/ros/ros/node_handle.h +ros/service_traits.h +/opt/ros/hydro/include/ros/ros/service_traits.h +ros/names.h +/opt/ros/hydro/include/ros/ros/names.h +boost/shared_ptr.hpp +- + +/opt/ros/hydro/include/ros/service_callback_helper.h +ros/forwards.h +/opt/ros/hydro/include/ros/ros/forwards.h +ros/common.h +/opt/ros/hydro/include/ros/ros/common.h +ros/message.h +/opt/ros/hydro/include/ros/ros/message.h +ros/message_traits.h +/opt/ros/hydro/include/ros/ros/message_traits.h +ros/service_traits.h +/opt/ros/hydro/include/ros/ros/service_traits.h +ros/serialization.h +/opt/ros/hydro/include/ros/ros/serialization.h +boost/type_traits/is_base_of.hpp +- +boost/utility/enable_if.hpp +- + +/opt/ros/hydro/include/ros/service_client.h +ros/forwards.h +/opt/ros/hydro/include/ros/ros/forwards.h +ros/common.h +/opt/ros/hydro/include/ros/ros/common.h +ros/service_traits.h +/opt/ros/hydro/include/ros/ros/service_traits.h +ros/serialization.h +/opt/ros/hydro/include/ros/ros/serialization.h + +/opt/ros/hydro/include/ros/service_client_options.h +ros/forwards.h +/opt/ros/hydro/include/ros/ros/forwards.h +common.h +/opt/ros/hydro/include/ros/common.h +ros/service_traits.h +/opt/ros/hydro/include/ros/ros/service_traits.h + +/opt/ros/hydro/include/ros/service_server.h +ros/forwards.h +/opt/ros/hydro/include/ros/ros/forwards.h +common.h +/opt/ros/hydro/include/ros/common.h + +/opt/ros/hydro/include/ros/service_traits.h +boost/type_traits/remove_reference.hpp +- +boost/type_traits/remove_const.hpp +- + +/opt/ros/hydro/include/ros/single_subscriber_publisher.h +ros/forwards.h +/opt/ros/hydro/include/ros/ros/forwards.h +ros/serialization.h +/opt/ros/hydro/include/ros/ros/serialization.h +common.h +/opt/ros/hydro/include/ros/common.h +boost/utility.hpp +- + +/opt/ros/hydro/include/ros/spinner.h +ros/types.h +/opt/ros/hydro/include/ros/ros/types.h +common.h +/opt/ros/hydro/include/ros/common.h +boost/shared_ptr.hpp +- + +/opt/ros/hydro/include/ros/static_assert.h +boost/static_assert.hpp +- + +/opt/ros/hydro/include/ros/subscribe_options.h +ros/forwards.h +/opt/ros/hydro/include/ros/ros/forwards.h +common.h +/opt/ros/hydro/include/ros/common.h +ros/transport_hints.h +/opt/ros/hydro/include/ros/ros/transport_hints.h +ros/message_traits.h +/opt/ros/hydro/include/ros/ros/message_traits.h +subscription_callback_helper.h +/opt/ros/hydro/include/ros/subscription_callback_helper.h + +/opt/ros/hydro/include/ros/subscriber.h +common.h +/opt/ros/hydro/include/ros/common.h +ros/forwards.h +/opt/ros/hydro/include/ros/ros/forwards.h +ros/subscription_callback_helper.h +/opt/ros/hydro/include/ros/ros/subscription_callback_helper.h + +/opt/ros/hydro/include/ros/subscription_callback_helper.h +typeinfo +- +common.h +/opt/ros/hydro/include/ros/common.h +ros/forwards.h +/opt/ros/hydro/include/ros/ros/forwards.h +ros/parameter_adapter.h +/opt/ros/hydro/include/ros/ros/parameter_adapter.h +ros/message_traits.h +/opt/ros/hydro/include/ros/ros/message_traits.h +ros/builtin_message_traits.h +/opt/ros/hydro/include/ros/ros/builtin_message_traits.h +ros/serialization.h +/opt/ros/hydro/include/ros/ros/serialization.h +ros/message_event.h +/opt/ros/hydro/include/ros/ros/message_event.h +ros/static_assert.h +- +boost/type_traits/add_const.hpp +- +boost/type_traits/remove_const.hpp +- +boost/type_traits/remove_reference.hpp +- +boost/type_traits/is_base_of.hpp +- +boost/utility/enable_if.hpp +- +boost/make_shared.hpp +- + +/opt/ros/hydro/include/ros/this_node.h +common.h +/opt/ros/hydro/include/ros/common.h +forwards.h +/opt/ros/hydro/include/ros/forwards.h + +/opt/ros/hydro/include/ros/time.h +ros/platform.h +- +iostream +- +cmath +- +ros/exception.h +- +duration.h +/opt/ros/hydro/include/ros/duration.h +boost/math/special_functions/round.hpp +- +rostime_decl.h +/opt/ros/hydro/include/ros/rostime_decl.h +sys/timeb.h +- +sys/time.h +- + +/opt/ros/hydro/include/ros/timer.h +common.h +/opt/ros/hydro/include/ros/common.h +forwards.h +/opt/ros/hydro/include/ros/forwards.h +timer_options.h +/opt/ros/hydro/include/ros/timer_options.h + +/opt/ros/hydro/include/ros/timer_options.h +common.h +/opt/ros/hydro/include/ros/common.h +ros/forwards.h +/opt/ros/hydro/include/ros/ros/forwards.h + +/opt/ros/hydro/include/ros/topic.h +common.h +/opt/ros/hydro/include/ros/common.h +node_handle.h +/opt/ros/hydro/include/ros/node_handle.h +boost/shared_ptr.hpp +- + +/opt/ros/hydro/include/ros/transport_hints.h +common.h +/opt/ros/hydro/include/ros/common.h +ros/forwards.h +/opt/ros/hydro/include/ros/ros/forwards.h +boost/lexical_cast.hpp +- + +/opt/ros/hydro/include/ros/types.h +stdint.h +- + +/opt/ros/hydro/include/ros/wall_timer.h +common.h +/opt/ros/hydro/include/ros/common.h +forwards.h +/opt/ros/hydro/include/ros/forwards.h +wall_timer_options.h +/opt/ros/hydro/include/ros/wall_timer_options.h + +/opt/ros/hydro/include/ros/wall_timer_options.h +common.h +/opt/ros/hydro/include/ros/common.h +ros/forwards.h +/opt/ros/hydro/include/ros/ros/forwards.h + +/opt/ros/hydro/include/rosconsole/macros_generated.h + +/opt/ros/hydro/include/sensor_msgs/ChannelFloat32.h +string +- +vector +- +map +- +ros/types.h +- +ros/serialization.h +- +ros/builtin_message_traits.h +- +ros/message_operations.h +- + +/opt/ros/hydro/include/sensor_msgs/JointState.h +string +- +vector +- +map +- +ros/types.h +- +ros/serialization.h +- +ros/builtin_message_traits.h +- +ros/message_operations.h +- +std_msgs/Header.h +- + +/opt/ros/hydro/include/sensor_msgs/PointCloud.h +string +- +vector +- +map +- +ros/types.h +- +ros/serialization.h +- +ros/builtin_message_traits.h +- +ros/message_operations.h +- +std_msgs/Header.h +- +geometry_msgs/Point32.h +- +sensor_msgs/ChannelFloat32.h +- + +/opt/ros/hydro/include/sensor_msgs/PointCloud2.h +string +- +vector +- +map +- +ros/types.h +- +ros/serialization.h +- +ros/builtin_message_traits.h +- +ros/message_operations.h +- +std_msgs/Header.h +- +sensor_msgs/PointField.h +- + +/opt/ros/hydro/include/sensor_msgs/PointField.h +string +- +vector +- +map +- +ros/types.h +- +ros/serialization.h +- +ros/builtin_message_traits.h +- +ros/message_operations.h +- + +/opt/ros/hydro/include/sensor_msgs/point_cloud_conversion.h +sensor_msgs/PointCloud.h +- +sensor_msgs/PointCloud2.h +- + +/opt/ros/hydro/include/std_msgs/Bool.h +string +- +vector +- +map +- +ros/types.h +- +ros/serialization.h +- +ros/builtin_message_traits.h +- +ros/message_operations.h +- + +/opt/ros/hydro/include/std_msgs/Empty.h +string +- +vector +- +map +- +ros/types.h +- +ros/serialization.h +- +ros/builtin_message_traits.h +- +ros/message_operations.h +- + +/opt/ros/hydro/include/std_msgs/Float32.h +string +- +vector +- +map +- +ros/types.h +- +ros/serialization.h +- +ros/builtin_message_traits.h +- +ros/message_operations.h +- + +/opt/ros/hydro/include/std_msgs/Float64.h +string +- +vector +- +map +- +ros/types.h +- +ros/serialization.h +- +ros/builtin_message_traits.h +- +ros/message_operations.h +- + +/opt/ros/hydro/include/std_msgs/Header.h +string +- +vector +- +map +- +ros/types.h +- +ros/serialization.h +- +ros/builtin_message_traits.h +- +ros/message_operations.h +- + +/opt/ros/hydro/include/std_msgs/Int8.h +string +- +vector +- +map +- +ros/types.h +- +ros/serialization.h +- +ros/builtin_message_traits.h +- +ros/message_operations.h +- + +/opt/ros/hydro/include/std_msgs/UInt8.h +string +- +vector +- +map +- +ros/types.h +- +ros/serialization.h +- +ros/builtin_message_traits.h +- +ros/message_operations.h +- + +/opt/ros/hydro/include/std_srvs/Empty.h +ros/service_traits.h +- +std_srvs/EmptyRequest.h +- +std_srvs/EmptyResponse.h +- + +/opt/ros/hydro/include/std_srvs/EmptyRequest.h +string +- +vector +- +map +- +ros/types.h +- +ros/serialization.h +- +ros/builtin_message_traits.h +- +ros/message_operations.h +- + +/opt/ros/hydro/include/std_srvs/EmptyResponse.h +string +- +vector +- +map +- +ros/types.h +- +ros/serialization.h +- +ros/builtin_message_traits.h +- +ros/message_operations.h +- + +/opt/ros/hydro/include/tf/FrameGraph.h +ros/service_traits.h +- +tf/FrameGraphRequest.h +- +tf/FrameGraphResponse.h +- + +/opt/ros/hydro/include/tf/FrameGraphRequest.h +string +- +vector +- +map +- +ros/types.h +- +ros/serialization.h +- +ros/builtin_message_traits.h +- +ros/message_operations.h +- + +/opt/ros/hydro/include/tf/FrameGraphResponse.h +string +- +vector +- +map +- +ros/types.h +- +ros/serialization.h +- +ros/builtin_message_traits.h +- +ros/message_operations.h +- + +/opt/ros/hydro/include/tf/LinearMath/Matrix3x3.h +Vector3.h +/opt/ros/hydro/include/tf/LinearMath/Vector3.h +Quaternion.h +/opt/ros/hydro/include/tf/LinearMath/Quaternion.h + +/opt/ros/hydro/include/tf/LinearMath/MinMax.h + +/opt/ros/hydro/include/tf/LinearMath/QuadWord.h +Scalar.h +/opt/ros/hydro/include/tf/LinearMath/Scalar.h +MinMax.h +/opt/ros/hydro/include/tf/LinearMath/MinMax.h +altivec.h +- + +/opt/ros/hydro/include/tf/LinearMath/Quaternion.h +Vector3.h +/opt/ros/hydro/include/tf/LinearMath/Vector3.h +QuadWord.h +/opt/ros/hydro/include/tf/LinearMath/QuadWord.h + +/opt/ros/hydro/include/tf/LinearMath/Scalar.h +math.h +- +stdlib.h +- +cstdlib +- +cfloat +- +float.h +- +ppcintrinsics.h +- +assert.h +- +assert.h +- +assert.h +- +assert.h +- + +/opt/ros/hydro/include/tf/LinearMath/Transform.h +Matrix3x3.h +/opt/ros/hydro/include/tf/LinearMath/Matrix3x3.h + +/opt/ros/hydro/include/tf/LinearMath/Vector3.h +Scalar.h +/opt/ros/hydro/include/tf/LinearMath/Scalar.h +MinMax.h +/opt/ros/hydro/include/tf/LinearMath/MinMax.h + +/opt/ros/hydro/include/tf/exceptions.h +stdexcept +- +tf2/exceptions.h +- + +/opt/ros/hydro/include/tf/tf.h +iostream +- +iomanip +- +cmath +- +vector +- +sstream +- +map +- +tf/exceptions.h +- +tf/time_cache.h +/opt/ros/hydro/include/tf/tf/time_cache.h +boost/unordered_map.hpp +- +boost/signals.hpp +- +geometry_msgs/TwistStamped.h +/opt/ros/hydro/include/tf/geometry_msgs/TwistStamped.h +tf2_ros/buffer.h +- + +/opt/ros/hydro/include/tf/tfMessage.h +string +- +vector +- +map +- +ros/types.h +- +ros/serialization.h +- +ros/builtin_message_traits.h +- +ros/message_operations.h +- +geometry_msgs/TransformStamped.h +- + +/opt/ros/hydro/include/tf/time_cache.h +set +- +boost/thread/mutex.hpp +- +tf/transform_datatypes.h +/opt/ros/hydro/include/tf/tf/transform_datatypes.h +tf/exceptions.h +/opt/ros/hydro/include/tf/tf/exceptions.h +tf/LinearMath/Transform.h +/opt/ros/hydro/include/tf/tf/LinearMath/Transform.h +sstream +- + +/opt/ros/hydro/include/tf/transform_broadcaster.h +tf/tf.h +/opt/ros/hydro/include/tf/tf/tf.h +tf/tfMessage.h +/opt/ros/hydro/include/tf/tf/tfMessage.h +tf2_ros/transform_broadcaster.h +- + +/opt/ros/hydro/include/tf/transform_datatypes.h +string +- +geometry_msgs/PointStamped.h +/opt/ros/hydro/include/tf/geometry_msgs/PointStamped.h +geometry_msgs/Vector3Stamped.h +/opt/ros/hydro/include/tf/geometry_msgs/Vector3Stamped.h +geometry_msgs/QuaternionStamped.h +/opt/ros/hydro/include/tf/geometry_msgs/QuaternionStamped.h +geometry_msgs/TransformStamped.h +/opt/ros/hydro/include/tf/geometry_msgs/TransformStamped.h +geometry_msgs/PoseStamped.h +/opt/ros/hydro/include/tf/geometry_msgs/PoseStamped.h +tf/LinearMath/Transform.h +/opt/ros/hydro/include/tf/tf/LinearMath/Transform.h +ros/time.h +/opt/ros/hydro/include/tf/ros/time.h +ros/console.h +/opt/ros/hydro/include/tf/ros/console.h + +/opt/ros/hydro/include/tf/transform_listener.h +sensor_msgs/PointCloud.h +/opt/ros/hydro/include/tf/sensor_msgs/PointCloud.h +std_msgs/Empty.h +/opt/ros/hydro/include/tf/std_msgs/Empty.h +tf/tfMessage.h +/opt/ros/hydro/include/tf/tf/tfMessage.h +tf/tf.h +/opt/ros/hydro/include/tf/tf/tf.h +ros/ros.h +/opt/ros/hydro/include/tf/ros/ros.h +ros/callback_queue.h +/opt/ros/hydro/include/tf/ros/callback_queue.h +tf/FrameGraph.h +/opt/ros/hydro/include/tf/tf/FrameGraph.h +boost/thread.hpp +/opt/ros/hydro/include/tf/boost/thread.hpp +tf2_ros/transform_listener.h +- + +/opt/ros/hydro/include/tf2/LinearMath/Quaternion.h +Vector3.h +/opt/ros/hydro/include/tf2/LinearMath/Vector3.h +QuadWord.h +/opt/ros/hydro/include/tf2/LinearMath/QuadWord.h + +/opt/ros/hydro/include/tf2/LinearMath/Vector3.h +Scalar.h +/opt/ros/hydro/include/tf2/LinearMath/Scalar.h +MinMax.h +/opt/ros/hydro/include/tf2/LinearMath/MinMax.h + +/opt/ros/hydro/include/tf2/buffer_core.h +transform_storage.h +/opt/ros/hydro/include/tf2/transform_storage.h +boost/signals.hpp +- +string +- +ros/duration.h +/opt/ros/hydro/include/tf2/ros/duration.h +ros/time.h +/opt/ros/hydro/include/tf2/ros/time.h +geometry_msgs/TransformStamped.h +/opt/ros/hydro/include/tf2/geometry_msgs/TransformStamped.h +boost/unordered_map.hpp +- +boost/thread/mutex.hpp +- +boost/function.hpp +- +boost/shared_ptr.hpp +- + +/opt/ros/hydro/include/tf2/convert.h +tf2/transform_datatypes.h +- +tf2/exceptions.h +- +geometry_msgs/TransformStamped.h +- + +/opt/ros/hydro/include/tf2/exceptions.h +stdexcept +- + +/opt/ros/hydro/include/tf2/transform_datatypes.h +string +- +ros/time.h +/opt/ros/hydro/include/tf2/ros/time.h + +/opt/ros/hydro/include/tf2/transform_storage.h +tf2/LinearMath/Vector3.h +- +tf2/LinearMath/Quaternion.h +- +ros/message_forward.h +- +ros/time.h +- +ros/types.h +- + +/opt/ros/hydro/include/tf2_msgs/FrameGraph.h +ros/service_traits.h +- +tf2_msgs/FrameGraphRequest.h +- +tf2_msgs/FrameGraphResponse.h +- + +/opt/ros/hydro/include/tf2_msgs/FrameGraphRequest.h +string +- +vector +- +map +- +ros/types.h +- +ros/serialization.h +- +ros/builtin_message_traits.h +- +ros/message_operations.h +- + +/opt/ros/hydro/include/tf2_msgs/FrameGraphResponse.h +string +- +vector +- +map +- +ros/types.h +- +ros/serialization.h +- +ros/builtin_message_traits.h +- +ros/message_operations.h +- + +/opt/ros/hydro/include/tf2_msgs/TFMessage.h +string +- +vector +- +map +- +ros/types.h +- +ros/serialization.h +- +ros/builtin_message_traits.h +- +ros/message_operations.h +- +geometry_msgs/TransformStamped.h +- + +/opt/ros/hydro/include/tf2_ros/buffer.h +tf2_ros/buffer_interface.h +- +tf2/buffer_core.h +- +tf2_msgs/FrameGraph.h +- +ros/ros.h +- +tf2/convert.h +- + +/opt/ros/hydro/include/tf2_ros/buffer_interface.h +tf2/buffer_core.h +- +tf2/transform_datatypes.h +- +tf2/exceptions.h +- +geometry_msgs/TransformStamped.h +- +sstream +- +tf2/convert.h +- + +/opt/ros/hydro/include/tf2_ros/transform_broadcaster.h +ros/ros.h +/opt/ros/hydro/include/tf2_ros/ros/ros.h +geometry_msgs/TransformStamped.h +/opt/ros/hydro/include/tf2_ros/geometry_msgs/TransformStamped.h + +/opt/ros/hydro/include/tf2_ros/transform_listener.h +std_msgs/Empty.h +/opt/ros/hydro/include/tf2_ros/std_msgs/Empty.h +tf2_msgs/TFMessage.h +/opt/ros/hydro/include/tf2_ros/tf2_msgs/TFMessage.h +ros/ros.h +/opt/ros/hydro/include/tf2_ros/ros/ros.h +ros/callback_queue.h +/opt/ros/hydro/include/tf2_ros/ros/callback_queue.h +tf2_ros/buffer.h +/opt/ros/hydro/include/tf2_ros/tf2_ros/buffer.h +boost/thread.hpp +/opt/ros/hydro/include/tf2_ros/boost/thread.hpp + +/usr/local/Aria/include/ArACTS.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArTcpConnection.h +/usr/local/Aria/include/ArTcpConnection.h +ariaUtil.h +/usr/local/Aria/include/ariaUtil.h +ArRobot.h +/usr/local/Aria/include/ArRobot.h + +/usr/local/Aria/include/ArAMPTU.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArBasePacket.h +/usr/local/Aria/include/ArBasePacket.h +ArPTZ.h +/usr/local/Aria/include/ArPTZ.h + +/usr/local/Aria/include/ArASyncTask.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArFunctor.h +/usr/local/Aria/include/ArFunctor.h +ArThread.h +/usr/local/Aria/include/ArThread.h + +/usr/local/Aria/include/ArAction.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArArg.h +/usr/local/Aria/include/ArArg.h +ArActionDesired.h +/usr/local/Aria/include/ArActionDesired.h +map +- +string +- + +/usr/local/Aria/include/ArActionAvoidFront.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ariaUtil.h +/usr/local/Aria/include/ariaUtil.h +ArFunctor.h +/usr/local/Aria/include/ArFunctor.h +ArAction.h +/usr/local/Aria/include/ArAction.h + +/usr/local/Aria/include/ArActionAvoidSide.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArAction.h +/usr/local/Aria/include/ArAction.h + +/usr/local/Aria/include/ArActionBumpers.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArAction.h +/usr/local/Aria/include/ArAction.h + +/usr/local/Aria/include/ArActionColorFollow.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ariaUtil.h +/usr/local/Aria/include/ariaUtil.h +ArFunctor.h +/usr/local/Aria/include/ArFunctor.h +ArAction.h +/usr/local/Aria/include/ArAction.h +ArACTS.h +/usr/local/Aria/include/ArACTS.h +ArPTZ.h +/usr/local/Aria/include/ArPTZ.h + +/usr/local/Aria/include/ArActionConstantVelocity.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArAction.h +/usr/local/Aria/include/ArAction.h + +/usr/local/Aria/include/ArActionDeceleratingLimiter.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArAction.h +/usr/local/Aria/include/ArAction.h + +/usr/local/Aria/include/ArActionDesired.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ariaUtil.h +/usr/local/Aria/include/ariaUtil.h + +/usr/local/Aria/include/ArActionDriveDistance.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ariaUtil.h +/usr/local/Aria/include/ariaUtil.h +ArAction.h +/usr/local/Aria/include/ArAction.h + +/usr/local/Aria/include/ArActionGoto.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ariaUtil.h +/usr/local/Aria/include/ariaUtil.h +ArAction.h +/usr/local/Aria/include/ArAction.h + +/usr/local/Aria/include/ArActionGotoStraight.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ariaUtil.h +/usr/local/Aria/include/ariaUtil.h +ArAction.h +/usr/local/Aria/include/ArAction.h + +/usr/local/Aria/include/ArActionGroup.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +list +- + +/usr/local/Aria/include/ArActionGroups.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArActionGroup.h +/usr/local/Aria/include/ArActionGroup.h +ArActionColorFollow.h +/usr/local/Aria/include/ArActionColorFollow.h +ArACTS.h +/usr/local/Aria/include/ArACTS.h +ArPTZ.h +/usr/local/Aria/include/ArPTZ.h + +/usr/local/Aria/include/ArActionIRs.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArAction.h +/usr/local/Aria/include/ArAction.h +ArRobotParams.h +/usr/local/Aria/include/ArRobotParams.h +vector +- + +/usr/local/Aria/include/ArActionInput.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArAction.h +/usr/local/Aria/include/ArAction.h + +/usr/local/Aria/include/ArActionJoydrive.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArAction.h +/usr/local/Aria/include/ArAction.h +ArJoyHandler.h +/usr/local/Aria/include/ArJoyHandler.h + +/usr/local/Aria/include/ArActionKeydrive.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArAction.h +/usr/local/Aria/include/ArAction.h +ArFunctor.h +/usr/local/Aria/include/ArFunctor.h + +/usr/local/Aria/include/ArActionLimiterBackwards.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArAction.h +/usr/local/Aria/include/ArAction.h + +/usr/local/Aria/include/ArActionLimiterForwards.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArAction.h +/usr/local/Aria/include/ArAction.h + +/usr/local/Aria/include/ArActionLimiterRot.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArAction.h +/usr/local/Aria/include/ArAction.h + +/usr/local/Aria/include/ArActionLimiterTableSensor.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArAction.h +/usr/local/Aria/include/ArAction.h + +/usr/local/Aria/include/ArActionMovementParameters.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArAction.h +/usr/local/Aria/include/ArAction.h +ArMapObject.h +/usr/local/Aria/include/ArMapObject.h + +/usr/local/Aria/include/ArActionMovementParametersDebugging.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArAction.h +/usr/local/Aria/include/ArAction.h +ArMapObject.h +/usr/local/Aria/include/ArMapObject.h + +/usr/local/Aria/include/ArActionRatioInput.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArAction.h +/usr/local/Aria/include/ArAction.h + +/usr/local/Aria/include/ArActionRobotJoydrive.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArAction.h +/usr/local/Aria/include/ArAction.h + +/usr/local/Aria/include/ArActionStallRecover.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArAction.h +/usr/local/Aria/include/ArAction.h + +/usr/local/Aria/include/ArActionStop.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArAction.h +/usr/local/Aria/include/ArAction.h + +/usr/local/Aria/include/ArActionTriangleDriveTo.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArAction.h +/usr/local/Aria/include/ArAction.h +ArLineFinder.h +/usr/local/Aria/include/ArLineFinder.h + +/usr/local/Aria/include/ArActionTurn.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArAction.h +/usr/local/Aria/include/ArAction.h + +/usr/local/Aria/include/ArAnalogGyro.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ariaUtil.h +/usr/local/Aria/include/ariaUtil.h +ArFunctor.h +/usr/local/Aria/include/ArFunctor.h + +/usr/local/Aria/include/ArArg.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ariaUtil.h +/usr/local/Aria/include/ariaUtil.h +ArFunctor.h +/usr/local/Aria/include/ArFunctor.h + +/usr/local/Aria/include/ArArgumentBuilder.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h + +/usr/local/Aria/include/ArArgumentParser.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArArgumentBuilder.h +/usr/local/Aria/include/ArArgumentBuilder.h + +/usr/local/Aria/include/ArBasePacket.h +string +- +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h + +/usr/local/Aria/include/ArBatteryConnector.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArSerialConnection.h +/usr/local/Aria/include/ArSerialConnection.h +ArTcpConnection.h +/usr/local/Aria/include/ArTcpConnection.h +ArArgumentBuilder.h +/usr/local/Aria/include/ArArgumentBuilder.h +ArArgumentParser.h +/usr/local/Aria/include/ArArgumentParser.h +ariaUtil.h +/usr/local/Aria/include/ariaUtil.h +ArRobotConnector.h +/usr/local/Aria/include/ArRobotConnector.h + +/usr/local/Aria/include/ArBatteryMTX.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArRangeDevice.h +/usr/local/Aria/include/ArRangeDevice.h +ArFunctor.h +/usr/local/Aria/include/ArFunctor.h +ArRobot.h +/usr/local/Aria/include/ArRobot.h +ArRobotPacket.h +/usr/local/Aria/include/ArRobotPacket.h +ArRobotConnector.h +/usr/local/Aria/include/ArRobotConnector.h + +/usr/local/Aria/include/ArBumpers.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArRangeDevice.h +/usr/local/Aria/include/ArRangeDevice.h + +/usr/local/Aria/include/ArCameraCollection.h +list +- +map +- +string +- +ArConfigArg.h +/usr/local/Aria/include/ArConfigArg.h +ArFunctor.h +/usr/local/Aria/include/ArFunctor.h +ArMutex.h +/usr/local/Aria/include/ArMutex.h + +/usr/local/Aria/include/ArCameraCommands.h +ariaUtil.h +/usr/local/Aria/include/ariaUtil.h + +/usr/local/Aria/include/ArCommands.h + +/usr/local/Aria/include/ArCondition.h +pthread.h +- +ArMutex.h +/usr/local/Aria/include/ArMutex.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h + +/usr/local/Aria/include/ArConfig.h +ArConfigArg.h +/usr/local/Aria/include/ArConfigArg.h +ArFileParser.h +/usr/local/Aria/include/ArFileParser.h +ArHasFileName.h +/usr/local/Aria/include/ArHasFileName.h +set +- + +/usr/local/Aria/include/ArConfigArg.h +map +- +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ariaUtil.h +/usr/local/Aria/include/ariaUtil.h +ArFunctor.h +/usr/local/Aria/include/ArFunctor.h + +/usr/local/Aria/include/ArConfigGroup.h +ArConfig.h +/usr/local/Aria/include/ArConfig.h + +/usr/local/Aria/include/ArDPPTU.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArRobot.h +/usr/local/Aria/include/ArRobot.h +ArPTZ.h +/usr/local/Aria/include/ArPTZ.h +vector +- + +/usr/local/Aria/include/ArDataLogger.h +ariaUtil.h +/usr/local/Aria/include/ariaUtil.h +ArMutex.h +/usr/local/Aria/include/ArMutex.h +ArFunctor.h +/usr/local/Aria/include/ArFunctor.h +vector +- + +/usr/local/Aria/include/ArDeviceConnection.h +string +- +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ariaUtil.h +/usr/local/Aria/include/ariaUtil.h +ArBasePacket.h +/usr/local/Aria/include/ArBasePacket.h + +/usr/local/Aria/include/ArDrawingData.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ariaUtil.h +/usr/local/Aria/include/ariaUtil.h + +/usr/local/Aria/include/ArExitErrorSource.h + +/usr/local/Aria/include/ArFileParser.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArArgumentParser.h +/usr/local/Aria/include/ArArgumentParser.h +ArFunctor.h +/usr/local/Aria/include/ArFunctor.h +ariaUtil.h +/usr/local/Aria/include/ariaUtil.h + +/usr/local/Aria/include/ArForbiddenRangeDevice.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArRangeDevice.h +/usr/local/Aria/include/ArRangeDevice.h +ArMapInterface.h +/usr/local/Aria/include/ArMapInterface.h + +/usr/local/Aria/include/ArFunctor.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ariaOSDef.h +/usr/local/Aria/include/ariaOSDef.h +stdarg.h +- +stdio.h +- + +/usr/local/Aria/include/ArFunctorASyncTask.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArASyncTask.h +/usr/local/Aria/include/ArASyncTask.h +ArFunctor.h +/usr/local/Aria/include/ArFunctor.h + +/usr/local/Aria/include/ArGPS.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArFunctor.h +/usr/local/Aria/include/ArFunctor.h +ariaUtil.h +/usr/local/Aria/include/ariaUtil.h +ArMutex.h +/usr/local/Aria/include/ArMutex.h +ArNMEAParser.h +/usr/local/Aria/include/ArNMEAParser.h +math.h +- +string +- +vector +- + +/usr/local/Aria/include/ArGPSCoords.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h + +/usr/local/Aria/include/ArGripper.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArRobot.h +/usr/local/Aria/include/ArRobot.h + +/usr/local/Aria/include/ArHasFileName.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h + +/usr/local/Aria/include/ArIRs.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArRangeDevice.h +/usr/local/Aria/include/ArRangeDevice.h + +/usr/local/Aria/include/ArInterpolation.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ariaUtil.h +/usr/local/Aria/include/ariaUtil.h + +/usr/local/Aria/include/ArIrrfDevice.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArRangeDevice.h +/usr/local/Aria/include/ArRangeDevice.h +ArFunctor.h +/usr/local/Aria/include/ArFunctor.h +ArRobot.h +/usr/local/Aria/include/ArRobot.h + +/usr/local/Aria/include/ArJoyHandler.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ariaUtil.h +/usr/local/Aria/include/ariaUtil.h +mmsystem.h +- +stdio.h +- +unistd.h +- +stdlib.h +- +sys/ioctl.h +- +fcntl.h +- +linux/joystick.h +- + +/usr/local/Aria/include/ArKeyHandler.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArFunctor.h +/usr/local/Aria/include/ArFunctor.h +map +- +stdio.h +- +termios.h +- +unistd.h +- + +/usr/local/Aria/include/ArLCDConnector.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArSerialConnection.h +/usr/local/Aria/include/ArSerialConnection.h +ArTcpConnection.h +/usr/local/Aria/include/ArTcpConnection.h +ArArgumentBuilder.h +/usr/local/Aria/include/ArArgumentBuilder.h +ArArgumentParser.h +/usr/local/Aria/include/ArArgumentParser.h +ariaUtil.h +/usr/local/Aria/include/ariaUtil.h +ArRobotConnector.h +/usr/local/Aria/include/ArRobotConnector.h + +/usr/local/Aria/include/ArLCDMTX.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArRangeDevice.h +/usr/local/Aria/include/ArRangeDevice.h +ArFunctor.h +/usr/local/Aria/include/ArFunctor.h +ArRobot.h +/usr/local/Aria/include/ArRobot.h +ArRobotPacket.h +/usr/local/Aria/include/ArRobotPacket.h +ArRobotConnector.h +/usr/local/Aria/include/ArRobotConnector.h + +/usr/local/Aria/include/ArLMS1XX.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArRobotPacket.h +/usr/local/Aria/include/ArRobotPacket.h +ArLaser.h +/usr/local/Aria/include/ArLaser.h +ArFunctor.h +/usr/local/Aria/include/ArFunctor.h + +/usr/local/Aria/include/ArLMS2xx.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArLMS2xxPacket.h +/usr/local/Aria/include/ArLMS2xxPacket.h +ArLMS2xxPacketReceiver.h +/usr/local/Aria/include/ArLMS2xxPacketReceiver.h +ArRobotPacket.h +/usr/local/Aria/include/ArRobotPacket.h +ArLaser.h +/usr/local/Aria/include/ArLaser.h +ArFunctor.h +/usr/local/Aria/include/ArFunctor.h +ArCondition.h +/usr/local/Aria/include/ArCondition.h + +/usr/local/Aria/include/ArLMS2xxPacket.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArBasePacket.h +/usr/local/Aria/include/ArBasePacket.h +ariaUtil.h +/usr/local/Aria/include/ariaUtil.h + +/usr/local/Aria/include/ArLMS2xxPacketReceiver.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArDeviceConnection.h +/usr/local/Aria/include/ArDeviceConnection.h +ArLMS2xxPacket.h +/usr/local/Aria/include/ArLMS2xxPacket.h + +/usr/local/Aria/include/ArLaser.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArRangeDeviceThreaded.h +/usr/local/Aria/include/ArRangeDeviceThreaded.h + +/usr/local/Aria/include/ArLaserConnector.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArSerialConnection.h +/usr/local/Aria/include/ArSerialConnection.h +ArTcpConnection.h +/usr/local/Aria/include/ArTcpConnection.h +ArArgumentBuilder.h +/usr/local/Aria/include/ArArgumentBuilder.h +ArArgumentParser.h +/usr/local/Aria/include/ArArgumentParser.h +ariaUtil.h +/usr/local/Aria/include/ariaUtil.h +ArRobotConnector.h +/usr/local/Aria/include/ArRobotConnector.h + +/usr/local/Aria/include/ArLaserFilter.h +ArLaser.h +/usr/local/Aria/include/ArLaser.h +ArFunctor.h +/usr/local/Aria/include/ArFunctor.h + +/usr/local/Aria/include/ArLaserLogger.h +stdio.h +- +ariaUtil.h +/usr/local/Aria/include/ariaUtil.h +ArFunctor.h +/usr/local/Aria/include/ArFunctor.h + +/usr/local/Aria/include/ArLaserReflectorDevice.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArRangeDevice.h +/usr/local/Aria/include/ArRangeDevice.h +ArFunctor.h +/usr/local/Aria/include/ArFunctor.h + +/usr/local/Aria/include/ArLineFinder.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArRangeDevice.h +/usr/local/Aria/include/ArRangeDevice.h +ariaUtil.h +/usr/local/Aria/include/ariaUtil.h +vector +- + +/usr/local/Aria/include/ArLog.h +stdio.h +- +string +- +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArMutex.h +/usr/local/Aria/include/ArMutex.h +ArFunctor.h +/usr/local/Aria/include/ArFunctor.h + +/usr/local/Aria/include/ArLogFileConnection.h +ArDeviceConnection.h +/usr/local/Aria/include/ArDeviceConnection.h +string +- +stdio.h +- +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h + +/usr/local/Aria/include/ArMTXIO.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArRobot.h +/usr/local/Aria/include/ArRobot.h + +/usr/local/Aria/include/ArMap.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ariaUtil.h +/usr/local/Aria/include/ariaUtil.h +ArMapComponents.h +/usr/local/Aria/include/ArMapComponents.h +ArMapInterface.h +/usr/local/Aria/include/ArMapInterface.h +ArMapUtils.h +/usr/local/Aria/include/ArMapUtils.h +ArFunctor.h +/usr/local/Aria/include/ArFunctor.h +ArArgumentBuilder.h +/usr/local/Aria/include/ArArgumentBuilder.h +ArMutex.h +/usr/local/Aria/include/ArMutex.h +vector +- + +/usr/local/Aria/include/ArMapComponents.h +ArMapInterface.h +/usr/local/Aria/include/ArMapInterface.h + +/usr/local/Aria/include/ArMapInterface.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ariaUtil.h +/usr/local/Aria/include/ariaUtil.h +ArMapObject.h +/usr/local/Aria/include/ArMapObject.h +ArMapUtils.h +/usr/local/Aria/include/ArMapUtils.h +ArArgumentBuilder.h +/usr/local/Aria/include/ArArgumentBuilder.h +ArFunctor.h +/usr/local/Aria/include/ArFunctor.h +ArHasFileName.h +/usr/local/Aria/include/ArHasFileName.h +ArMutex.h +/usr/local/Aria/include/ArMutex.h +vector +- +set +- + +/usr/local/Aria/include/ArMapObject.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ariaUtil.h +/usr/local/Aria/include/ariaUtil.h + +/usr/local/Aria/include/ArMapUtils.h +algorithm +- +functional +- +map +- +set +- +string +- +vector +- +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ariaUtil.h +/usr/local/Aria/include/ariaUtil.h + +/usr/local/Aria/include/ArMode.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArFunctor.h +/usr/local/Aria/include/ArFunctor.h +string +- +list +- + +/usr/local/Aria/include/ArModes.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArMode.h +/usr/local/Aria/include/ArMode.h +ArActionGroups.h +/usr/local/Aria/include/ArActionGroups.h +ArGripper.h +/usr/local/Aria/include/ArGripper.h +ArTcpConnection.h +/usr/local/Aria/include/ArTcpConnection.h +ArSerialConnection.h +/usr/local/Aria/include/ArSerialConnection.h +ArPTZ.h +/usr/local/Aria/include/ArPTZ.h +ArTCMCompassRobot.h +/usr/local/Aria/include/ArTCMCompassRobot.h +ArRobotConfigPacketReader.h +/usr/local/Aria/include/ArRobotConfigPacketReader.h + +/usr/local/Aria/include/ArModule.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArRobot.h +/usr/local/Aria/include/ArRobot.h + +/usr/local/Aria/include/ArModuleLoader.h +map +- +string +- +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArRobot.h +/usr/local/Aria/include/ArRobot.h + +/usr/local/Aria/include/ArMutex.h +pthread.h +- +string +- +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h + +/usr/local/Aria/include/ArNMEAParser.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArFunctor.h +/usr/local/Aria/include/ArFunctor.h +ariaUtil.h +/usr/local/Aria/include/ariaUtil.h +ArDeviceConnection.h +/usr/local/Aria/include/ArDeviceConnection.h +string +- +vector +- + +/usr/local/Aria/include/ArNetServer.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArSocket.h +/usr/local/Aria/include/ArSocket.h +ArFunctor.h +/usr/local/Aria/include/ArFunctor.h +ariaUtil.h +/usr/local/Aria/include/ariaUtil.h +list +- + +/usr/local/Aria/include/ArNovatelGPS.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArFunctor.h +/usr/local/Aria/include/ArFunctor.h +ariaUtil.h +/usr/local/Aria/include/ariaUtil.h +ArGPS.h +/usr/local/Aria/include/ArGPS.h + +/usr/local/Aria/include/ArP2Arm.h +ArRobot.h +/usr/local/Aria/include/ArRobot.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArSerialConnection.h +/usr/local/Aria/include/ArSerialConnection.h +ariaOSDef.h +/usr/local/Aria/include/ariaOSDef.h + +/usr/local/Aria/include/ArPTZ.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArFunctor.h +/usr/local/Aria/include/ArFunctor.h +ArCommands.h +/usr/local/Aria/include/ArCommands.h +ArPTZConnector.h +/usr/local/Aria/include/ArPTZConnector.h + +/usr/local/Aria/include/ArPTZConnector.h +string +- +vector +- +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ariaUtil.h +/usr/local/Aria/include/ariaUtil.h +ArFunctor.h +/usr/local/Aria/include/ArFunctor.h +ArRobotParams.h +/usr/local/Aria/include/ArRobotParams.h +ariaInternal.h +/usr/local/Aria/include/ariaInternal.h + +/usr/local/Aria/include/ArPriorityResolver.h +ArResolver.h +/usr/local/Aria/include/ArResolver.h + +/usr/local/Aria/include/ArRVisionPTZ.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArBasePacket.h +/usr/local/Aria/include/ArBasePacket.h +ArPTZ.h +/usr/local/Aria/include/ArPTZ.h +ArSerialConnection.h +/usr/local/Aria/include/ArSerialConnection.h + +/usr/local/Aria/include/ArRangeBuffer.h +ariaUtil.h +/usr/local/Aria/include/ariaUtil.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArTransform.h +/usr/local/Aria/include/ArTransform.h +list +- +vector +- + +/usr/local/Aria/include/ArRangeDevice.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArRangeBuffer.h +/usr/local/Aria/include/ArRangeBuffer.h +ArSensorReading.h +/usr/local/Aria/include/ArSensorReading.h +ArDrawingData.h +/usr/local/Aria/include/ArDrawingData.h +ArMutex.h +/usr/local/Aria/include/ArMutex.h +set +- + +/usr/local/Aria/include/ArRangeDeviceThreaded.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArRangeDevice.h +/usr/local/Aria/include/ArRangeDevice.h +ArFunctorASyncTask.h +/usr/local/Aria/include/ArFunctorASyncTask.h + +/usr/local/Aria/include/ArRatioInputJoydrive.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArAction.h +/usr/local/Aria/include/ArAction.h +ArActionRatioInput.h +/usr/local/Aria/include/ArActionRatioInput.h +ArJoyHandler.h +/usr/local/Aria/include/ArJoyHandler.h + +/usr/local/Aria/include/ArRatioInputKeydrive.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArAction.h +/usr/local/Aria/include/ArAction.h +ArFunctor.h +/usr/local/Aria/include/ArFunctor.h +ArActionRatioInput.h +/usr/local/Aria/include/ArActionRatioInput.h + +/usr/local/Aria/include/ArRatioInputRobotJoydrive.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArActionRatioInput.h +/usr/local/Aria/include/ArActionRatioInput.h + +/usr/local/Aria/include/ArRecurrentTask.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArFunctor.h +/usr/local/Aria/include/ArFunctor.h +ArThread.h +/usr/local/Aria/include/ArThread.h +ArASyncTask.h +/usr/local/Aria/include/ArASyncTask.h + +/usr/local/Aria/include/ArResolver.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArActionDesired.h +/usr/local/Aria/include/ArActionDesired.h +string +- + +/usr/local/Aria/include/ArRobot.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArRobotPacketSender.h +/usr/local/Aria/include/ArRobotPacketSender.h +ArRobotPacketReceiver.h +/usr/local/Aria/include/ArRobotPacketReceiver.h +ArFunctor.h +/usr/local/Aria/include/ArFunctor.h +ArFunctor.h +/usr/local/Aria/include/ArFunctor.h +ArSyncTask.h +/usr/local/Aria/include/ArSyncTask.h +ArSensorReading.h +/usr/local/Aria/include/ArSensorReading.h +ArMutex.h +/usr/local/Aria/include/ArMutex.h +ArCondition.h +/usr/local/Aria/include/ArCondition.h +ArSyncLoop.h +/usr/local/Aria/include/ArSyncLoop.h +ArRobotPacketReaderThread.h +/usr/local/Aria/include/ArRobotPacketReaderThread.h +ArRobotParams.h +/usr/local/Aria/include/ArRobotParams.h +ArActionDesired.h +/usr/local/Aria/include/ArActionDesired.h +ArResolver.h +/usr/local/Aria/include/ArResolver.h +ArTransform.h +/usr/local/Aria/include/ArTransform.h +ArInterpolation.h +/usr/local/Aria/include/ArInterpolation.h +ArKeyHandler.h +/usr/local/Aria/include/ArKeyHandler.h +list +- + +/usr/local/Aria/include/ArRobotBatteryPacketReader.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ariaUtil.h +/usr/local/Aria/include/ariaUtil.h +ArFunctor.h +/usr/local/Aria/include/ArFunctor.h + +/usr/local/Aria/include/ArRobotConfig.h +ArFunctor.h +/usr/local/Aria/include/ArFunctor.h + +/usr/local/Aria/include/ArRobotConfigPacketReader.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ariaUtil.h +/usr/local/Aria/include/ariaUtil.h +ArFunctor.h +/usr/local/Aria/include/ArFunctor.h +ArRobotPacket.h +/usr/local/Aria/include/ArRobotPacket.h + +/usr/local/Aria/include/ArRobotConnector.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArSerialConnection.h +/usr/local/Aria/include/ArSerialConnection.h +ArTcpConnection.h +/usr/local/Aria/include/ArTcpConnection.h +ArArgumentBuilder.h +/usr/local/Aria/include/ArArgumentBuilder.h +ArArgumentParser.h +/usr/local/Aria/include/ArArgumentParser.h +ariaUtil.h +/usr/local/Aria/include/ariaUtil.h + +/usr/local/Aria/include/ArRobotJoyHandler.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ariaUtil.h +/usr/local/Aria/include/ariaUtil.h + +/usr/local/Aria/include/ArRobotPacket.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArBasePacket.h +/usr/local/Aria/include/ArBasePacket.h +ariaUtil.h +/usr/local/Aria/include/ariaUtil.h + +/usr/local/Aria/include/ArRobotPacketReaderThread.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArASyncTask.h +/usr/local/Aria/include/ArASyncTask.h + +/usr/local/Aria/include/ArRobotPacketReceiver.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArRobotPacket.h +/usr/local/Aria/include/ArRobotPacket.h + +/usr/local/Aria/include/ArRobotPacketSender.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArRobotPacket.h +/usr/local/Aria/include/ArRobotPacket.h + +/usr/local/Aria/include/ArRobotParams.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArConfig.h +/usr/local/Aria/include/ArConfig.h +vector +- + +/usr/local/Aria/include/ArRobotTypes.h +ariaUtil.h +/usr/local/Aria/include/ariaUtil.h +ArRobotParams.h +/usr/local/Aria/include/ArRobotParams.h + +/usr/local/Aria/include/ArS3Series.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ariaOSDef.h +/usr/local/Aria/include/ariaOSDef.h +ArRobotPacket.h +/usr/local/Aria/include/ArRobotPacket.h +ArLaser.h +/usr/local/Aria/include/ArLaser.h +ArFunctor.h +/usr/local/Aria/include/ArFunctor.h + +/usr/local/Aria/include/ArSZSeries.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ariaOSDef.h +/usr/local/Aria/include/ariaOSDef.h +ArRobotPacket.h +/usr/local/Aria/include/ArRobotPacket.h +ArLaser.h +/usr/local/Aria/include/ArLaser.h +ArFunctor.h +/usr/local/Aria/include/ArFunctor.h + +/usr/local/Aria/include/ArSensorReading.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ariaUtil.h +/usr/local/Aria/include/ariaUtil.h +ArTransform.h +/usr/local/Aria/include/ArTransform.h + +/usr/local/Aria/include/ArSerialConnection.h +string +- +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArDeviceConnection.h +/usr/local/Aria/include/ArDeviceConnection.h + +/usr/local/Aria/include/ArSick.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArRobotPacket.h +/usr/local/Aria/include/ArRobotPacket.h +ArLaser.h +/usr/local/Aria/include/ArLaser.h +ArFunctor.h +/usr/local/Aria/include/ArFunctor.h +ArCondition.h +/usr/local/Aria/include/ArCondition.h +ArLMS2xx.h +/usr/local/Aria/include/ArLMS2xx.h + +/usr/local/Aria/include/ArSignalHandler.h +list +- +signal.h +- +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArASyncTask.h +/usr/local/Aria/include/ArASyncTask.h +ArFunctor.h +/usr/local/Aria/include/ArFunctor.h + +/usr/local/Aria/include/ArSimpleConnector.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArSerialConnection.h +/usr/local/Aria/include/ArSerialConnection.h +ArTcpConnection.h +/usr/local/Aria/include/ArTcpConnection.h +ArArgumentBuilder.h +/usr/local/Aria/include/ArArgumentBuilder.h +ArArgumentParser.h +/usr/local/Aria/include/ArArgumentParser.h +ariaUtil.h +/usr/local/Aria/include/ariaUtil.h +ArRobotConnector.h +/usr/local/Aria/include/ArRobotConnector.h +ArLaserConnector.h +/usr/local/Aria/include/ArLaserConnector.h + +/usr/local/Aria/include/ArSimulatedLaser.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArLaser.h +/usr/local/Aria/include/ArLaser.h + +/usr/local/Aria/include/ArSocket.h +sys/time.h +- +sys/types.h +- +unistd.h +- +sys/types.h +- +sys/socket.h +- +sys/stat.h +- +sys/param.h +- +fcntl.h +- +netinet/in.h +- +stdio.h +- +errno.h +- +stdarg.h +- +string +- +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArMutex.h +/usr/local/Aria/include/ArMutex.h +ariaUtil.h +/usr/local/Aria/include/ariaUtil.h + +/usr/local/Aria/include/ArSonarAutoDisabler.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ariaUtil.h +/usr/local/Aria/include/ariaUtil.h +ArFunctor.h +/usr/local/Aria/include/ArFunctor.h + +/usr/local/Aria/include/ArSonarConnector.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArSerialConnection.h +/usr/local/Aria/include/ArSerialConnection.h +ArTcpConnection.h +/usr/local/Aria/include/ArTcpConnection.h +ArArgumentBuilder.h +/usr/local/Aria/include/ArArgumentBuilder.h +ArArgumentParser.h +/usr/local/Aria/include/ArArgumentParser.h +ariaUtil.h +/usr/local/Aria/include/ariaUtil.h +ArRobotConnector.h +/usr/local/Aria/include/ArRobotConnector.h + +/usr/local/Aria/include/ArSonarDevice.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArRangeDevice.h +/usr/local/Aria/include/ArRangeDevice.h +ArFunctor.h +/usr/local/Aria/include/ArFunctor.h +ArRobot.h +/usr/local/Aria/include/ArRobot.h + +/usr/local/Aria/include/ArSonarMTX.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArRangeDevice.h +/usr/local/Aria/include/ArRangeDevice.h +ArFunctor.h +/usr/local/Aria/include/ArFunctor.h +ArRobot.h +/usr/local/Aria/include/ArRobot.h +ArRobotPacket.h +/usr/local/Aria/include/ArRobotPacket.h + +/usr/local/Aria/include/ArSonyPTZ.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArBasePacket.h +/usr/local/Aria/include/ArBasePacket.h +ArPTZ.h +/usr/local/Aria/include/ArPTZ.h + +/usr/local/Aria/include/ArSoundPlayer.h +ArFunctor.h +/usr/local/Aria/include/ArFunctor.h + +/usr/local/Aria/include/ArSoundsQueue.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArASyncTask.h +/usr/local/Aria/include/ArASyncTask.h +ArCondition.h +/usr/local/Aria/include/ArCondition.h +ArFunctor.h +/usr/local/Aria/include/ArFunctor.h +ArSpeech.h +/usr/local/Aria/include/ArSpeech.h +list +- +string +- +set +- + +/usr/local/Aria/include/ArSpeech.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArFunctor.h +/usr/local/Aria/include/ArFunctor.h +ArConfig.h +/usr/local/Aria/include/ArConfig.h +list +- +string +- + +/usr/local/Aria/include/ArStringInfoGroup.h +ariaUtil.h +/usr/local/Aria/include/ariaUtil.h +ArMutex.h +/usr/local/Aria/include/ArMutex.h +string +- +set +- +list +- + +/usr/local/Aria/include/ArSyncLoop.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArASyncTask.h +/usr/local/Aria/include/ArASyncTask.h +ArSyncTask.h +/usr/local/Aria/include/ArSyncTask.h + +/usr/local/Aria/include/ArSyncTask.h +string +- +map +- +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArFunctor.h +/usr/local/Aria/include/ArFunctor.h +ArTaskState.h +/usr/local/Aria/include/ArTaskState.h + +/usr/local/Aria/include/ArTCM2.h +ariaUtil.h +/usr/local/Aria/include/ariaUtil.h +ArFunctor.h +/usr/local/Aria/include/ArFunctor.h +ArRobot.h +/usr/local/Aria/include/ArRobot.h + +/usr/local/Aria/include/ArTCMCompassDirect.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ariaUtil.h +/usr/local/Aria/include/ariaUtil.h +ArDeviceConnection.h +/usr/local/Aria/include/ArDeviceConnection.h +ArTCM2.h +/usr/local/Aria/include/ArTCM2.h +ArNMEAParser.h +/usr/local/Aria/include/ArNMEAParser.h + +/usr/local/Aria/include/ArTCMCompassRobot.h +ariaUtil.h +/usr/local/Aria/include/ariaUtil.h +ArCommands.h +/usr/local/Aria/include/ArCommands.h +ArFunctor.h +/usr/local/Aria/include/ArFunctor.h +ArRobot.h +/usr/local/Aria/include/ArRobot.h +ArTCM2.h +/usr/local/Aria/include/ArTCM2.h + +/usr/local/Aria/include/ArTaskState.h + +/usr/local/Aria/include/ArTcpConnection.h +ArDeviceConnection.h +/usr/local/Aria/include/ArDeviceConnection.h +string +- +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArSocket.h +/usr/local/Aria/include/ArSocket.h + +/usr/local/Aria/include/ArThread.h +map +- +pthread.h +- +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArMutex.h +/usr/local/Aria/include/ArMutex.h +ArFunctor.h +/usr/local/Aria/include/ArFunctor.h +ArLog.h +/usr/local/Aria/include/ArLog.h +vector +- +map +- + +/usr/local/Aria/include/ArTransform.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ariaUtil.h +/usr/local/Aria/include/ariaUtil.h + +/usr/local/Aria/include/ArTrimbleGPS.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArFunctor.h +/usr/local/Aria/include/ArFunctor.h +ariaUtil.h +/usr/local/Aria/include/ariaUtil.h +ArGPS.h +/usr/local/Aria/include/ArGPS.h +ArDeviceConnection.h +/usr/local/Aria/include/ArDeviceConnection.h +ArMutex.h +/usr/local/Aria/include/ArMutex.h +deque +- + +/usr/local/Aria/include/ArUrg.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArLaser.h +/usr/local/Aria/include/ArLaser.h +ArDeviceConnection.h +/usr/local/Aria/include/ArDeviceConnection.h + +/usr/local/Aria/include/ArUrg_2_0.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArLaser.h +/usr/local/Aria/include/ArLaser.h +ArDeviceConnection.h +/usr/local/Aria/include/ArDeviceConnection.h + +/usr/local/Aria/include/ArVCC4.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArBasePacket.h +/usr/local/Aria/include/ArBasePacket.h +ArPTZ.h +/usr/local/Aria/include/ArPTZ.h +ariaUtil.h +/usr/local/Aria/include/ariaUtil.h +ArCommands.h +/usr/local/Aria/include/ArCommands.h +ArSerialConnection.h +/usr/local/Aria/include/ArSerialConnection.h + +/usr/local/Aria/include/ArVersalogicIO.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArRobot.h +/usr/local/Aria/include/ArRobot.h + +/usr/local/Aria/include/ArZippable.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h + +/usr/local/Aria/include/Aria.h +ariaOSDef.h +/usr/local/Aria/include/ariaOSDef.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArSerialConnection.h +/usr/local/Aria/include/ArSerialConnection.h +ArTcpConnection.h +/usr/local/Aria/include/ArTcpConnection.h +ArSimpleConnector.h +/usr/local/Aria/include/ArSimpleConnector.h +ArLogFileConnection.h +/usr/local/Aria/include/ArLogFileConnection.h +ArLog.h +/usr/local/Aria/include/ArLog.h +ArRobotPacket.h +/usr/local/Aria/include/ArRobotPacket.h +ArRobotPacketSender.h +/usr/local/Aria/include/ArRobotPacketSender.h +ArRobotPacketReceiver.h +/usr/local/Aria/include/ArRobotPacketReceiver.h +ArRobotConfigPacketReader.h +/usr/local/Aria/include/ArRobotConfigPacketReader.h +ArRobotTypes.h +/usr/local/Aria/include/ArRobotTypes.h +ariaUtil.h +/usr/local/Aria/include/ariaUtil.h +ArArgumentBuilder.h +/usr/local/Aria/include/ArArgumentBuilder.h +ArArgumentParser.h +/usr/local/Aria/include/ArArgumentParser.h +ArFileParser.h +/usr/local/Aria/include/ArFileParser.h +ArConfig.h +/usr/local/Aria/include/ArConfig.h +ArConfigArg.h +/usr/local/Aria/include/ArConfigArg.h +ArConfigGroup.h +/usr/local/Aria/include/ArConfigGroup.h +ArRobot.h +/usr/local/Aria/include/ArRobot.h +ArCommands.h +/usr/local/Aria/include/ArCommands.h +ArJoyHandler.h +/usr/local/Aria/include/ArJoyHandler.h +ArSyncTask.h +/usr/local/Aria/include/ArSyncTask.h +ArTaskState.h +/usr/local/Aria/include/ArTaskState.h +ariaInternal.h +/usr/local/Aria/include/ariaInternal.h +ArSonarDevice.h +/usr/local/Aria/include/ArSonarDevice.h +ArPriorityResolver.h +/usr/local/Aria/include/ArPriorityResolver.h +ArAction.h +/usr/local/Aria/include/ArAction.h +ArActionGroup.h +/usr/local/Aria/include/ArActionGroup.h +ArActionGroups.h +/usr/local/Aria/include/ArActionGroups.h +ArActionDeceleratingLimiter.h +/usr/local/Aria/include/ArActionDeceleratingLimiter.h +ArActionLimiterForwards.h +/usr/local/Aria/include/ArActionLimiterForwards.h +ArActionLimiterBackwards.h +/usr/local/Aria/include/ArActionLimiterBackwards.h +ArActionLimiterTableSensor.h +/usr/local/Aria/include/ArActionLimiterTableSensor.h +ArActionBumpers.h +/usr/local/Aria/include/ArActionBumpers.h +ArActionIRs.h +/usr/local/Aria/include/ArActionIRs.h +ArActionStallRecover.h +/usr/local/Aria/include/ArActionStallRecover.h +ArActionAvoidFront.h +/usr/local/Aria/include/ArActionAvoidFront.h +ArActionAvoidSide.h +/usr/local/Aria/include/ArActionAvoidSide.h +ArActionConstantVelocity.h +/usr/local/Aria/include/ArActionConstantVelocity.h +ArActionInput.h +/usr/local/Aria/include/ArActionInput.h +ArActionRobotJoydrive.h +/usr/local/Aria/include/ArActionRobotJoydrive.h +ArActionJoydrive.h +/usr/local/Aria/include/ArActionJoydrive.h +ArActionKeydrive.h +/usr/local/Aria/include/ArActionKeydrive.h +ArActionTriangleDriveTo.h +/usr/local/Aria/include/ArActionTriangleDriveTo.h +ArActionTurn.h +/usr/local/Aria/include/ArActionTurn.h +ArActionRatioInput.h +/usr/local/Aria/include/ArActionRatioInput.h +ArActionStop.h +/usr/local/Aria/include/ArActionStop.h +ArActionGoto.h +/usr/local/Aria/include/ArActionGoto.h +ArModule.h +/usr/local/Aria/include/ArModule.h +ArModuleLoader.h +/usr/local/Aria/include/ArModuleLoader.h +ArRecurrentTask.h +/usr/local/Aria/include/ArRecurrentTask.h +ArInterpolation.h +/usr/local/Aria/include/ArInterpolation.h +ArGripper.h +/usr/local/Aria/include/ArGripper.h +ArSonyPTZ.h +/usr/local/Aria/include/ArSonyPTZ.h +ArRVisionPTZ.h +/usr/local/Aria/include/ArRVisionPTZ.h +ArAMPTU.h +/usr/local/Aria/include/ArAMPTU.h +ArP2Arm.h +/usr/local/Aria/include/ArP2Arm.h +ArACTS.h +/usr/local/Aria/include/ArACTS.h +ArSick.h +/usr/local/Aria/include/ArSick.h +ArLaserLogger.h +/usr/local/Aria/include/ArLaserLogger.h +ArIrrfDevice.h +/usr/local/Aria/include/ArIrrfDevice.h +ArKeyHandler.h +/usr/local/Aria/include/ArKeyHandler.h +ArDPPTU.h +/usr/local/Aria/include/ArDPPTU.h +ArVCC4.h +/usr/local/Aria/include/ArVCC4.h +ArMode.h +/usr/local/Aria/include/ArMode.h +ArModes.h +/usr/local/Aria/include/ArModes.h +ArNetServer.h +/usr/local/Aria/include/ArNetServer.h +ArSignalHandler.h +/usr/local/Aria/include/ArSignalHandler.h +ArAnalogGyro.h +/usr/local/Aria/include/ArAnalogGyro.h +ArMapInterface.h +/usr/local/Aria/include/ArMapInterface.h +ArMapObject.h +/usr/local/Aria/include/ArMapObject.h +ArMap.h +/usr/local/Aria/include/ArMap.h +ArLineFinder.h +/usr/local/Aria/include/ArLineFinder.h +ArBumpers.h +/usr/local/Aria/include/ArBumpers.h +ArIRs.h +/usr/local/Aria/include/ArIRs.h +ArDrawingData.h +/usr/local/Aria/include/ArDrawingData.h +ArForbiddenRangeDevice.h +/usr/local/Aria/include/ArForbiddenRangeDevice.h +ArTCM2.h +/usr/local/Aria/include/ArTCM2.h +ArVersalogicIO.h +/usr/local/Aria/include/ArVersalogicIO.h +ArMTXIO.h +/usr/local/Aria/include/ArMTXIO.h +ArActionGotoStraight.h +/usr/local/Aria/include/ArActionGotoStraight.h +ArDataLogger.h +/usr/local/Aria/include/ArDataLogger.h +ArRobotJoyHandler.h +/usr/local/Aria/include/ArRobotJoyHandler.h +ArRatioInputKeydrive.h +/usr/local/Aria/include/ArRatioInputKeydrive.h +ArRatioInputJoydrive.h +/usr/local/Aria/include/ArRatioInputJoydrive.h +ArRatioInputRobotJoydrive.h +/usr/local/Aria/include/ArRatioInputRobotJoydrive.h +ArActionMovementParameters.h +/usr/local/Aria/include/ArActionMovementParameters.h +ArSoundPlayer.h +/usr/local/Aria/include/ArSoundPlayer.h +ArSoundsQueue.h +/usr/local/Aria/include/ArSoundsQueue.h +ArCameraCollection.h +/usr/local/Aria/include/ArCameraCollection.h +ArCameraCommands.h +/usr/local/Aria/include/ArCameraCommands.h +ArStringInfoGroup.h +/usr/local/Aria/include/ArStringInfoGroup.h +ArSonarAutoDisabler.h +/usr/local/Aria/include/ArSonarAutoDisabler.h +ArActionDriveDistance.h +/usr/local/Aria/include/ArActionDriveDistance.h +ArLaserReflectorDevice.h +/usr/local/Aria/include/ArLaserReflectorDevice.h +ArRobotConfig.h +/usr/local/Aria/include/ArRobotConfig.h +ArTCMCompassRobot.h +/usr/local/Aria/include/ArTCMCompassRobot.h +ArTCMCompassDirect.h +/usr/local/Aria/include/ArTCMCompassDirect.h +ArLaserFilter.h +/usr/local/Aria/include/ArLaserFilter.h +ArUrg.h +/usr/local/Aria/include/ArUrg.h +ArSpeech.h +/usr/local/Aria/include/ArSpeech.h +ArGPS.h +/usr/local/Aria/include/ArGPS.h +ArTrimbleGPS.h +/usr/local/Aria/include/ArTrimbleGPS.h +ArNovatelGPS.h +/usr/local/Aria/include/ArNovatelGPS.h +ArGPSCoords.h +/usr/local/Aria/include/ArGPSCoords.h +ArLaser.h +/usr/local/Aria/include/ArLaser.h +ArRobotConnector.h +/usr/local/Aria/include/ArRobotConnector.h +ArLaserConnector.h +/usr/local/Aria/include/ArLaserConnector.h +ArSonarConnector.h +/usr/local/Aria/include/ArSonarConnector.h +ArBatteryConnector.h +/usr/local/Aria/include/ArBatteryConnector.h +ArLCDConnector.h +/usr/local/Aria/include/ArLCDConnector.h +ArSonarMTX.h +/usr/local/Aria/include/ArSonarMTX.h +ArBatteryMTX.h +/usr/local/Aria/include/ArBatteryMTX.h +ArLCDMTX.h +/usr/local/Aria/include/ArLCDMTX.h +ArSimulatedLaser.h +/usr/local/Aria/include/ArSimulatedLaser.h +ArExitErrorSource.h +/usr/local/Aria/include/ArExitErrorSource.h +ArActionLimiterRot.h +/usr/local/Aria/include/ArActionLimiterRot.h +ArRobotBatteryPacketReader.h +/usr/local/Aria/include/ArRobotBatteryPacketReader.h +ArLMS1XX.h +/usr/local/Aria/include/ArLMS1XX.h +ArUrg_2_0.h +/usr/local/Aria/include/ArUrg_2_0.h +ArActionMovementParametersDebugging.h +/usr/local/Aria/include/ArActionMovementParametersDebugging.h +ArZippable.h +/usr/local/Aria/include/ArZippable.h +ArS3Series.h +/usr/local/Aria/include/ArS3Series.h +ArSZSeries.h +/usr/local/Aria/include/ArSZSeries.h +ArRobotPacketReaderThread.h +/usr/local/Aria/include/ArRobotPacketReaderThread.h +ArHasFileName.h +/usr/local/Aria/include/ArHasFileName.h + +/usr/local/Aria/include/ariaInternal.h +ArMutex.h +/usr/local/Aria/include/ArMutex.h +ArFunctor.h +/usr/local/Aria/include/ArFunctor.h +ArConfig.h +/usr/local/Aria/include/ArConfig.h +ArStringInfoGroup.h +/usr/local/Aria/include/ArStringInfoGroup.h + +/usr/local/Aria/include/ariaOSDef.h +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h + +/usr/local/Aria/include/ariaTypedefs.h +time.h +- +string +- +map +- +list +- +winsock2.h +- +windows.h +- + +/usr/local/Aria/include/ariaUtil.h +string +- +list +- +map +- +math.h +- +stdarg.h +- +stdlib.h +- +limits.h +- +string.h +- +float.h +- +sys/timeb.h +- +sys/stat.h +- +sys/types.h +- +sys/stat.h +- +sys/time.h +- +unistd.h +- +strings.h +- +time.h +- +ariaTypedefs.h +/usr/local/Aria/include/ariaTypedefs.h +ArLog.h +/usr/local/Aria/include/ArLog.h +ArFunctor.h +/usr/local/Aria/include/ArFunctor.h +ArArgumentParser.h +/usr/local/Aria/include/ArArgumentParser.h +ariaOSDef.h +/usr/local/Aria/include/ariaOSDef.h + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/RosAria.dir/DependInfo.cmake b/Legacy/ws_linux/build/rosaria/CMakeFiles/RosAria.dir/DependInfo.cmake new file mode 100644 index 0000000..111026e --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/RosAria.dir/DependInfo.cmake @@ -0,0 +1,21 @@ +# The set of languages for which implicit dependencies are needed: +SET(CMAKE_DEPENDS_LANGUAGES + "CXX" + ) +# The set of files for implicit dependencies of each language: +SET(CMAKE_DEPENDS_CHECK_CXX + "/home/lab1_5/ws/ws_linux/src/rosaria/RosAria.cpp" "/home/lab1_5/ws/ws_linux/build/rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o" + ) +SET(CMAKE_CXX_COMPILER_ID "GNU") + +# Preprocessor definitions for this target. +SET(CMAKE_TARGET_DEFINITIONS + "ROS_BUILD_SHARED_LIBS=1" + "ROS_PACKAGE_NAME=\"rosaria\"" + "ROSCONSOLE_BACKEND_LOG4CXX" + "ADEPT_PKG" + ) + +# Targets to which this target links. +SET(CMAKE_TARGET_LINKED_INFO_FILES + ) diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o b/Legacy/ws_linux/build/rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o new file mode 100644 index 0000000000000000000000000000000000000000..b5d5232eee80df94a187b21e31a9e10866bdf719 GIT binary patch literal 3018152 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
    { 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 zby

    cd>t7b+%?Kf-1G8&DtRvi<d9 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�q{cLg~3C>i-H#eFAnbe>k|Fq^^^uL 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

    *d>s=XHM0^ZtGhYP*vqpWo&0diiDI1)Zny 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%0D1tB1& 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

    ifdgZwXhwBV7HyaP^bm>d$~X-Yeja z_fEL}Pr&tm6|Vkcxccwm>f0{Y7-#hz;OcwA)vpV8yhGuRcQ?5Hzk=(30$lxhaP?Qf z)lY}3e;BU*Ww`qH;g0twxZ_>4dt;pS?*`X@b-4PC;Od9M)sKU#p8!{XEL{EBaL0QM z-0{wU>;E)d|G&c3e+F0o6I}g5JsRVzz9U@yDsc6E;f{A(xZ~XuuK(e1{indyPlc<$ z2Cn`txcbN8>Sw~$e++lLEtYSLr{ir8*S`l`|Fz)iH-W3)7OsAGxcY

    Q98LKM(GB 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]lRoKQ+}4gO5T#5+3w7 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 literal 0 HcmV?d00001 diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/RosAria.dir/build.make b/Legacy/ws_linux/build/rosaria/CMakeFiles/RosAria.dir/build.make new file mode 100644 index 0000000..aaf596b --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/RosAria.dir/build.make @@ -0,0 +1,126 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/lab1_5/ws/ws_linux/src + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/lab1_5/ws/ws_linux/build + +# Include any dependencies generated for this target. +include rosaria/CMakeFiles/RosAria.dir/depend.make + +# Include the progress variables for this target. +include rosaria/CMakeFiles/RosAria.dir/progress.make + +# Include the compile flags for this target's objects. +include rosaria/CMakeFiles/RosAria.dir/flags.make + +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: rosaria/CMakeFiles/RosAria.dir/flags.make +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /home/lab1_5/ws/ws_linux/src/rosaria/RosAria.cpp + $(CMAKE_COMMAND) -E cmake_progress_report /home/lab1_5/ws/ws_linux/build/CMakeFiles $(CMAKE_PROGRESS_1) + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Building CXX object rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o" + cd /home/lab1_5/ws/ws_linux/build/rosaria && /usr/bin/c++ $(CXX_DEFINES) $(CXX_FLAGS) -fPIC -o CMakeFiles/RosAria.dir/RosAria.cpp.o -c /home/lab1_5/ws/ws_linux/src/rosaria/RosAria.cpp + +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing CXX source to CMakeFiles/RosAria.dir/RosAria.cpp.i" + cd /home/lab1_5/ws/ws_linux/build/rosaria && /usr/bin/c++ $(CXX_DEFINES) $(CXX_FLAGS) -fPIC -E /home/lab1_5/ws/ws_linux/src/rosaria/RosAria.cpp > CMakeFiles/RosAria.dir/RosAria.cpp.i + +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling CXX source to assembly CMakeFiles/RosAria.dir/RosAria.cpp.s" + cd /home/lab1_5/ws/ws_linux/build/rosaria && /usr/bin/c++ $(CXX_DEFINES) $(CXX_FLAGS) -fPIC -S /home/lab1_5/ws/ws_linux/src/rosaria/RosAria.cpp -o CMakeFiles/RosAria.dir/RosAria.cpp.s + +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o.requires: +.PHONY : rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o.requires + +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o.provides: rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o.requires + $(MAKE) -f rosaria/CMakeFiles/RosAria.dir/build.make rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o.provides.build +.PHONY : rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o.provides + +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o.provides.build: rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o + +# Object files for target RosAria +RosAria_OBJECTS = \ +"CMakeFiles/RosAria.dir/RosAria.cpp.o" + +# External object files for target RosAria +RosAria_EXTERNAL_OBJECTS = + +/home/lab1_5/ws/ws_linux/devel/lib/rosaria/RosAria: rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o +/home/lab1_5/ws/ws_linux/devel/lib/rosaria/RosAria: /opt/ros/hydro/lib/libtf.so +/home/lab1_5/ws/ws_linux/devel/lib/rosaria/RosAria: /opt/ros/hydro/lib/libtf2_ros.so +/home/lab1_5/ws/ws_linux/devel/lib/rosaria/RosAria: /opt/ros/hydro/lib/libactionlib.so +/home/lab1_5/ws/ws_linux/devel/lib/rosaria/RosAria: /opt/ros/hydro/lib/libmessage_filters.so +/home/lab1_5/ws/ws_linux/devel/lib/rosaria/RosAria: /opt/ros/hydro/lib/libroscpp.so +/home/lab1_5/ws/ws_linux/devel/lib/rosaria/RosAria: /usr/lib/libboost_signals-mt.so +/home/lab1_5/ws/ws_linux/devel/lib/rosaria/RosAria: /usr/lib/libboost_filesystem-mt.so +/home/lab1_5/ws/ws_linux/devel/lib/rosaria/RosAria: /opt/ros/hydro/lib/libxmlrpcpp.so +/home/lab1_5/ws/ws_linux/devel/lib/rosaria/RosAria: /opt/ros/hydro/lib/libtf2.so +/home/lab1_5/ws/ws_linux/devel/lib/rosaria/RosAria: /opt/ros/hydro/lib/librosconsole.so +/home/lab1_5/ws/ws_linux/devel/lib/rosaria/RosAria: /opt/ros/hydro/lib/librosconsole_log4cxx.so +/home/lab1_5/ws/ws_linux/devel/lib/rosaria/RosAria: /opt/ros/hydro/lib/librosconsole_backend_interface.so +/home/lab1_5/ws/ws_linux/devel/lib/rosaria/RosAria: /usr/lib/liblog4cxx.so +/home/lab1_5/ws/ws_linux/devel/lib/rosaria/RosAria: /usr/lib/libboost_regex-mt.so +/home/lab1_5/ws/ws_linux/devel/lib/rosaria/RosAria: /opt/ros/hydro/lib/libdynamic_reconfigure_config_init_mutex.so +/home/lab1_5/ws/ws_linux/devel/lib/rosaria/RosAria: /opt/ros/hydro/lib/libroscpp_serialization.so +/home/lab1_5/ws/ws_linux/devel/lib/rosaria/RosAria: /opt/ros/hydro/lib/librostime.so +/home/lab1_5/ws/ws_linux/devel/lib/rosaria/RosAria: /usr/lib/libboost_date_time-mt.so +/home/lab1_5/ws/ws_linux/devel/lib/rosaria/RosAria: /usr/lib/libboost_system-mt.so +/home/lab1_5/ws/ws_linux/devel/lib/rosaria/RosAria: /usr/lib/libboost_thread-mt.so +/home/lab1_5/ws/ws_linux/devel/lib/rosaria/RosAria: /usr/lib/x86_64-linux-gnu/libpthread.so +/home/lab1_5/ws/ws_linux/devel/lib/rosaria/RosAria: /opt/ros/hydro/lib/libcpp_common.so +/home/lab1_5/ws/ws_linux/devel/lib/rosaria/RosAria: /opt/ros/hydro/lib/libconsole_bridge.so +/home/lab1_5/ws/ws_linux/devel/lib/rosaria/RosAria: /usr/lib/libboost_thread-mt.so +/home/lab1_5/ws/ws_linux/devel/lib/rosaria/RosAria: /usr/lib/x86_64-linux-gnu/libpthread.so +/home/lab1_5/ws/ws_linux/devel/lib/rosaria/RosAria: /opt/ros/hydro/lib/libcpp_common.so +/home/lab1_5/ws/ws_linux/devel/lib/rosaria/RosAria: /opt/ros/hydro/lib/libconsole_bridge.so +/home/lab1_5/ws/ws_linux/devel/lib/rosaria/RosAria: rosaria/CMakeFiles/RosAria.dir/build.make +/home/lab1_5/ws/ws_linux/devel/lib/rosaria/RosAria: rosaria/CMakeFiles/RosAria.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --red --bold "Linking CXX executable /home/lab1_5/ws/ws_linux/devel/lib/rosaria/RosAria" + cd /home/lab1_5/ws/ws_linux/build/rosaria && $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/RosAria.dir/link.txt --verbose=$(VERBOSE) + +# Rule to build all files generated by this target. +rosaria/CMakeFiles/RosAria.dir/build: /home/lab1_5/ws/ws_linux/devel/lib/rosaria/RosAria +.PHONY : rosaria/CMakeFiles/RosAria.dir/build + +rosaria/CMakeFiles/RosAria.dir/requires: rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o.requires +.PHONY : rosaria/CMakeFiles/RosAria.dir/requires + +rosaria/CMakeFiles/RosAria.dir/clean: + cd /home/lab1_5/ws/ws_linux/build/rosaria && $(CMAKE_COMMAND) -P CMakeFiles/RosAria.dir/cmake_clean.cmake +.PHONY : rosaria/CMakeFiles/RosAria.dir/clean + +rosaria/CMakeFiles/RosAria.dir/depend: + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/lab1_5/ws/ws_linux/src /home/lab1_5/ws/ws_linux/src/rosaria /home/lab1_5/ws/ws_linux/build /home/lab1_5/ws/ws_linux/build/rosaria /home/lab1_5/ws/ws_linux/build/rosaria/CMakeFiles/RosAria.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : rosaria/CMakeFiles/RosAria.dir/depend + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/RosAria.dir/cmake_clean.cmake b/Legacy/ws_linux/build/rosaria/CMakeFiles/RosAria.dir/cmake_clean.cmake new file mode 100644 index 0000000..941f843 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/RosAria.dir/cmake_clean.cmake @@ -0,0 +1,10 @@ +FILE(REMOVE_RECURSE + "CMakeFiles/RosAria.dir/RosAria.cpp.o" + "/home/lab1_5/ws/ws_linux/devel/lib/rosaria/RosAria.pdb" + "/home/lab1_5/ws/ws_linux/devel/lib/rosaria/RosAria" +) + +# Per-language clean rules from dependency scanning. +FOREACH(lang CXX) + INCLUDE(CMakeFiles/RosAria.dir/cmake_clean_${lang}.cmake OPTIONAL) +ENDFOREACH(lang) diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/RosAria.dir/depend.internal b/Legacy/ws_linux/build/rosaria/CMakeFiles/RosAria.dir/depend.internal new file mode 100644 index 0000000..45a50b4 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/RosAria.dir/depend.internal @@ -0,0 +1,302 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o + /home/lab1_5/ws/ws_linux/devel/include/rosaria/BumperState.h + /home/lab1_5/ws/ws_linux/devel/include/rosaria/RosAriaConfig.h + /home/lab1_5/ws/ws_linux/devel/include/rosaria_msgs/RestrictionsMsg.h + /home/lab1_5/ws/ws_linux/devel/include/rosaria_msgs/RobotInfoMsg.h + /home/lab1_5/ws/ws_linux/src/rosaria/RosAria.cpp + /opt/ros/hydro/include/XmlRpcDecl.h + /opt/ros/hydro/include/XmlRpcValue.h + /opt/ros/hydro/include/dynamic_reconfigure/BoolParameter.h + /opt/ros/hydro/include/dynamic_reconfigure/Config.h + /opt/ros/hydro/include/dynamic_reconfigure/ConfigDescription.h + /opt/ros/hydro/include/dynamic_reconfigure/DoubleParameter.h + /opt/ros/hydro/include/dynamic_reconfigure/Group.h + /opt/ros/hydro/include/dynamic_reconfigure/GroupState.h + /opt/ros/hydro/include/dynamic_reconfigure/IntParameter.h + /opt/ros/hydro/include/dynamic_reconfigure/ParamDescription.h + /opt/ros/hydro/include/dynamic_reconfigure/Reconfigure.h + /opt/ros/hydro/include/dynamic_reconfigure/ReconfigureRequest.h + /opt/ros/hydro/include/dynamic_reconfigure/ReconfigureResponse.h + /opt/ros/hydro/include/dynamic_reconfigure/StrParameter.h + /opt/ros/hydro/include/dynamic_reconfigure/config_init_mutex.h + /opt/ros/hydro/include/dynamic_reconfigure/config_tools.h + /opt/ros/hydro/include/dynamic_reconfigure/server.h + /opt/ros/hydro/include/geometry_msgs/Point.h + /opt/ros/hydro/include/geometry_msgs/Point32.h + /opt/ros/hydro/include/geometry_msgs/PointStamped.h + /opt/ros/hydro/include/geometry_msgs/Pose.h + /opt/ros/hydro/include/geometry_msgs/PoseStamped.h + /opt/ros/hydro/include/geometry_msgs/PoseWithCovariance.h + /opt/ros/hydro/include/geometry_msgs/Quaternion.h + /opt/ros/hydro/include/geometry_msgs/QuaternionStamped.h + /opt/ros/hydro/include/geometry_msgs/Transform.h + /opt/ros/hydro/include/geometry_msgs/TransformStamped.h + /opt/ros/hydro/include/geometry_msgs/Twist.h + /opt/ros/hydro/include/geometry_msgs/TwistStamped.h + /opt/ros/hydro/include/geometry_msgs/TwistWithCovariance.h + /opt/ros/hydro/include/geometry_msgs/Vector3.h + /opt/ros/hydro/include/geometry_msgs/Vector3Stamped.h + /opt/ros/hydro/include/nav_msgs/Odometry.h + /opt/ros/hydro/include/ros/advertise_options.h + /opt/ros/hydro/include/ros/advertise_service_options.h + /opt/ros/hydro/include/ros/assert.h + /opt/ros/hydro/include/ros/builtin_message_traits.h + /opt/ros/hydro/include/ros/callback_queue.h + /opt/ros/hydro/include/ros/callback_queue_interface.h + /opt/ros/hydro/include/ros/common.h + /opt/ros/hydro/include/ros/console.h + /opt/ros/hydro/include/ros/console_backend.h + /opt/ros/hydro/include/ros/datatypes.h + /opt/ros/hydro/include/ros/duration.h + /opt/ros/hydro/include/ros/exception.h + /opt/ros/hydro/include/ros/exceptions.h + /opt/ros/hydro/include/ros/forwards.h + /opt/ros/hydro/include/ros/init.h + /opt/ros/hydro/include/ros/macros.h + /opt/ros/hydro/include/ros/master.h + /opt/ros/hydro/include/ros/message.h + /opt/ros/hydro/include/ros/message_event.h + /opt/ros/hydro/include/ros/message_forward.h + /opt/ros/hydro/include/ros/message_operations.h + /opt/ros/hydro/include/ros/message_traits.h + /opt/ros/hydro/include/ros/names.h + /opt/ros/hydro/include/ros/node_handle.h + /opt/ros/hydro/include/ros/param.h + /opt/ros/hydro/include/ros/parameter_adapter.h + /opt/ros/hydro/include/ros/platform.h + /opt/ros/hydro/include/ros/publisher.h + /opt/ros/hydro/include/ros/rate.h + /opt/ros/hydro/include/ros/ros.h + /opt/ros/hydro/include/ros/roscpp_serialization_macros.h + /opt/ros/hydro/include/ros/rostime_decl.h + /opt/ros/hydro/include/ros/serialization.h + /opt/ros/hydro/include/ros/serialized_message.h + /opt/ros/hydro/include/ros/service.h + /opt/ros/hydro/include/ros/service_callback_helper.h + /opt/ros/hydro/include/ros/service_client.h + /opt/ros/hydro/include/ros/service_client_options.h + /opt/ros/hydro/include/ros/service_server.h + /opt/ros/hydro/include/ros/service_traits.h + /opt/ros/hydro/include/ros/single_subscriber_publisher.h + /opt/ros/hydro/include/ros/spinner.h + /opt/ros/hydro/include/ros/static_assert.h + /opt/ros/hydro/include/ros/subscribe_options.h + /opt/ros/hydro/include/ros/subscriber.h + /opt/ros/hydro/include/ros/subscription_callback_helper.h + /opt/ros/hydro/include/ros/this_node.h + /opt/ros/hydro/include/ros/time.h + /opt/ros/hydro/include/ros/timer.h + /opt/ros/hydro/include/ros/timer_options.h + /opt/ros/hydro/include/ros/topic.h + /opt/ros/hydro/include/ros/transport_hints.h + /opt/ros/hydro/include/ros/types.h + /opt/ros/hydro/include/ros/wall_timer.h + /opt/ros/hydro/include/ros/wall_timer_options.h + /opt/ros/hydro/include/rosconsole/macros_generated.h + /opt/ros/hydro/include/sensor_msgs/ChannelFloat32.h + /opt/ros/hydro/include/sensor_msgs/JointState.h + /opt/ros/hydro/include/sensor_msgs/PointCloud.h + /opt/ros/hydro/include/sensor_msgs/PointCloud2.h + /opt/ros/hydro/include/sensor_msgs/PointField.h + /opt/ros/hydro/include/sensor_msgs/point_cloud_conversion.h + /opt/ros/hydro/include/std_msgs/Bool.h + /opt/ros/hydro/include/std_msgs/Empty.h + /opt/ros/hydro/include/std_msgs/Float32.h + /opt/ros/hydro/include/std_msgs/Float64.h + /opt/ros/hydro/include/std_msgs/Header.h + /opt/ros/hydro/include/std_msgs/Int8.h + /opt/ros/hydro/include/std_msgs/UInt8.h + /opt/ros/hydro/include/std_srvs/Empty.h + /opt/ros/hydro/include/std_srvs/EmptyRequest.h + /opt/ros/hydro/include/std_srvs/EmptyResponse.h + /opt/ros/hydro/include/tf/FrameGraph.h + /opt/ros/hydro/include/tf/FrameGraphRequest.h + /opt/ros/hydro/include/tf/FrameGraphResponse.h + /opt/ros/hydro/include/tf/LinearMath/Matrix3x3.h + /opt/ros/hydro/include/tf/LinearMath/MinMax.h + /opt/ros/hydro/include/tf/LinearMath/QuadWord.h + /opt/ros/hydro/include/tf/LinearMath/Quaternion.h + /opt/ros/hydro/include/tf/LinearMath/Scalar.h + /opt/ros/hydro/include/tf/LinearMath/Transform.h + /opt/ros/hydro/include/tf/LinearMath/Vector3.h + /opt/ros/hydro/include/tf/exceptions.h + /opt/ros/hydro/include/tf/tf.h + /opt/ros/hydro/include/tf/tfMessage.h + /opt/ros/hydro/include/tf/time_cache.h + /opt/ros/hydro/include/tf/transform_broadcaster.h + /opt/ros/hydro/include/tf/transform_datatypes.h + /opt/ros/hydro/include/tf/transform_listener.h + /opt/ros/hydro/include/tf2/LinearMath/Quaternion.h + /opt/ros/hydro/include/tf2/LinearMath/Vector3.h + /opt/ros/hydro/include/tf2/buffer_core.h + /opt/ros/hydro/include/tf2/convert.h + /opt/ros/hydro/include/tf2/exceptions.h + /opt/ros/hydro/include/tf2/transform_datatypes.h + /opt/ros/hydro/include/tf2/transform_storage.h + /opt/ros/hydro/include/tf2_msgs/FrameGraph.h + /opt/ros/hydro/include/tf2_msgs/FrameGraphRequest.h + /opt/ros/hydro/include/tf2_msgs/FrameGraphResponse.h + /opt/ros/hydro/include/tf2_msgs/TFMessage.h + /opt/ros/hydro/include/tf2_ros/buffer.h + /opt/ros/hydro/include/tf2_ros/buffer_interface.h + /opt/ros/hydro/include/tf2_ros/transform_broadcaster.h + /opt/ros/hydro/include/tf2_ros/transform_listener.h + /usr/local/Aria/include/ArACTS.h + /usr/local/Aria/include/ArAMPTU.h + /usr/local/Aria/include/ArASyncTask.h + /usr/local/Aria/include/ArAction.h + /usr/local/Aria/include/ArActionAvoidFront.h + /usr/local/Aria/include/ArActionAvoidSide.h + /usr/local/Aria/include/ArActionBumpers.h + /usr/local/Aria/include/ArActionColorFollow.h + /usr/local/Aria/include/ArActionConstantVelocity.h + /usr/local/Aria/include/ArActionDeceleratingLimiter.h + /usr/local/Aria/include/ArActionDesired.h + /usr/local/Aria/include/ArActionDriveDistance.h + /usr/local/Aria/include/ArActionGoto.h + /usr/local/Aria/include/ArActionGotoStraight.h + /usr/local/Aria/include/ArActionGroup.h + /usr/local/Aria/include/ArActionGroups.h + /usr/local/Aria/include/ArActionIRs.h + /usr/local/Aria/include/ArActionInput.h + /usr/local/Aria/include/ArActionJoydrive.h + /usr/local/Aria/include/ArActionKeydrive.h + /usr/local/Aria/include/ArActionLimiterBackwards.h + /usr/local/Aria/include/ArActionLimiterForwards.h + /usr/local/Aria/include/ArActionLimiterRot.h + /usr/local/Aria/include/ArActionLimiterTableSensor.h + /usr/local/Aria/include/ArActionMovementParameters.h + /usr/local/Aria/include/ArActionMovementParametersDebugging.h + /usr/local/Aria/include/ArActionRatioInput.h + /usr/local/Aria/include/ArActionRobotJoydrive.h + /usr/local/Aria/include/ArActionStallRecover.h + /usr/local/Aria/include/ArActionStop.h + /usr/local/Aria/include/ArActionTriangleDriveTo.h + /usr/local/Aria/include/ArActionTurn.h + /usr/local/Aria/include/ArAnalogGyro.h + /usr/local/Aria/include/ArArg.h + /usr/local/Aria/include/ArArgumentBuilder.h + /usr/local/Aria/include/ArArgumentParser.h + /usr/local/Aria/include/ArBasePacket.h + /usr/local/Aria/include/ArBatteryConnector.h + /usr/local/Aria/include/ArBatteryMTX.h + /usr/local/Aria/include/ArBumpers.h + /usr/local/Aria/include/ArCameraCollection.h + /usr/local/Aria/include/ArCameraCommands.h + /usr/local/Aria/include/ArCommands.h + /usr/local/Aria/include/ArCondition.h + /usr/local/Aria/include/ArConfig.h + /usr/local/Aria/include/ArConfigArg.h + /usr/local/Aria/include/ArConfigGroup.h + /usr/local/Aria/include/ArDPPTU.h + /usr/local/Aria/include/ArDataLogger.h + /usr/local/Aria/include/ArDeviceConnection.h + /usr/local/Aria/include/ArDrawingData.h + /usr/local/Aria/include/ArExitErrorSource.h + /usr/local/Aria/include/ArFileParser.h + /usr/local/Aria/include/ArForbiddenRangeDevice.h + /usr/local/Aria/include/ArFunctor.h + /usr/local/Aria/include/ArFunctorASyncTask.h + /usr/local/Aria/include/ArGPS.h + /usr/local/Aria/include/ArGPSCoords.h + /usr/local/Aria/include/ArGripper.h + /usr/local/Aria/include/ArHasFileName.h + /usr/local/Aria/include/ArIRs.h + /usr/local/Aria/include/ArInterpolation.h + /usr/local/Aria/include/ArIrrfDevice.h + /usr/local/Aria/include/ArJoyHandler.h + /usr/local/Aria/include/ArKeyHandler.h + /usr/local/Aria/include/ArLCDConnector.h + /usr/local/Aria/include/ArLCDMTX.h + /usr/local/Aria/include/ArLMS1XX.h + /usr/local/Aria/include/ArLMS2xx.h + /usr/local/Aria/include/ArLMS2xxPacket.h + /usr/local/Aria/include/ArLMS2xxPacketReceiver.h + /usr/local/Aria/include/ArLaser.h + /usr/local/Aria/include/ArLaserConnector.h + /usr/local/Aria/include/ArLaserFilter.h + /usr/local/Aria/include/ArLaserLogger.h + /usr/local/Aria/include/ArLaserReflectorDevice.h + /usr/local/Aria/include/ArLineFinder.h + /usr/local/Aria/include/ArLog.h + /usr/local/Aria/include/ArLogFileConnection.h + /usr/local/Aria/include/ArMTXIO.h + /usr/local/Aria/include/ArMap.h + /usr/local/Aria/include/ArMapComponents.h + /usr/local/Aria/include/ArMapInterface.h + /usr/local/Aria/include/ArMapObject.h + /usr/local/Aria/include/ArMapUtils.h + /usr/local/Aria/include/ArMode.h + /usr/local/Aria/include/ArModes.h + /usr/local/Aria/include/ArModule.h + /usr/local/Aria/include/ArModuleLoader.h + /usr/local/Aria/include/ArMutex.h + /usr/local/Aria/include/ArNMEAParser.h + /usr/local/Aria/include/ArNetServer.h + /usr/local/Aria/include/ArNovatelGPS.h + /usr/local/Aria/include/ArP2Arm.h + /usr/local/Aria/include/ArPTZ.h + /usr/local/Aria/include/ArPTZConnector.h + /usr/local/Aria/include/ArPriorityResolver.h + /usr/local/Aria/include/ArRVisionPTZ.h + /usr/local/Aria/include/ArRangeBuffer.h + /usr/local/Aria/include/ArRangeDevice.h + /usr/local/Aria/include/ArRangeDeviceThreaded.h + /usr/local/Aria/include/ArRatioInputJoydrive.h + /usr/local/Aria/include/ArRatioInputKeydrive.h + /usr/local/Aria/include/ArRatioInputRobotJoydrive.h + /usr/local/Aria/include/ArRecurrentTask.h + /usr/local/Aria/include/ArResolver.h + /usr/local/Aria/include/ArRobot.h + /usr/local/Aria/include/ArRobotBatteryPacketReader.h + /usr/local/Aria/include/ArRobotConfig.h + /usr/local/Aria/include/ArRobotConfigPacketReader.h + /usr/local/Aria/include/ArRobotConnector.h + /usr/local/Aria/include/ArRobotJoyHandler.h + /usr/local/Aria/include/ArRobotPacket.h + /usr/local/Aria/include/ArRobotPacketReaderThread.h + /usr/local/Aria/include/ArRobotPacketReceiver.h + /usr/local/Aria/include/ArRobotPacketSender.h + /usr/local/Aria/include/ArRobotParams.h + /usr/local/Aria/include/ArRobotTypes.h + /usr/local/Aria/include/ArS3Series.h + /usr/local/Aria/include/ArSZSeries.h + /usr/local/Aria/include/ArSensorReading.h + /usr/local/Aria/include/ArSerialConnection.h + /usr/local/Aria/include/ArSick.h + /usr/local/Aria/include/ArSignalHandler.h + /usr/local/Aria/include/ArSimpleConnector.h + /usr/local/Aria/include/ArSimulatedLaser.h + /usr/local/Aria/include/ArSocket.h + /usr/local/Aria/include/ArSonarAutoDisabler.h + /usr/local/Aria/include/ArSonarConnector.h + /usr/local/Aria/include/ArSonarDevice.h + /usr/local/Aria/include/ArSonarMTX.h + /usr/local/Aria/include/ArSonyPTZ.h + /usr/local/Aria/include/ArSoundPlayer.h + /usr/local/Aria/include/ArSoundsQueue.h + /usr/local/Aria/include/ArSpeech.h + /usr/local/Aria/include/ArStringInfoGroup.h + /usr/local/Aria/include/ArSyncLoop.h + /usr/local/Aria/include/ArSyncTask.h + /usr/local/Aria/include/ArTCM2.h + /usr/local/Aria/include/ArTCMCompassDirect.h + /usr/local/Aria/include/ArTCMCompassRobot.h + /usr/local/Aria/include/ArTaskState.h + /usr/local/Aria/include/ArTcpConnection.h + /usr/local/Aria/include/ArThread.h + /usr/local/Aria/include/ArTransform.h + /usr/local/Aria/include/ArTrimbleGPS.h + /usr/local/Aria/include/ArUrg.h + /usr/local/Aria/include/ArUrg_2_0.h + /usr/local/Aria/include/ArVCC4.h + /usr/local/Aria/include/ArVersalogicIO.h + /usr/local/Aria/include/ArZippable.h + /usr/local/Aria/include/Aria.h + /usr/local/Aria/include/ariaInternal.h + /usr/local/Aria/include/ariaOSDef.h + /usr/local/Aria/include/ariaTypedefs.h + /usr/local/Aria/include/ariaUtil.h diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/RosAria.dir/depend.make b/Legacy/ws_linux/build/rosaria/CMakeFiles/RosAria.dir/depend.make new file mode 100644 index 0000000..4f21a21 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/RosAria.dir/depend.make @@ -0,0 +1,302 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /home/lab1_5/ws/ws_linux/devel/include/rosaria/BumperState.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /home/lab1_5/ws/ws_linux/devel/include/rosaria/RosAriaConfig.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /home/lab1_5/ws/ws_linux/devel/include/rosaria_msgs/RestrictionsMsg.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /home/lab1_5/ws/ws_linux/devel/include/rosaria_msgs/RobotInfoMsg.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /home/lab1_5/ws/ws_linux/src/rosaria/RosAria.cpp +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/XmlRpcDecl.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/XmlRpcValue.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/dynamic_reconfigure/BoolParameter.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/dynamic_reconfigure/Config.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/dynamic_reconfigure/ConfigDescription.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/dynamic_reconfigure/DoubleParameter.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/dynamic_reconfigure/Group.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/dynamic_reconfigure/GroupState.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/dynamic_reconfigure/IntParameter.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/dynamic_reconfigure/ParamDescription.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/dynamic_reconfigure/Reconfigure.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/dynamic_reconfigure/ReconfigureRequest.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/dynamic_reconfigure/ReconfigureResponse.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/dynamic_reconfigure/StrParameter.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/dynamic_reconfigure/config_init_mutex.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/dynamic_reconfigure/config_tools.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/dynamic_reconfigure/server.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/geometry_msgs/Point.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/geometry_msgs/Point32.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/geometry_msgs/PointStamped.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/geometry_msgs/Pose.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/geometry_msgs/PoseStamped.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/geometry_msgs/PoseWithCovariance.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/geometry_msgs/Quaternion.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/geometry_msgs/QuaternionStamped.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/geometry_msgs/Transform.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/geometry_msgs/TransformStamped.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/geometry_msgs/Twist.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/geometry_msgs/TwistStamped.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/geometry_msgs/TwistWithCovariance.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/geometry_msgs/Vector3.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/geometry_msgs/Vector3Stamped.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/nav_msgs/Odometry.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/ros/advertise_options.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/ros/advertise_service_options.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/ros/assert.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/ros/builtin_message_traits.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/ros/callback_queue.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/ros/callback_queue_interface.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/ros/common.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/ros/console.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/ros/console_backend.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/ros/datatypes.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/ros/duration.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/ros/exception.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/ros/exceptions.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/ros/forwards.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/ros/init.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/ros/macros.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/ros/master.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/ros/message.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/ros/message_event.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/ros/message_forward.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/ros/message_operations.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/ros/message_traits.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/ros/names.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/ros/node_handle.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/ros/param.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/ros/parameter_adapter.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/ros/platform.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/ros/publisher.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/ros/rate.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/ros/ros.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/ros/roscpp_serialization_macros.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/ros/rostime_decl.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/ros/serialization.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/ros/serialized_message.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/ros/service.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/ros/service_callback_helper.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/ros/service_client.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/ros/service_client_options.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/ros/service_server.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/ros/service_traits.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/ros/single_subscriber_publisher.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/ros/spinner.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/ros/static_assert.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/ros/subscribe_options.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/ros/subscriber.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/ros/subscription_callback_helper.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/ros/this_node.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/ros/time.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/ros/timer.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/ros/timer_options.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/ros/topic.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/ros/transport_hints.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/ros/types.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/ros/wall_timer.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/ros/wall_timer_options.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/rosconsole/macros_generated.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/sensor_msgs/ChannelFloat32.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/sensor_msgs/JointState.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/sensor_msgs/PointCloud.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/sensor_msgs/PointCloud2.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/sensor_msgs/PointField.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/sensor_msgs/point_cloud_conversion.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/std_msgs/Bool.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/std_msgs/Empty.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/std_msgs/Float32.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/std_msgs/Float64.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/std_msgs/Header.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/std_msgs/Int8.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/std_msgs/UInt8.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/std_srvs/Empty.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/std_srvs/EmptyRequest.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/std_srvs/EmptyResponse.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/tf/FrameGraph.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/tf/FrameGraphRequest.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/tf/FrameGraphResponse.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/tf/LinearMath/Matrix3x3.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/tf/LinearMath/MinMax.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/tf/LinearMath/QuadWord.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/tf/LinearMath/Quaternion.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/tf/LinearMath/Scalar.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/tf/LinearMath/Transform.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/tf/LinearMath/Vector3.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/tf/exceptions.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/tf/tf.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/tf/tfMessage.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/tf/time_cache.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/tf/transform_broadcaster.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/tf/transform_datatypes.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/tf/transform_listener.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/tf2/LinearMath/Quaternion.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/tf2/LinearMath/Vector3.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/tf2/buffer_core.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/tf2/convert.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/tf2/exceptions.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/tf2/transform_datatypes.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/tf2/transform_storage.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/tf2_msgs/FrameGraph.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/tf2_msgs/FrameGraphRequest.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/tf2_msgs/FrameGraphResponse.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/tf2_msgs/TFMessage.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/tf2_ros/buffer.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/tf2_ros/buffer_interface.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/tf2_ros/transform_broadcaster.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /opt/ros/hydro/include/tf2_ros/transform_listener.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArACTS.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArAMPTU.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArASyncTask.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArAction.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArActionAvoidFront.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArActionAvoidSide.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArActionBumpers.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArActionColorFollow.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArActionConstantVelocity.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArActionDeceleratingLimiter.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArActionDesired.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArActionDriveDistance.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArActionGoto.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArActionGotoStraight.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArActionGroup.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArActionGroups.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArActionIRs.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArActionInput.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArActionJoydrive.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArActionKeydrive.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArActionLimiterBackwards.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArActionLimiterForwards.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArActionLimiterRot.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArActionLimiterTableSensor.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArActionMovementParameters.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArActionMovementParametersDebugging.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArActionRatioInput.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArActionRobotJoydrive.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArActionStallRecover.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArActionStop.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArActionTriangleDriveTo.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArActionTurn.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArAnalogGyro.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArArg.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArArgumentBuilder.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArArgumentParser.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArBasePacket.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArBatteryConnector.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArBatteryMTX.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArBumpers.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArCameraCollection.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArCameraCommands.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArCommands.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArCondition.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArConfig.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArConfigArg.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArConfigGroup.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArDPPTU.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArDataLogger.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArDeviceConnection.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArDrawingData.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArExitErrorSource.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArFileParser.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArForbiddenRangeDevice.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArFunctor.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArFunctorASyncTask.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArGPS.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArGPSCoords.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArGripper.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArHasFileName.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArIRs.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArInterpolation.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArIrrfDevice.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArJoyHandler.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArKeyHandler.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArLCDConnector.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArLCDMTX.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArLMS1XX.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArLMS2xx.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArLMS2xxPacket.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArLMS2xxPacketReceiver.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArLaser.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArLaserConnector.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArLaserFilter.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArLaserLogger.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArLaserReflectorDevice.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArLineFinder.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArLog.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArLogFileConnection.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArMTXIO.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArMap.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArMapComponents.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArMapInterface.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArMapObject.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArMapUtils.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArMode.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArModes.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArModule.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArModuleLoader.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArMutex.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArNMEAParser.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArNetServer.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArNovatelGPS.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArP2Arm.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArPTZ.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArPTZConnector.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArPriorityResolver.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArRVisionPTZ.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArRangeBuffer.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArRangeDevice.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArRangeDeviceThreaded.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArRatioInputJoydrive.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArRatioInputKeydrive.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArRatioInputRobotJoydrive.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArRecurrentTask.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArResolver.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArRobot.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArRobotBatteryPacketReader.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArRobotConfig.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArRobotConfigPacketReader.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArRobotConnector.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArRobotJoyHandler.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArRobotPacket.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArRobotPacketReaderThread.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArRobotPacketReceiver.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArRobotPacketSender.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArRobotParams.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArRobotTypes.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArS3Series.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArSZSeries.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArSensorReading.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArSerialConnection.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArSick.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArSignalHandler.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArSimpleConnector.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArSimulatedLaser.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArSocket.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArSonarAutoDisabler.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArSonarConnector.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArSonarDevice.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArSonarMTX.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArSonyPTZ.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArSoundPlayer.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArSoundsQueue.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArSpeech.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArStringInfoGroup.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArSyncLoop.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArSyncTask.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArTCM2.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArTCMCompassDirect.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArTCMCompassRobot.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArTaskState.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArTcpConnection.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArThread.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArTransform.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArTrimbleGPS.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArUrg.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArUrg_2_0.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArVCC4.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArVersalogicIO.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ArZippable.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/Aria.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ariaInternal.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ariaOSDef.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ariaTypedefs.h +rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o: /usr/local/Aria/include/ariaUtil.h + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/RosAria.dir/flags.make b/Legacy/ws_linux/build/rosaria/CMakeFiles/RosAria.dir/flags.make new file mode 100644 index 0000000..e758f3f --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/RosAria.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +# compile CXX with /usr/bin/c++ +CXX_FLAGS = -I/home/lab1_5/ws/ws_linux/devel/include -I/opt/ros/hydro/include -I/usr/local/Aria/include + +CXX_DEFINES = -DROS_BUILD_SHARED_LIBS=1 -DROS_PACKAGE_NAME=\"rosaria\" -DROSCONSOLE_BACKEND_LOG4CXX -DADEPT_PKG + +# TARGET_FLAGS = -fPIC + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/RosAria.dir/link.txt b/Legacy/ws_linux/build/rosaria/CMakeFiles/RosAria.dir/link.txt new file mode 100644 index 0000000..c6dc19b --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/RosAria.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ CMakeFiles/RosAria.dir/RosAria.cpp.o -o /home/lab1_5/ws/ws_linux/devel/lib/rosaria/RosAria -rdynamic -L/usr/local/Aria/lib /opt/ros/hydro/lib/libtf.so /opt/ros/hydro/lib/libtf2_ros.so /opt/ros/hydro/lib/libactionlib.so /opt/ros/hydro/lib/libmessage_filters.so /opt/ros/hydro/lib/libroscpp.so -lboost_signals-mt -lboost_filesystem-mt /opt/ros/hydro/lib/libxmlrpcpp.so /opt/ros/hydro/lib/libtf2.so /opt/ros/hydro/lib/librosconsole.so /opt/ros/hydro/lib/librosconsole_log4cxx.so /opt/ros/hydro/lib/librosconsole_backend_interface.so -llog4cxx -lboost_regex-mt /opt/ros/hydro/lib/libdynamic_reconfigure_config_init_mutex.so /opt/ros/hydro/lib/libroscpp_serialization.so /opt/ros/hydro/lib/librostime.so -lboost_date_time-mt -lboost_system-mt -lboost_thread-mt -lpthread /opt/ros/hydro/lib/libcpp_common.so /opt/ros/hydro/lib/libconsole_bridge.so -lboost_thread-mt -lpthread -lAria -lpthread -ldl -lrt -lpthread /opt/ros/hydro/lib/libcpp_common.so /opt/ros/hydro/lib/libconsole_bridge.so -lpthread -lAria -lpthread -lAria -ldl -lrt -Wl,-rpath,/usr/local/Aria/lib:/opt/ros/hydro/lib: diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/RosAria.dir/progress.make b/Legacy/ws_linux/build/rosaria/CMakeFiles/RosAria.dir/progress.make new file mode 100644 index 0000000..781c7de --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/RosAria.dir/progress.make @@ -0,0 +1,2 @@ +CMAKE_PROGRESS_1 = 1 + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_generate_messages_cpp.dir/DependInfo.cmake b/Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_generate_messages_cpp.dir/DependInfo.cmake new file mode 100644 index 0000000..85f8501 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_generate_messages_cpp.dir/DependInfo.cmake @@ -0,0 +1,16 @@ +# The set of languages for which implicit dependencies are needed: +SET(CMAKE_DEPENDS_LANGUAGES + ) +# The set of files for implicit dependencies of each language: + +# Preprocessor definitions for this target. +SET(CMAKE_TARGET_DEFINITIONS + "ROS_BUILD_SHARED_LIBS=1" + "ROS_PACKAGE_NAME=\"rosaria\"" + "ROSCONSOLE_BACKEND_LOG4CXX" + "ADEPT_PKG" + ) + +# Targets to which this target links. +SET(CMAKE_TARGET_LINKED_INFO_FILES + ) diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_generate_messages_cpp.dir/build.make b/Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_generate_messages_cpp.dir/build.make new file mode 100644 index 0000000..c67a88c --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_generate_messages_cpp.dir/build.make @@ -0,0 +1,62 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/lab1_5/ws/ws_linux/src + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/lab1_5/ws/ws_linux/build + +# Utility rule file for actionlib_generate_messages_cpp. + +# Include the progress variables for this target. +include rosaria/CMakeFiles/actionlib_generate_messages_cpp.dir/progress.make + +rosaria/CMakeFiles/actionlib_generate_messages_cpp: + +actionlib_generate_messages_cpp: rosaria/CMakeFiles/actionlib_generate_messages_cpp +actionlib_generate_messages_cpp: rosaria/CMakeFiles/actionlib_generate_messages_cpp.dir/build.make +.PHONY : actionlib_generate_messages_cpp + +# Rule to build all files generated by this target. +rosaria/CMakeFiles/actionlib_generate_messages_cpp.dir/build: actionlib_generate_messages_cpp +.PHONY : rosaria/CMakeFiles/actionlib_generate_messages_cpp.dir/build + +rosaria/CMakeFiles/actionlib_generate_messages_cpp.dir/clean: + cd /home/lab1_5/ws/ws_linux/build/rosaria && $(CMAKE_COMMAND) -P CMakeFiles/actionlib_generate_messages_cpp.dir/cmake_clean.cmake +.PHONY : rosaria/CMakeFiles/actionlib_generate_messages_cpp.dir/clean + +rosaria/CMakeFiles/actionlib_generate_messages_cpp.dir/depend: + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/lab1_5/ws/ws_linux/src /home/lab1_5/ws/ws_linux/src/rosaria /home/lab1_5/ws/ws_linux/build /home/lab1_5/ws/ws_linux/build/rosaria /home/lab1_5/ws/ws_linux/build/rosaria/CMakeFiles/actionlib_generate_messages_cpp.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : rosaria/CMakeFiles/actionlib_generate_messages_cpp.dir/depend + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_generate_messages_cpp.dir/cmake_clean.cmake b/Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_generate_messages_cpp.dir/cmake_clean.cmake new file mode 100644 index 0000000..4e0256b --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_generate_messages_cpp.dir/cmake_clean.cmake @@ -0,0 +1,8 @@ +FILE(REMOVE_RECURSE + "CMakeFiles/actionlib_generate_messages_cpp" +) + +# Per-language clean rules from dependency scanning. +FOREACH(lang) + INCLUDE(CMakeFiles/actionlib_generate_messages_cpp.dir/cmake_clean_${lang}.cmake OPTIONAL) +ENDFOREACH(lang) diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_generate_messages_cpp.dir/progress.make b/Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_generate_messages_cpp.dir/progress.make new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_generate_messages_cpp.dir/progress.make @@ -0,0 +1 @@ + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_generate_messages_lisp.dir/DependInfo.cmake b/Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_generate_messages_lisp.dir/DependInfo.cmake new file mode 100644 index 0000000..85f8501 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_generate_messages_lisp.dir/DependInfo.cmake @@ -0,0 +1,16 @@ +# The set of languages for which implicit dependencies are needed: +SET(CMAKE_DEPENDS_LANGUAGES + ) +# The set of files for implicit dependencies of each language: + +# Preprocessor definitions for this target. +SET(CMAKE_TARGET_DEFINITIONS + "ROS_BUILD_SHARED_LIBS=1" + "ROS_PACKAGE_NAME=\"rosaria\"" + "ROSCONSOLE_BACKEND_LOG4CXX" + "ADEPT_PKG" + ) + +# Targets to which this target links. +SET(CMAKE_TARGET_LINKED_INFO_FILES + ) diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_generate_messages_lisp.dir/build.make b/Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_generate_messages_lisp.dir/build.make new file mode 100644 index 0000000..5cf6583 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_generate_messages_lisp.dir/build.make @@ -0,0 +1,62 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/lab1_5/ws/ws_linux/src + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/lab1_5/ws/ws_linux/build + +# Utility rule file for actionlib_generate_messages_lisp. + +# Include the progress variables for this target. +include rosaria/CMakeFiles/actionlib_generate_messages_lisp.dir/progress.make + +rosaria/CMakeFiles/actionlib_generate_messages_lisp: + +actionlib_generate_messages_lisp: rosaria/CMakeFiles/actionlib_generate_messages_lisp +actionlib_generate_messages_lisp: rosaria/CMakeFiles/actionlib_generate_messages_lisp.dir/build.make +.PHONY : actionlib_generate_messages_lisp + +# Rule to build all files generated by this target. +rosaria/CMakeFiles/actionlib_generate_messages_lisp.dir/build: actionlib_generate_messages_lisp +.PHONY : rosaria/CMakeFiles/actionlib_generate_messages_lisp.dir/build + +rosaria/CMakeFiles/actionlib_generate_messages_lisp.dir/clean: + cd /home/lab1_5/ws/ws_linux/build/rosaria && $(CMAKE_COMMAND) -P CMakeFiles/actionlib_generate_messages_lisp.dir/cmake_clean.cmake +.PHONY : rosaria/CMakeFiles/actionlib_generate_messages_lisp.dir/clean + +rosaria/CMakeFiles/actionlib_generate_messages_lisp.dir/depend: + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/lab1_5/ws/ws_linux/src /home/lab1_5/ws/ws_linux/src/rosaria /home/lab1_5/ws/ws_linux/build /home/lab1_5/ws/ws_linux/build/rosaria /home/lab1_5/ws/ws_linux/build/rosaria/CMakeFiles/actionlib_generate_messages_lisp.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : rosaria/CMakeFiles/actionlib_generate_messages_lisp.dir/depend + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_generate_messages_lisp.dir/cmake_clean.cmake b/Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_generate_messages_lisp.dir/cmake_clean.cmake new file mode 100644 index 0000000..338cf95 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_generate_messages_lisp.dir/cmake_clean.cmake @@ -0,0 +1,8 @@ +FILE(REMOVE_RECURSE + "CMakeFiles/actionlib_generate_messages_lisp" +) + +# Per-language clean rules from dependency scanning. +FOREACH(lang) + INCLUDE(CMakeFiles/actionlib_generate_messages_lisp.dir/cmake_clean_${lang}.cmake OPTIONAL) +ENDFOREACH(lang) diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_generate_messages_lisp.dir/progress.make b/Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_generate_messages_lisp.dir/progress.make new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_generate_messages_lisp.dir/progress.make @@ -0,0 +1 @@ + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_generate_messages_py.dir/DependInfo.cmake b/Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_generate_messages_py.dir/DependInfo.cmake new file mode 100644 index 0000000..85f8501 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_generate_messages_py.dir/DependInfo.cmake @@ -0,0 +1,16 @@ +# The set of languages for which implicit dependencies are needed: +SET(CMAKE_DEPENDS_LANGUAGES + ) +# The set of files for implicit dependencies of each language: + +# Preprocessor definitions for this target. +SET(CMAKE_TARGET_DEFINITIONS + "ROS_BUILD_SHARED_LIBS=1" + "ROS_PACKAGE_NAME=\"rosaria\"" + "ROSCONSOLE_BACKEND_LOG4CXX" + "ADEPT_PKG" + ) + +# Targets to which this target links. +SET(CMAKE_TARGET_LINKED_INFO_FILES + ) diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_generate_messages_py.dir/build.make b/Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_generate_messages_py.dir/build.make new file mode 100644 index 0000000..75a9229 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_generate_messages_py.dir/build.make @@ -0,0 +1,62 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/lab1_5/ws/ws_linux/src + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/lab1_5/ws/ws_linux/build + +# Utility rule file for actionlib_generate_messages_py. + +# Include the progress variables for this target. +include rosaria/CMakeFiles/actionlib_generate_messages_py.dir/progress.make + +rosaria/CMakeFiles/actionlib_generate_messages_py: + +actionlib_generate_messages_py: rosaria/CMakeFiles/actionlib_generate_messages_py +actionlib_generate_messages_py: rosaria/CMakeFiles/actionlib_generate_messages_py.dir/build.make +.PHONY : actionlib_generate_messages_py + +# Rule to build all files generated by this target. +rosaria/CMakeFiles/actionlib_generate_messages_py.dir/build: actionlib_generate_messages_py +.PHONY : rosaria/CMakeFiles/actionlib_generate_messages_py.dir/build + +rosaria/CMakeFiles/actionlib_generate_messages_py.dir/clean: + cd /home/lab1_5/ws/ws_linux/build/rosaria && $(CMAKE_COMMAND) -P CMakeFiles/actionlib_generate_messages_py.dir/cmake_clean.cmake +.PHONY : rosaria/CMakeFiles/actionlib_generate_messages_py.dir/clean + +rosaria/CMakeFiles/actionlib_generate_messages_py.dir/depend: + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/lab1_5/ws/ws_linux/src /home/lab1_5/ws/ws_linux/src/rosaria /home/lab1_5/ws/ws_linux/build /home/lab1_5/ws/ws_linux/build/rosaria /home/lab1_5/ws/ws_linux/build/rosaria/CMakeFiles/actionlib_generate_messages_py.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : rosaria/CMakeFiles/actionlib_generate_messages_py.dir/depend + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_generate_messages_py.dir/cmake_clean.cmake b/Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_generate_messages_py.dir/cmake_clean.cmake new file mode 100644 index 0000000..01fa21b --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_generate_messages_py.dir/cmake_clean.cmake @@ -0,0 +1,8 @@ +FILE(REMOVE_RECURSE + "CMakeFiles/actionlib_generate_messages_py" +) + +# Per-language clean rules from dependency scanning. +FOREACH(lang) + INCLUDE(CMakeFiles/actionlib_generate_messages_py.dir/cmake_clean_${lang}.cmake OPTIONAL) +ENDFOREACH(lang) diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_generate_messages_py.dir/progress.make b/Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_generate_messages_py.dir/progress.make new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_generate_messages_py.dir/progress.make @@ -0,0 +1 @@ + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_msgs_generate_messages_cpp.dir/DependInfo.cmake b/Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_msgs_generate_messages_cpp.dir/DependInfo.cmake new file mode 100644 index 0000000..85f8501 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_msgs_generate_messages_cpp.dir/DependInfo.cmake @@ -0,0 +1,16 @@ +# The set of languages for which implicit dependencies are needed: +SET(CMAKE_DEPENDS_LANGUAGES + ) +# The set of files for implicit dependencies of each language: + +# Preprocessor definitions for this target. +SET(CMAKE_TARGET_DEFINITIONS + "ROS_BUILD_SHARED_LIBS=1" + "ROS_PACKAGE_NAME=\"rosaria\"" + "ROSCONSOLE_BACKEND_LOG4CXX" + "ADEPT_PKG" + ) + +# Targets to which this target links. +SET(CMAKE_TARGET_LINKED_INFO_FILES + ) diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_msgs_generate_messages_cpp.dir/build.make b/Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_msgs_generate_messages_cpp.dir/build.make new file mode 100644 index 0000000..2190cd8 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_msgs_generate_messages_cpp.dir/build.make @@ -0,0 +1,62 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/lab1_5/ws/ws_linux/src + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/lab1_5/ws/ws_linux/build + +# Utility rule file for actionlib_msgs_generate_messages_cpp. + +# Include the progress variables for this target. +include rosaria/CMakeFiles/actionlib_msgs_generate_messages_cpp.dir/progress.make + +rosaria/CMakeFiles/actionlib_msgs_generate_messages_cpp: + +actionlib_msgs_generate_messages_cpp: rosaria/CMakeFiles/actionlib_msgs_generate_messages_cpp +actionlib_msgs_generate_messages_cpp: rosaria/CMakeFiles/actionlib_msgs_generate_messages_cpp.dir/build.make +.PHONY : actionlib_msgs_generate_messages_cpp + +# Rule to build all files generated by this target. +rosaria/CMakeFiles/actionlib_msgs_generate_messages_cpp.dir/build: actionlib_msgs_generate_messages_cpp +.PHONY : rosaria/CMakeFiles/actionlib_msgs_generate_messages_cpp.dir/build + +rosaria/CMakeFiles/actionlib_msgs_generate_messages_cpp.dir/clean: + cd /home/lab1_5/ws/ws_linux/build/rosaria && $(CMAKE_COMMAND) -P CMakeFiles/actionlib_msgs_generate_messages_cpp.dir/cmake_clean.cmake +.PHONY : rosaria/CMakeFiles/actionlib_msgs_generate_messages_cpp.dir/clean + +rosaria/CMakeFiles/actionlib_msgs_generate_messages_cpp.dir/depend: + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/lab1_5/ws/ws_linux/src /home/lab1_5/ws/ws_linux/src/rosaria /home/lab1_5/ws/ws_linux/build /home/lab1_5/ws/ws_linux/build/rosaria /home/lab1_5/ws/ws_linux/build/rosaria/CMakeFiles/actionlib_msgs_generate_messages_cpp.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : rosaria/CMakeFiles/actionlib_msgs_generate_messages_cpp.dir/depend + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_msgs_generate_messages_cpp.dir/cmake_clean.cmake b/Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_msgs_generate_messages_cpp.dir/cmake_clean.cmake new file mode 100644 index 0000000..9f2b9ac --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_msgs_generate_messages_cpp.dir/cmake_clean.cmake @@ -0,0 +1,8 @@ +FILE(REMOVE_RECURSE + "CMakeFiles/actionlib_msgs_generate_messages_cpp" +) + +# Per-language clean rules from dependency scanning. +FOREACH(lang) + INCLUDE(CMakeFiles/actionlib_msgs_generate_messages_cpp.dir/cmake_clean_${lang}.cmake OPTIONAL) +ENDFOREACH(lang) diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_msgs_generate_messages_cpp.dir/progress.make b/Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_msgs_generate_messages_cpp.dir/progress.make new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_msgs_generate_messages_cpp.dir/progress.make @@ -0,0 +1 @@ + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_msgs_generate_messages_lisp.dir/DependInfo.cmake b/Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_msgs_generate_messages_lisp.dir/DependInfo.cmake new file mode 100644 index 0000000..85f8501 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_msgs_generate_messages_lisp.dir/DependInfo.cmake @@ -0,0 +1,16 @@ +# The set of languages for which implicit dependencies are needed: +SET(CMAKE_DEPENDS_LANGUAGES + ) +# The set of files for implicit dependencies of each language: + +# Preprocessor definitions for this target. +SET(CMAKE_TARGET_DEFINITIONS + "ROS_BUILD_SHARED_LIBS=1" + "ROS_PACKAGE_NAME=\"rosaria\"" + "ROSCONSOLE_BACKEND_LOG4CXX" + "ADEPT_PKG" + ) + +# Targets to which this target links. +SET(CMAKE_TARGET_LINKED_INFO_FILES + ) diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_msgs_generate_messages_lisp.dir/build.make b/Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_msgs_generate_messages_lisp.dir/build.make new file mode 100644 index 0000000..b350eda --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_msgs_generate_messages_lisp.dir/build.make @@ -0,0 +1,62 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/lab1_5/ws/ws_linux/src + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/lab1_5/ws/ws_linux/build + +# Utility rule file for actionlib_msgs_generate_messages_lisp. + +# Include the progress variables for this target. +include rosaria/CMakeFiles/actionlib_msgs_generate_messages_lisp.dir/progress.make + +rosaria/CMakeFiles/actionlib_msgs_generate_messages_lisp: + +actionlib_msgs_generate_messages_lisp: rosaria/CMakeFiles/actionlib_msgs_generate_messages_lisp +actionlib_msgs_generate_messages_lisp: rosaria/CMakeFiles/actionlib_msgs_generate_messages_lisp.dir/build.make +.PHONY : actionlib_msgs_generate_messages_lisp + +# Rule to build all files generated by this target. +rosaria/CMakeFiles/actionlib_msgs_generate_messages_lisp.dir/build: actionlib_msgs_generate_messages_lisp +.PHONY : rosaria/CMakeFiles/actionlib_msgs_generate_messages_lisp.dir/build + +rosaria/CMakeFiles/actionlib_msgs_generate_messages_lisp.dir/clean: + cd /home/lab1_5/ws/ws_linux/build/rosaria && $(CMAKE_COMMAND) -P CMakeFiles/actionlib_msgs_generate_messages_lisp.dir/cmake_clean.cmake +.PHONY : rosaria/CMakeFiles/actionlib_msgs_generate_messages_lisp.dir/clean + +rosaria/CMakeFiles/actionlib_msgs_generate_messages_lisp.dir/depend: + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/lab1_5/ws/ws_linux/src /home/lab1_5/ws/ws_linux/src/rosaria /home/lab1_5/ws/ws_linux/build /home/lab1_5/ws/ws_linux/build/rosaria /home/lab1_5/ws/ws_linux/build/rosaria/CMakeFiles/actionlib_msgs_generate_messages_lisp.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : rosaria/CMakeFiles/actionlib_msgs_generate_messages_lisp.dir/depend + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_msgs_generate_messages_lisp.dir/cmake_clean.cmake b/Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_msgs_generate_messages_lisp.dir/cmake_clean.cmake new file mode 100644 index 0000000..1c5d47e --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_msgs_generate_messages_lisp.dir/cmake_clean.cmake @@ -0,0 +1,8 @@ +FILE(REMOVE_RECURSE + "CMakeFiles/actionlib_msgs_generate_messages_lisp" +) + +# Per-language clean rules from dependency scanning. +FOREACH(lang) + INCLUDE(CMakeFiles/actionlib_msgs_generate_messages_lisp.dir/cmake_clean_${lang}.cmake OPTIONAL) +ENDFOREACH(lang) diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_msgs_generate_messages_lisp.dir/progress.make b/Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_msgs_generate_messages_lisp.dir/progress.make new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_msgs_generate_messages_lisp.dir/progress.make @@ -0,0 +1 @@ + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_msgs_generate_messages_py.dir/DependInfo.cmake b/Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_msgs_generate_messages_py.dir/DependInfo.cmake new file mode 100644 index 0000000..85f8501 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_msgs_generate_messages_py.dir/DependInfo.cmake @@ -0,0 +1,16 @@ +# The set of languages for which implicit dependencies are needed: +SET(CMAKE_DEPENDS_LANGUAGES + ) +# The set of files for implicit dependencies of each language: + +# Preprocessor definitions for this target. +SET(CMAKE_TARGET_DEFINITIONS + "ROS_BUILD_SHARED_LIBS=1" + "ROS_PACKAGE_NAME=\"rosaria\"" + "ROSCONSOLE_BACKEND_LOG4CXX" + "ADEPT_PKG" + ) + +# Targets to which this target links. +SET(CMAKE_TARGET_LINKED_INFO_FILES + ) diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_msgs_generate_messages_py.dir/build.make b/Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_msgs_generate_messages_py.dir/build.make new file mode 100644 index 0000000..8547212 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_msgs_generate_messages_py.dir/build.make @@ -0,0 +1,62 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/lab1_5/ws/ws_linux/src + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/lab1_5/ws/ws_linux/build + +# Utility rule file for actionlib_msgs_generate_messages_py. + +# Include the progress variables for this target. +include rosaria/CMakeFiles/actionlib_msgs_generate_messages_py.dir/progress.make + +rosaria/CMakeFiles/actionlib_msgs_generate_messages_py: + +actionlib_msgs_generate_messages_py: rosaria/CMakeFiles/actionlib_msgs_generate_messages_py +actionlib_msgs_generate_messages_py: rosaria/CMakeFiles/actionlib_msgs_generate_messages_py.dir/build.make +.PHONY : actionlib_msgs_generate_messages_py + +# Rule to build all files generated by this target. +rosaria/CMakeFiles/actionlib_msgs_generate_messages_py.dir/build: actionlib_msgs_generate_messages_py +.PHONY : rosaria/CMakeFiles/actionlib_msgs_generate_messages_py.dir/build + +rosaria/CMakeFiles/actionlib_msgs_generate_messages_py.dir/clean: + cd /home/lab1_5/ws/ws_linux/build/rosaria && $(CMAKE_COMMAND) -P CMakeFiles/actionlib_msgs_generate_messages_py.dir/cmake_clean.cmake +.PHONY : rosaria/CMakeFiles/actionlib_msgs_generate_messages_py.dir/clean + +rosaria/CMakeFiles/actionlib_msgs_generate_messages_py.dir/depend: + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/lab1_5/ws/ws_linux/src /home/lab1_5/ws/ws_linux/src/rosaria /home/lab1_5/ws/ws_linux/build /home/lab1_5/ws/ws_linux/build/rosaria /home/lab1_5/ws/ws_linux/build/rosaria/CMakeFiles/actionlib_msgs_generate_messages_py.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : rosaria/CMakeFiles/actionlib_msgs_generate_messages_py.dir/depend + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_msgs_generate_messages_py.dir/cmake_clean.cmake b/Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_msgs_generate_messages_py.dir/cmake_clean.cmake new file mode 100644 index 0000000..6dcc146 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_msgs_generate_messages_py.dir/cmake_clean.cmake @@ -0,0 +1,8 @@ +FILE(REMOVE_RECURSE + "CMakeFiles/actionlib_msgs_generate_messages_py" +) + +# Per-language clean rules from dependency scanning. +FOREACH(lang) + INCLUDE(CMakeFiles/actionlib_msgs_generate_messages_py.dir/cmake_clean_${lang}.cmake OPTIONAL) +ENDFOREACH(lang) diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_msgs_generate_messages_py.dir/progress.make b/Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_msgs_generate_messages_py.dir/progress.make new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/actionlib_msgs_generate_messages_py.dir/progress.make @@ -0,0 +1 @@ + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/dynamic_reconfigure_gencfg.dir/DependInfo.cmake b/Legacy/ws_linux/build/rosaria/CMakeFiles/dynamic_reconfigure_gencfg.dir/DependInfo.cmake new file mode 100644 index 0000000..85f8501 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/dynamic_reconfigure_gencfg.dir/DependInfo.cmake @@ -0,0 +1,16 @@ +# The set of languages for which implicit dependencies are needed: +SET(CMAKE_DEPENDS_LANGUAGES + ) +# The set of files for implicit dependencies of each language: + +# Preprocessor definitions for this target. +SET(CMAKE_TARGET_DEFINITIONS + "ROS_BUILD_SHARED_LIBS=1" + "ROS_PACKAGE_NAME=\"rosaria\"" + "ROSCONSOLE_BACKEND_LOG4CXX" + "ADEPT_PKG" + ) + +# Targets to which this target links. +SET(CMAKE_TARGET_LINKED_INFO_FILES + ) diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/dynamic_reconfigure_gencfg.dir/build.make b/Legacy/ws_linux/build/rosaria/CMakeFiles/dynamic_reconfigure_gencfg.dir/build.make new file mode 100644 index 0000000..823867b --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/dynamic_reconfigure_gencfg.dir/build.make @@ -0,0 +1,62 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/lab1_5/ws/ws_linux/src + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/lab1_5/ws/ws_linux/build + +# Utility rule file for dynamic_reconfigure_gencfg. + +# Include the progress variables for this target. +include rosaria/CMakeFiles/dynamic_reconfigure_gencfg.dir/progress.make + +rosaria/CMakeFiles/dynamic_reconfigure_gencfg: + +dynamic_reconfigure_gencfg: rosaria/CMakeFiles/dynamic_reconfigure_gencfg +dynamic_reconfigure_gencfg: rosaria/CMakeFiles/dynamic_reconfigure_gencfg.dir/build.make +.PHONY : dynamic_reconfigure_gencfg + +# Rule to build all files generated by this target. +rosaria/CMakeFiles/dynamic_reconfigure_gencfg.dir/build: dynamic_reconfigure_gencfg +.PHONY : rosaria/CMakeFiles/dynamic_reconfigure_gencfg.dir/build + +rosaria/CMakeFiles/dynamic_reconfigure_gencfg.dir/clean: + cd /home/lab1_5/ws/ws_linux/build/rosaria && $(CMAKE_COMMAND) -P CMakeFiles/dynamic_reconfigure_gencfg.dir/cmake_clean.cmake +.PHONY : rosaria/CMakeFiles/dynamic_reconfigure_gencfg.dir/clean + +rosaria/CMakeFiles/dynamic_reconfigure_gencfg.dir/depend: + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/lab1_5/ws/ws_linux/src /home/lab1_5/ws/ws_linux/src/rosaria /home/lab1_5/ws/ws_linux/build /home/lab1_5/ws/ws_linux/build/rosaria /home/lab1_5/ws/ws_linux/build/rosaria/CMakeFiles/dynamic_reconfigure_gencfg.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : rosaria/CMakeFiles/dynamic_reconfigure_gencfg.dir/depend + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/dynamic_reconfigure_gencfg.dir/cmake_clean.cmake b/Legacy/ws_linux/build/rosaria/CMakeFiles/dynamic_reconfigure_gencfg.dir/cmake_clean.cmake new file mode 100644 index 0000000..a97f6d1 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/dynamic_reconfigure_gencfg.dir/cmake_clean.cmake @@ -0,0 +1,8 @@ +FILE(REMOVE_RECURSE + "CMakeFiles/dynamic_reconfigure_gencfg" +) + +# Per-language clean rules from dependency scanning. +FOREACH(lang) + INCLUDE(CMakeFiles/dynamic_reconfigure_gencfg.dir/cmake_clean_${lang}.cmake OPTIONAL) +ENDFOREACH(lang) diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/dynamic_reconfigure_gencfg.dir/progress.make b/Legacy/ws_linux/build/rosaria/CMakeFiles/dynamic_reconfigure_gencfg.dir/progress.make new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/dynamic_reconfigure_gencfg.dir/progress.make @@ -0,0 +1 @@ + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_cpp.dir/DependInfo.cmake b/Legacy/ws_linux/build/rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_cpp.dir/DependInfo.cmake new file mode 100644 index 0000000..85f8501 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_cpp.dir/DependInfo.cmake @@ -0,0 +1,16 @@ +# The set of languages for which implicit dependencies are needed: +SET(CMAKE_DEPENDS_LANGUAGES + ) +# The set of files for implicit dependencies of each language: + +# Preprocessor definitions for this target. +SET(CMAKE_TARGET_DEFINITIONS + "ROS_BUILD_SHARED_LIBS=1" + "ROS_PACKAGE_NAME=\"rosaria\"" + "ROSCONSOLE_BACKEND_LOG4CXX" + "ADEPT_PKG" + ) + +# Targets to which this target links. +SET(CMAKE_TARGET_LINKED_INFO_FILES + ) diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_cpp.dir/build.make b/Legacy/ws_linux/build/rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_cpp.dir/build.make new file mode 100644 index 0000000..debd928 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_cpp.dir/build.make @@ -0,0 +1,62 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/lab1_5/ws/ws_linux/src + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/lab1_5/ws/ws_linux/build + +# Utility rule file for dynamic_reconfigure_generate_messages_cpp. + +# Include the progress variables for this target. +include rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_cpp.dir/progress.make + +rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_cpp: + +dynamic_reconfigure_generate_messages_cpp: rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_cpp +dynamic_reconfigure_generate_messages_cpp: rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_cpp.dir/build.make +.PHONY : dynamic_reconfigure_generate_messages_cpp + +# Rule to build all files generated by this target. +rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_cpp.dir/build: dynamic_reconfigure_generate_messages_cpp +.PHONY : rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_cpp.dir/build + +rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_cpp.dir/clean: + cd /home/lab1_5/ws/ws_linux/build/rosaria && $(CMAKE_COMMAND) -P CMakeFiles/dynamic_reconfigure_generate_messages_cpp.dir/cmake_clean.cmake +.PHONY : rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_cpp.dir/clean + +rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_cpp.dir/depend: + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/lab1_5/ws/ws_linux/src /home/lab1_5/ws/ws_linux/src/rosaria /home/lab1_5/ws/ws_linux/build /home/lab1_5/ws/ws_linux/build/rosaria /home/lab1_5/ws/ws_linux/build/rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_cpp.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_cpp.dir/depend + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_cpp.dir/cmake_clean.cmake b/Legacy/ws_linux/build/rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_cpp.dir/cmake_clean.cmake new file mode 100644 index 0000000..640246f --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_cpp.dir/cmake_clean.cmake @@ -0,0 +1,8 @@ +FILE(REMOVE_RECURSE + "CMakeFiles/dynamic_reconfigure_generate_messages_cpp" +) + +# Per-language clean rules from dependency scanning. +FOREACH(lang) + INCLUDE(CMakeFiles/dynamic_reconfigure_generate_messages_cpp.dir/cmake_clean_${lang}.cmake OPTIONAL) +ENDFOREACH(lang) diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_cpp.dir/progress.make b/Legacy/ws_linux/build/rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_cpp.dir/progress.make new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_cpp.dir/progress.make @@ -0,0 +1 @@ + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_lisp.dir/DependInfo.cmake b/Legacy/ws_linux/build/rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_lisp.dir/DependInfo.cmake new file mode 100644 index 0000000..85f8501 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_lisp.dir/DependInfo.cmake @@ -0,0 +1,16 @@ +# The set of languages for which implicit dependencies are needed: +SET(CMAKE_DEPENDS_LANGUAGES + ) +# The set of files for implicit dependencies of each language: + +# Preprocessor definitions for this target. +SET(CMAKE_TARGET_DEFINITIONS + "ROS_BUILD_SHARED_LIBS=1" + "ROS_PACKAGE_NAME=\"rosaria\"" + "ROSCONSOLE_BACKEND_LOG4CXX" + "ADEPT_PKG" + ) + +# Targets to which this target links. +SET(CMAKE_TARGET_LINKED_INFO_FILES + ) diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_lisp.dir/build.make b/Legacy/ws_linux/build/rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_lisp.dir/build.make new file mode 100644 index 0000000..c26d081 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_lisp.dir/build.make @@ -0,0 +1,62 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/lab1_5/ws/ws_linux/src + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/lab1_5/ws/ws_linux/build + +# Utility rule file for dynamic_reconfigure_generate_messages_lisp. + +# Include the progress variables for this target. +include rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_lisp.dir/progress.make + +rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_lisp: + +dynamic_reconfigure_generate_messages_lisp: rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_lisp +dynamic_reconfigure_generate_messages_lisp: rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_lisp.dir/build.make +.PHONY : dynamic_reconfigure_generate_messages_lisp + +# Rule to build all files generated by this target. +rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_lisp.dir/build: dynamic_reconfigure_generate_messages_lisp +.PHONY : rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_lisp.dir/build + +rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_lisp.dir/clean: + cd /home/lab1_5/ws/ws_linux/build/rosaria && $(CMAKE_COMMAND) -P CMakeFiles/dynamic_reconfigure_generate_messages_lisp.dir/cmake_clean.cmake +.PHONY : rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_lisp.dir/clean + +rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_lisp.dir/depend: + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/lab1_5/ws/ws_linux/src /home/lab1_5/ws/ws_linux/src/rosaria /home/lab1_5/ws/ws_linux/build /home/lab1_5/ws/ws_linux/build/rosaria /home/lab1_5/ws/ws_linux/build/rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_lisp.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_lisp.dir/depend + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_lisp.dir/cmake_clean.cmake b/Legacy/ws_linux/build/rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_lisp.dir/cmake_clean.cmake new file mode 100644 index 0000000..d054616 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_lisp.dir/cmake_clean.cmake @@ -0,0 +1,8 @@ +FILE(REMOVE_RECURSE + "CMakeFiles/dynamic_reconfigure_generate_messages_lisp" +) + +# Per-language clean rules from dependency scanning. +FOREACH(lang) + INCLUDE(CMakeFiles/dynamic_reconfigure_generate_messages_lisp.dir/cmake_clean_${lang}.cmake OPTIONAL) +ENDFOREACH(lang) diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_lisp.dir/progress.make b/Legacy/ws_linux/build/rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_lisp.dir/progress.make new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_lisp.dir/progress.make @@ -0,0 +1 @@ + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_py.dir/DependInfo.cmake b/Legacy/ws_linux/build/rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_py.dir/DependInfo.cmake new file mode 100644 index 0000000..85f8501 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_py.dir/DependInfo.cmake @@ -0,0 +1,16 @@ +# The set of languages for which implicit dependencies are needed: +SET(CMAKE_DEPENDS_LANGUAGES + ) +# The set of files for implicit dependencies of each language: + +# Preprocessor definitions for this target. +SET(CMAKE_TARGET_DEFINITIONS + "ROS_BUILD_SHARED_LIBS=1" + "ROS_PACKAGE_NAME=\"rosaria\"" + "ROSCONSOLE_BACKEND_LOG4CXX" + "ADEPT_PKG" + ) + +# Targets to which this target links. +SET(CMAKE_TARGET_LINKED_INFO_FILES + ) diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_py.dir/build.make b/Legacy/ws_linux/build/rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_py.dir/build.make new file mode 100644 index 0000000..e9476f6 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_py.dir/build.make @@ -0,0 +1,62 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/lab1_5/ws/ws_linux/src + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/lab1_5/ws/ws_linux/build + +# Utility rule file for dynamic_reconfigure_generate_messages_py. + +# Include the progress variables for this target. +include rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_py.dir/progress.make + +rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_py: + +dynamic_reconfigure_generate_messages_py: rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_py +dynamic_reconfigure_generate_messages_py: rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_py.dir/build.make +.PHONY : dynamic_reconfigure_generate_messages_py + +# Rule to build all files generated by this target. +rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_py.dir/build: dynamic_reconfigure_generate_messages_py +.PHONY : rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_py.dir/build + +rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_py.dir/clean: + cd /home/lab1_5/ws/ws_linux/build/rosaria && $(CMAKE_COMMAND) -P CMakeFiles/dynamic_reconfigure_generate_messages_py.dir/cmake_clean.cmake +.PHONY : rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_py.dir/clean + +rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_py.dir/depend: + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/lab1_5/ws/ws_linux/src /home/lab1_5/ws/ws_linux/src/rosaria /home/lab1_5/ws/ws_linux/build /home/lab1_5/ws/ws_linux/build/rosaria /home/lab1_5/ws/ws_linux/build/rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_py.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_py.dir/depend + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_py.dir/cmake_clean.cmake b/Legacy/ws_linux/build/rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_py.dir/cmake_clean.cmake new file mode 100644 index 0000000..7353389 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_py.dir/cmake_clean.cmake @@ -0,0 +1,8 @@ +FILE(REMOVE_RECURSE + "CMakeFiles/dynamic_reconfigure_generate_messages_py" +) + +# Per-language clean rules from dependency scanning. +FOREACH(lang) + INCLUDE(CMakeFiles/dynamic_reconfigure_generate_messages_py.dir/cmake_clean_${lang}.cmake OPTIONAL) +ENDFOREACH(lang) diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_py.dir/progress.make b/Legacy/ws_linux/build/rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_py.dir/progress.make new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_py.dir/progress.make @@ -0,0 +1 @@ + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/nav_msgs_generate_messages_cpp.dir/DependInfo.cmake b/Legacy/ws_linux/build/rosaria/CMakeFiles/nav_msgs_generate_messages_cpp.dir/DependInfo.cmake new file mode 100644 index 0000000..85f8501 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/nav_msgs_generate_messages_cpp.dir/DependInfo.cmake @@ -0,0 +1,16 @@ +# The set of languages for which implicit dependencies are needed: +SET(CMAKE_DEPENDS_LANGUAGES + ) +# The set of files for implicit dependencies of each language: + +# Preprocessor definitions for this target. +SET(CMAKE_TARGET_DEFINITIONS + "ROS_BUILD_SHARED_LIBS=1" + "ROS_PACKAGE_NAME=\"rosaria\"" + "ROSCONSOLE_BACKEND_LOG4CXX" + "ADEPT_PKG" + ) + +# Targets to which this target links. +SET(CMAKE_TARGET_LINKED_INFO_FILES + ) diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/nav_msgs_generate_messages_cpp.dir/build.make b/Legacy/ws_linux/build/rosaria/CMakeFiles/nav_msgs_generate_messages_cpp.dir/build.make new file mode 100644 index 0000000..144da2f --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/nav_msgs_generate_messages_cpp.dir/build.make @@ -0,0 +1,62 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/lab1_5/ws/ws_linux/src + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/lab1_5/ws/ws_linux/build + +# Utility rule file for nav_msgs_generate_messages_cpp. + +# Include the progress variables for this target. +include rosaria/CMakeFiles/nav_msgs_generate_messages_cpp.dir/progress.make + +rosaria/CMakeFiles/nav_msgs_generate_messages_cpp: + +nav_msgs_generate_messages_cpp: rosaria/CMakeFiles/nav_msgs_generate_messages_cpp +nav_msgs_generate_messages_cpp: rosaria/CMakeFiles/nav_msgs_generate_messages_cpp.dir/build.make +.PHONY : nav_msgs_generate_messages_cpp + +# Rule to build all files generated by this target. +rosaria/CMakeFiles/nav_msgs_generate_messages_cpp.dir/build: nav_msgs_generate_messages_cpp +.PHONY : rosaria/CMakeFiles/nav_msgs_generate_messages_cpp.dir/build + +rosaria/CMakeFiles/nav_msgs_generate_messages_cpp.dir/clean: + cd /home/lab1_5/ws/ws_linux/build/rosaria && $(CMAKE_COMMAND) -P CMakeFiles/nav_msgs_generate_messages_cpp.dir/cmake_clean.cmake +.PHONY : rosaria/CMakeFiles/nav_msgs_generate_messages_cpp.dir/clean + +rosaria/CMakeFiles/nav_msgs_generate_messages_cpp.dir/depend: + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/lab1_5/ws/ws_linux/src /home/lab1_5/ws/ws_linux/src/rosaria /home/lab1_5/ws/ws_linux/build /home/lab1_5/ws/ws_linux/build/rosaria /home/lab1_5/ws/ws_linux/build/rosaria/CMakeFiles/nav_msgs_generate_messages_cpp.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : rosaria/CMakeFiles/nav_msgs_generate_messages_cpp.dir/depend + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/nav_msgs_generate_messages_cpp.dir/cmake_clean.cmake b/Legacy/ws_linux/build/rosaria/CMakeFiles/nav_msgs_generate_messages_cpp.dir/cmake_clean.cmake new file mode 100644 index 0000000..4dd12c3 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/nav_msgs_generate_messages_cpp.dir/cmake_clean.cmake @@ -0,0 +1,8 @@ +FILE(REMOVE_RECURSE + "CMakeFiles/nav_msgs_generate_messages_cpp" +) + +# Per-language clean rules from dependency scanning. +FOREACH(lang) + INCLUDE(CMakeFiles/nav_msgs_generate_messages_cpp.dir/cmake_clean_${lang}.cmake OPTIONAL) +ENDFOREACH(lang) diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/nav_msgs_generate_messages_cpp.dir/progress.make b/Legacy/ws_linux/build/rosaria/CMakeFiles/nav_msgs_generate_messages_cpp.dir/progress.make new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/nav_msgs_generate_messages_cpp.dir/progress.make @@ -0,0 +1 @@ + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/nav_msgs_generate_messages_lisp.dir/DependInfo.cmake b/Legacy/ws_linux/build/rosaria/CMakeFiles/nav_msgs_generate_messages_lisp.dir/DependInfo.cmake new file mode 100644 index 0000000..85f8501 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/nav_msgs_generate_messages_lisp.dir/DependInfo.cmake @@ -0,0 +1,16 @@ +# The set of languages for which implicit dependencies are needed: +SET(CMAKE_DEPENDS_LANGUAGES + ) +# The set of files for implicit dependencies of each language: + +# Preprocessor definitions for this target. +SET(CMAKE_TARGET_DEFINITIONS + "ROS_BUILD_SHARED_LIBS=1" + "ROS_PACKAGE_NAME=\"rosaria\"" + "ROSCONSOLE_BACKEND_LOG4CXX" + "ADEPT_PKG" + ) + +# Targets to which this target links. +SET(CMAKE_TARGET_LINKED_INFO_FILES + ) diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/nav_msgs_generate_messages_lisp.dir/build.make b/Legacy/ws_linux/build/rosaria/CMakeFiles/nav_msgs_generate_messages_lisp.dir/build.make new file mode 100644 index 0000000..8f439c3 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/nav_msgs_generate_messages_lisp.dir/build.make @@ -0,0 +1,62 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/lab1_5/ws/ws_linux/src + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/lab1_5/ws/ws_linux/build + +# Utility rule file for nav_msgs_generate_messages_lisp. + +# Include the progress variables for this target. +include rosaria/CMakeFiles/nav_msgs_generate_messages_lisp.dir/progress.make + +rosaria/CMakeFiles/nav_msgs_generate_messages_lisp: + +nav_msgs_generate_messages_lisp: rosaria/CMakeFiles/nav_msgs_generate_messages_lisp +nav_msgs_generate_messages_lisp: rosaria/CMakeFiles/nav_msgs_generate_messages_lisp.dir/build.make +.PHONY : nav_msgs_generate_messages_lisp + +# Rule to build all files generated by this target. +rosaria/CMakeFiles/nav_msgs_generate_messages_lisp.dir/build: nav_msgs_generate_messages_lisp +.PHONY : rosaria/CMakeFiles/nav_msgs_generate_messages_lisp.dir/build + +rosaria/CMakeFiles/nav_msgs_generate_messages_lisp.dir/clean: + cd /home/lab1_5/ws/ws_linux/build/rosaria && $(CMAKE_COMMAND) -P CMakeFiles/nav_msgs_generate_messages_lisp.dir/cmake_clean.cmake +.PHONY : rosaria/CMakeFiles/nav_msgs_generate_messages_lisp.dir/clean + +rosaria/CMakeFiles/nav_msgs_generate_messages_lisp.dir/depend: + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/lab1_5/ws/ws_linux/src /home/lab1_5/ws/ws_linux/src/rosaria /home/lab1_5/ws/ws_linux/build /home/lab1_5/ws/ws_linux/build/rosaria /home/lab1_5/ws/ws_linux/build/rosaria/CMakeFiles/nav_msgs_generate_messages_lisp.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : rosaria/CMakeFiles/nav_msgs_generate_messages_lisp.dir/depend + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/nav_msgs_generate_messages_lisp.dir/cmake_clean.cmake b/Legacy/ws_linux/build/rosaria/CMakeFiles/nav_msgs_generate_messages_lisp.dir/cmake_clean.cmake new file mode 100644 index 0000000..e6bdcfb --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/nav_msgs_generate_messages_lisp.dir/cmake_clean.cmake @@ -0,0 +1,8 @@ +FILE(REMOVE_RECURSE + "CMakeFiles/nav_msgs_generate_messages_lisp" +) + +# Per-language clean rules from dependency scanning. +FOREACH(lang) + INCLUDE(CMakeFiles/nav_msgs_generate_messages_lisp.dir/cmake_clean_${lang}.cmake OPTIONAL) +ENDFOREACH(lang) diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/nav_msgs_generate_messages_lisp.dir/progress.make b/Legacy/ws_linux/build/rosaria/CMakeFiles/nav_msgs_generate_messages_lisp.dir/progress.make new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/nav_msgs_generate_messages_lisp.dir/progress.make @@ -0,0 +1 @@ + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/nav_msgs_generate_messages_py.dir/DependInfo.cmake b/Legacy/ws_linux/build/rosaria/CMakeFiles/nav_msgs_generate_messages_py.dir/DependInfo.cmake new file mode 100644 index 0000000..85f8501 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/nav_msgs_generate_messages_py.dir/DependInfo.cmake @@ -0,0 +1,16 @@ +# The set of languages for which implicit dependencies are needed: +SET(CMAKE_DEPENDS_LANGUAGES + ) +# The set of files for implicit dependencies of each language: + +# Preprocessor definitions for this target. +SET(CMAKE_TARGET_DEFINITIONS + "ROS_BUILD_SHARED_LIBS=1" + "ROS_PACKAGE_NAME=\"rosaria\"" + "ROSCONSOLE_BACKEND_LOG4CXX" + "ADEPT_PKG" + ) + +# Targets to which this target links. +SET(CMAKE_TARGET_LINKED_INFO_FILES + ) diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/nav_msgs_generate_messages_py.dir/build.make b/Legacy/ws_linux/build/rosaria/CMakeFiles/nav_msgs_generate_messages_py.dir/build.make new file mode 100644 index 0000000..e396a62 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/nav_msgs_generate_messages_py.dir/build.make @@ -0,0 +1,62 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/lab1_5/ws/ws_linux/src + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/lab1_5/ws/ws_linux/build + +# Utility rule file for nav_msgs_generate_messages_py. + +# Include the progress variables for this target. +include rosaria/CMakeFiles/nav_msgs_generate_messages_py.dir/progress.make + +rosaria/CMakeFiles/nav_msgs_generate_messages_py: + +nav_msgs_generate_messages_py: rosaria/CMakeFiles/nav_msgs_generate_messages_py +nav_msgs_generate_messages_py: rosaria/CMakeFiles/nav_msgs_generate_messages_py.dir/build.make +.PHONY : nav_msgs_generate_messages_py + +# Rule to build all files generated by this target. +rosaria/CMakeFiles/nav_msgs_generate_messages_py.dir/build: nav_msgs_generate_messages_py +.PHONY : rosaria/CMakeFiles/nav_msgs_generate_messages_py.dir/build + +rosaria/CMakeFiles/nav_msgs_generate_messages_py.dir/clean: + cd /home/lab1_5/ws/ws_linux/build/rosaria && $(CMAKE_COMMAND) -P CMakeFiles/nav_msgs_generate_messages_py.dir/cmake_clean.cmake +.PHONY : rosaria/CMakeFiles/nav_msgs_generate_messages_py.dir/clean + +rosaria/CMakeFiles/nav_msgs_generate_messages_py.dir/depend: + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/lab1_5/ws/ws_linux/src /home/lab1_5/ws/ws_linux/src/rosaria /home/lab1_5/ws/ws_linux/build /home/lab1_5/ws/ws_linux/build/rosaria /home/lab1_5/ws/ws_linux/build/rosaria/CMakeFiles/nav_msgs_generate_messages_py.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : rosaria/CMakeFiles/nav_msgs_generate_messages_py.dir/depend + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/nav_msgs_generate_messages_py.dir/cmake_clean.cmake b/Legacy/ws_linux/build/rosaria/CMakeFiles/nav_msgs_generate_messages_py.dir/cmake_clean.cmake new file mode 100644 index 0000000..5d55a59 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/nav_msgs_generate_messages_py.dir/cmake_clean.cmake @@ -0,0 +1,8 @@ +FILE(REMOVE_RECURSE + "CMakeFiles/nav_msgs_generate_messages_py" +) + +# Per-language clean rules from dependency scanning. +FOREACH(lang) + INCLUDE(CMakeFiles/nav_msgs_generate_messages_py.dir/cmake_clean_${lang}.cmake OPTIONAL) +ENDFOREACH(lang) diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/nav_msgs_generate_messages_py.dir/progress.make b/Legacy/ws_linux/build/rosaria/CMakeFiles/nav_msgs_generate_messages_py.dir/progress.make new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/nav_msgs_generate_messages_py.dir/progress.make @@ -0,0 +1 @@ + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/progress.marks b/Legacy/ws_linux/build/rosaria/CMakeFiles/progress.marks new file mode 100644 index 0000000..1e8b314 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/progress.marks @@ -0,0 +1 @@ +6 diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_gencfg.dir/DependInfo.cmake b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_gencfg.dir/DependInfo.cmake new file mode 100644 index 0000000..e2053f2 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_gencfg.dir/DependInfo.cmake @@ -0,0 +1,25 @@ +# The set of languages for which implicit dependencies are needed: +SET(CMAKE_DEPENDS_LANGUAGES + ) +# The set of files for implicit dependencies of each language: + +# Preprocessor definitions for this target. +SET(CMAKE_TARGET_DEFINITIONS + "ROS_BUILD_SHARED_LIBS=1" + "ROS_PACKAGE_NAME=\"rosaria\"" + "ROSCONSOLE_BACKEND_LOG4CXX" + "ADEPT_PKG" + ) + +# Pairs of files generated by the same build rule. +SET(CMAKE_MULTIPLE_OUTPUT_PAIRS + "/home/lab1_5/ws/ws_linux/devel/lib/python2.7/dist-packages/rosaria/cfg/RosAriaConfig.py" "/home/lab1_5/ws/ws_linux/devel/include/rosaria/RosAriaConfig.h" + "/home/lab1_5/ws/ws_linux/devel/share/rosaria/docs/RosAriaConfig-usage.dox" "/home/lab1_5/ws/ws_linux/devel/include/rosaria/RosAriaConfig.h" + "/home/lab1_5/ws/ws_linux/devel/share/rosaria/docs/RosAriaConfig.dox" "/home/lab1_5/ws/ws_linux/devel/include/rosaria/RosAriaConfig.h" + "/home/lab1_5/ws/ws_linux/devel/share/rosaria/docs/RosAriaConfig.wikidoc" "/home/lab1_5/ws/ws_linux/devel/include/rosaria/RosAriaConfig.h" + ) + + +# Targets to which this target links. +SET(CMAKE_TARGET_LINKED_INFO_FILES + ) diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_gencfg.dir/build.make b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_gencfg.dir/build.make new file mode 100644 index 0000000..f95f3bc --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_gencfg.dir/build.make @@ -0,0 +1,83 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/lab1_5/ws/ws_linux/src + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/lab1_5/ws/ws_linux/build + +# Utility rule file for rosaria_gencfg. + +# Include the progress variables for this target. +include rosaria/CMakeFiles/rosaria_gencfg.dir/progress.make + +rosaria/CMakeFiles/rosaria_gencfg: /home/lab1_5/ws/ws_linux/devel/include/rosaria/RosAriaConfig.h +rosaria/CMakeFiles/rosaria_gencfg: /home/lab1_5/ws/ws_linux/devel/lib/python2.7/dist-packages/rosaria/cfg/RosAriaConfig.py + +/home/lab1_5/ws/ws_linux/devel/include/rosaria/RosAriaConfig.h: /home/lab1_5/ws/ws_linux/src/rosaria/cfg/RosAria.cfg +/home/lab1_5/ws/ws_linux/devel/include/rosaria/RosAriaConfig.h: /opt/ros/hydro/share/dynamic_reconfigure/cmake/../templates/ConfigType.py.template +/home/lab1_5/ws/ws_linux/devel/include/rosaria/RosAriaConfig.h: /opt/ros/hydro/share/dynamic_reconfigure/cmake/../templates/ConfigType.h.template + $(CMAKE_COMMAND) -E cmake_progress_report /home/lab1_5/ws/ws_linux/build/CMakeFiles $(CMAKE_PROGRESS_1) + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --blue --bold "Generating dynamic reconfigure files from cfg/RosAria.cfg: /home/lab1_5/ws/ws_linux/devel/include/rosaria/RosAriaConfig.h /home/lab1_5/ws/ws_linux/devel/lib/python2.7/dist-packages/rosaria/cfg/RosAriaConfig.py" + cd /home/lab1_5/ws/ws_linux/build/rosaria && ../catkin_generated/env_cached.sh /home/lab1_5/ws/ws_linux/src/rosaria/cfg/RosAria.cfg /opt/ros/hydro/share/dynamic_reconfigure/cmake/.. /home/lab1_5/ws/ws_linux/devel/share/rosaria /home/lab1_5/ws/ws_linux/devel/include/rosaria /home/lab1_5/ws/ws_linux/devel/lib/python2.7/dist-packages/rosaria + +/home/lab1_5/ws/ws_linux/devel/share/rosaria/docs/RosAriaConfig.dox: /home/lab1_5/ws/ws_linux/devel/include/rosaria/RosAriaConfig.h + +/home/lab1_5/ws/ws_linux/devel/share/rosaria/docs/RosAriaConfig-usage.dox: /home/lab1_5/ws/ws_linux/devel/include/rosaria/RosAriaConfig.h + +/home/lab1_5/ws/ws_linux/devel/lib/python2.7/dist-packages/rosaria/cfg/RosAriaConfig.py: /home/lab1_5/ws/ws_linux/devel/include/rosaria/RosAriaConfig.h + +/home/lab1_5/ws/ws_linux/devel/share/rosaria/docs/RosAriaConfig.wikidoc: /home/lab1_5/ws/ws_linux/devel/include/rosaria/RosAriaConfig.h + +rosaria_gencfg: rosaria/CMakeFiles/rosaria_gencfg +rosaria_gencfg: /home/lab1_5/ws/ws_linux/devel/include/rosaria/RosAriaConfig.h +rosaria_gencfg: /home/lab1_5/ws/ws_linux/devel/share/rosaria/docs/RosAriaConfig.dox +rosaria_gencfg: /home/lab1_5/ws/ws_linux/devel/share/rosaria/docs/RosAriaConfig-usage.dox +rosaria_gencfg: /home/lab1_5/ws/ws_linux/devel/lib/python2.7/dist-packages/rosaria/cfg/RosAriaConfig.py +rosaria_gencfg: /home/lab1_5/ws/ws_linux/devel/share/rosaria/docs/RosAriaConfig.wikidoc +rosaria_gencfg: rosaria/CMakeFiles/rosaria_gencfg.dir/build.make +.PHONY : rosaria_gencfg + +# Rule to build all files generated by this target. +rosaria/CMakeFiles/rosaria_gencfg.dir/build: rosaria_gencfg +.PHONY : rosaria/CMakeFiles/rosaria_gencfg.dir/build + +rosaria/CMakeFiles/rosaria_gencfg.dir/clean: + cd /home/lab1_5/ws/ws_linux/build/rosaria && $(CMAKE_COMMAND) -P CMakeFiles/rosaria_gencfg.dir/cmake_clean.cmake +.PHONY : rosaria/CMakeFiles/rosaria_gencfg.dir/clean + +rosaria/CMakeFiles/rosaria_gencfg.dir/depend: + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/lab1_5/ws/ws_linux/src /home/lab1_5/ws/ws_linux/src/rosaria /home/lab1_5/ws/ws_linux/build /home/lab1_5/ws/ws_linux/build/rosaria /home/lab1_5/ws/ws_linux/build/rosaria/CMakeFiles/rosaria_gencfg.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : rosaria/CMakeFiles/rosaria_gencfg.dir/depend + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_gencfg.dir/cmake_clean.cmake b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_gencfg.dir/cmake_clean.cmake new file mode 100644 index 0000000..8ebaf2d --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_gencfg.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +FILE(REMOVE_RECURSE + "CMakeFiles/rosaria_gencfg" + "/home/lab1_5/ws/ws_linux/devel/include/rosaria/RosAriaConfig.h" + "/home/lab1_5/ws/ws_linux/devel/share/rosaria/docs/RosAriaConfig.dox" + "/home/lab1_5/ws/ws_linux/devel/share/rosaria/docs/RosAriaConfig-usage.dox" + "/home/lab1_5/ws/ws_linux/devel/lib/python2.7/dist-packages/rosaria/cfg/RosAriaConfig.py" + "/home/lab1_5/ws/ws_linux/devel/share/rosaria/docs/RosAriaConfig.wikidoc" +) + +# Per-language clean rules from dependency scanning. +FOREACH(lang) + INCLUDE(CMakeFiles/rosaria_gencfg.dir/cmake_clean_${lang}.cmake OPTIONAL) +ENDFOREACH(lang) diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_gencfg.dir/depend.internal b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_gencfg.dir/depend.internal new file mode 100644 index 0000000..38eae05 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_gencfg.dir/depend.internal @@ -0,0 +1,3 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_gencfg.dir/depend.make b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_gencfg.dir/depend.make new file mode 100644 index 0000000..38eae05 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_gencfg.dir/depend.make @@ -0,0 +1,3 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_gencfg.dir/progress.make b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_gencfg.dir/progress.make new file mode 100644 index 0000000..16d5ea2 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_gencfg.dir/progress.make @@ -0,0 +1,2 @@ +CMAKE_PROGRESS_1 = 6 + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_gencpp.dir/DependInfo.cmake b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_gencpp.dir/DependInfo.cmake new file mode 100644 index 0000000..85f8501 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_gencpp.dir/DependInfo.cmake @@ -0,0 +1,16 @@ +# The set of languages for which implicit dependencies are needed: +SET(CMAKE_DEPENDS_LANGUAGES + ) +# The set of files for implicit dependencies of each language: + +# Preprocessor definitions for this target. +SET(CMAKE_TARGET_DEFINITIONS + "ROS_BUILD_SHARED_LIBS=1" + "ROS_PACKAGE_NAME=\"rosaria\"" + "ROSCONSOLE_BACKEND_LOG4CXX" + "ADEPT_PKG" + ) + +# Targets to which this target links. +SET(CMAKE_TARGET_LINKED_INFO_FILES + ) diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_gencpp.dir/build.make b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_gencpp.dir/build.make new file mode 100644 index 0000000..8c7472e --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_gencpp.dir/build.make @@ -0,0 +1,62 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/lab1_5/ws/ws_linux/src + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/lab1_5/ws/ws_linux/build + +# Utility rule file for rosaria_gencpp. + +# Include the progress variables for this target. +include rosaria/CMakeFiles/rosaria_gencpp.dir/progress.make + +rosaria/CMakeFiles/rosaria_gencpp: + +rosaria_gencpp: rosaria/CMakeFiles/rosaria_gencpp +rosaria_gencpp: rosaria/CMakeFiles/rosaria_gencpp.dir/build.make +.PHONY : rosaria_gencpp + +# Rule to build all files generated by this target. +rosaria/CMakeFiles/rosaria_gencpp.dir/build: rosaria_gencpp +.PHONY : rosaria/CMakeFiles/rosaria_gencpp.dir/build + +rosaria/CMakeFiles/rosaria_gencpp.dir/clean: + cd /home/lab1_5/ws/ws_linux/build/rosaria && $(CMAKE_COMMAND) -P CMakeFiles/rosaria_gencpp.dir/cmake_clean.cmake +.PHONY : rosaria/CMakeFiles/rosaria_gencpp.dir/clean + +rosaria/CMakeFiles/rosaria_gencpp.dir/depend: + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/lab1_5/ws/ws_linux/src /home/lab1_5/ws/ws_linux/src/rosaria /home/lab1_5/ws/ws_linux/build /home/lab1_5/ws/ws_linux/build/rosaria /home/lab1_5/ws/ws_linux/build/rosaria/CMakeFiles/rosaria_gencpp.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : rosaria/CMakeFiles/rosaria_gencpp.dir/depend + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_gencpp.dir/cmake_clean.cmake b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_gencpp.dir/cmake_clean.cmake new file mode 100644 index 0000000..d4c69c4 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_gencpp.dir/cmake_clean.cmake @@ -0,0 +1,8 @@ +FILE(REMOVE_RECURSE + "CMakeFiles/rosaria_gencpp" +) + +# Per-language clean rules from dependency scanning. +FOREACH(lang) + INCLUDE(CMakeFiles/rosaria_gencpp.dir/cmake_clean_${lang}.cmake OPTIONAL) +ENDFOREACH(lang) diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_gencpp.dir/depend.internal b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_gencpp.dir/depend.internal new file mode 100644 index 0000000..38eae05 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_gencpp.dir/depend.internal @@ -0,0 +1,3 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_gencpp.dir/depend.make b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_gencpp.dir/depend.make new file mode 100644 index 0000000..38eae05 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_gencpp.dir/depend.make @@ -0,0 +1,3 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_gencpp.dir/progress.make b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_gencpp.dir/progress.make new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_gencpp.dir/progress.make @@ -0,0 +1 @@ + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages.dir/DependInfo.cmake b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages.dir/DependInfo.cmake new file mode 100644 index 0000000..85f8501 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages.dir/DependInfo.cmake @@ -0,0 +1,16 @@ +# The set of languages for which implicit dependencies are needed: +SET(CMAKE_DEPENDS_LANGUAGES + ) +# The set of files for implicit dependencies of each language: + +# Preprocessor definitions for this target. +SET(CMAKE_TARGET_DEFINITIONS + "ROS_BUILD_SHARED_LIBS=1" + "ROS_PACKAGE_NAME=\"rosaria\"" + "ROSCONSOLE_BACKEND_LOG4CXX" + "ADEPT_PKG" + ) + +# Targets to which this target links. +SET(CMAKE_TARGET_LINKED_INFO_FILES + ) diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages.dir/build.make b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages.dir/build.make new file mode 100644 index 0000000..c70a070 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages.dir/build.make @@ -0,0 +1,62 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/lab1_5/ws/ws_linux/src + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/lab1_5/ws/ws_linux/build + +# Utility rule file for rosaria_generate_messages. + +# Include the progress variables for this target. +include rosaria/CMakeFiles/rosaria_generate_messages.dir/progress.make + +rosaria/CMakeFiles/rosaria_generate_messages: + +rosaria_generate_messages: rosaria/CMakeFiles/rosaria_generate_messages +rosaria_generate_messages: rosaria/CMakeFiles/rosaria_generate_messages.dir/build.make +.PHONY : rosaria_generate_messages + +# Rule to build all files generated by this target. +rosaria/CMakeFiles/rosaria_generate_messages.dir/build: rosaria_generate_messages +.PHONY : rosaria/CMakeFiles/rosaria_generate_messages.dir/build + +rosaria/CMakeFiles/rosaria_generate_messages.dir/clean: + cd /home/lab1_5/ws/ws_linux/build/rosaria && $(CMAKE_COMMAND) -P CMakeFiles/rosaria_generate_messages.dir/cmake_clean.cmake +.PHONY : rosaria/CMakeFiles/rosaria_generate_messages.dir/clean + +rosaria/CMakeFiles/rosaria_generate_messages.dir/depend: + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/lab1_5/ws/ws_linux/src /home/lab1_5/ws/ws_linux/src/rosaria /home/lab1_5/ws/ws_linux/build /home/lab1_5/ws/ws_linux/build/rosaria /home/lab1_5/ws/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : rosaria/CMakeFiles/rosaria_generate_messages.dir/depend + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages.dir/cmake_clean.cmake b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages.dir/cmake_clean.cmake new file mode 100644 index 0000000..a0ee125 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages.dir/cmake_clean.cmake @@ -0,0 +1,8 @@ +FILE(REMOVE_RECURSE + "CMakeFiles/rosaria_generate_messages" +) + +# Per-language clean rules from dependency scanning. +FOREACH(lang) + INCLUDE(CMakeFiles/rosaria_generate_messages.dir/cmake_clean_${lang}.cmake OPTIONAL) +ENDFOREACH(lang) diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages.dir/depend.internal b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages.dir/depend.internal new file mode 100644 index 0000000..38eae05 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages.dir/depend.internal @@ -0,0 +1,3 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages.dir/depend.make b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages.dir/depend.make new file mode 100644 index 0000000..38eae05 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages.dir/depend.make @@ -0,0 +1,3 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages.dir/progress.make b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages.dir/progress.make new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages.dir/progress.make @@ -0,0 +1 @@ + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages_cpp.dir/DependInfo.cmake b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages_cpp.dir/DependInfo.cmake new file mode 100644 index 0000000..85f8501 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages_cpp.dir/DependInfo.cmake @@ -0,0 +1,16 @@ +# The set of languages for which implicit dependencies are needed: +SET(CMAKE_DEPENDS_LANGUAGES + ) +# The set of files for implicit dependencies of each language: + +# Preprocessor definitions for this target. +SET(CMAKE_TARGET_DEFINITIONS + "ROS_BUILD_SHARED_LIBS=1" + "ROS_PACKAGE_NAME=\"rosaria\"" + "ROSCONSOLE_BACKEND_LOG4CXX" + "ADEPT_PKG" + ) + +# Targets to which this target links. +SET(CMAKE_TARGET_LINKED_INFO_FILES + ) diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages_cpp.dir/build.make b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages_cpp.dir/build.make new file mode 100644 index 0000000..3f752d9 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages_cpp.dir/build.make @@ -0,0 +1,71 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/lab1_5/ws/ws_linux/src + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/lab1_5/ws/ws_linux/build + +# Utility rule file for rosaria_generate_messages_cpp. + +# Include the progress variables for this target. +include rosaria/CMakeFiles/rosaria_generate_messages_cpp.dir/progress.make + +rosaria/CMakeFiles/rosaria_generate_messages_cpp: /home/lab1_5/ws/ws_linux/devel/include/rosaria/BumperState.h + +/home/lab1_5/ws/ws_linux/devel/include/rosaria/BumperState.h: /opt/ros/hydro/share/gencpp/cmake/../../../lib/gencpp/gen_cpp.py +/home/lab1_5/ws/ws_linux/devel/include/rosaria/BumperState.h: /home/lab1_5/ws/ws_linux/src/rosaria/msg/BumperState.msg +/home/lab1_5/ws/ws_linux/devel/include/rosaria/BumperState.h: /opt/ros/hydro/share/std_msgs/cmake/../msg/Header.msg +/home/lab1_5/ws/ws_linux/devel/include/rosaria/BumperState.h: /opt/ros/hydro/share/gencpp/cmake/../msg.h.template + $(CMAKE_COMMAND) -E cmake_progress_report /home/lab1_5/ws/ws_linux/build/CMakeFiles $(CMAKE_PROGRESS_1) + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --blue --bold "Generating C++ code from rosaria/BumperState.msg" + cd /home/lab1_5/ws/ws_linux/build/rosaria && ../catkin_generated/env_cached.sh /usr/bin/python /opt/ros/hydro/share/gencpp/cmake/../../../lib/gencpp/gen_cpp.py /home/lab1_5/ws/ws_linux/src/rosaria/msg/BumperState.msg -Irosaria:/home/lab1_5/ws/ws_linux/src/rosaria/msg -Igeometry_msgs:/opt/ros/hydro/share/geometry_msgs/cmake/../msg -Istd_msgs:/opt/ros/hydro/share/std_msgs/cmake/../msg -p rosaria -o /home/lab1_5/ws/ws_linux/devel/include/rosaria -e /opt/ros/hydro/share/gencpp/cmake/.. + +rosaria_generate_messages_cpp: rosaria/CMakeFiles/rosaria_generate_messages_cpp +rosaria_generate_messages_cpp: /home/lab1_5/ws/ws_linux/devel/include/rosaria/BumperState.h +rosaria_generate_messages_cpp: rosaria/CMakeFiles/rosaria_generate_messages_cpp.dir/build.make +.PHONY : rosaria_generate_messages_cpp + +# Rule to build all files generated by this target. +rosaria/CMakeFiles/rosaria_generate_messages_cpp.dir/build: rosaria_generate_messages_cpp +.PHONY : rosaria/CMakeFiles/rosaria_generate_messages_cpp.dir/build + +rosaria/CMakeFiles/rosaria_generate_messages_cpp.dir/clean: + cd /home/lab1_5/ws/ws_linux/build/rosaria && $(CMAKE_COMMAND) -P CMakeFiles/rosaria_generate_messages_cpp.dir/cmake_clean.cmake +.PHONY : rosaria/CMakeFiles/rosaria_generate_messages_cpp.dir/clean + +rosaria/CMakeFiles/rosaria_generate_messages_cpp.dir/depend: + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/lab1_5/ws/ws_linux/src /home/lab1_5/ws/ws_linux/src/rosaria /home/lab1_5/ws/ws_linux/build /home/lab1_5/ws/ws_linux/build/rosaria /home/lab1_5/ws/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages_cpp.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : rosaria/CMakeFiles/rosaria_generate_messages_cpp.dir/depend + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages_cpp.dir/cmake_clean.cmake b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages_cpp.dir/cmake_clean.cmake new file mode 100644 index 0000000..1ebcaed --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages_cpp.dir/cmake_clean.cmake @@ -0,0 +1,9 @@ +FILE(REMOVE_RECURSE + "CMakeFiles/rosaria_generate_messages_cpp" + "/home/lab1_5/ws/ws_linux/devel/include/rosaria/BumperState.h" +) + +# Per-language clean rules from dependency scanning. +FOREACH(lang) + INCLUDE(CMakeFiles/rosaria_generate_messages_cpp.dir/cmake_clean_${lang}.cmake OPTIONAL) +ENDFOREACH(lang) diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages_cpp.dir/depend.internal b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages_cpp.dir/depend.internal new file mode 100644 index 0000000..38eae05 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages_cpp.dir/depend.internal @@ -0,0 +1,3 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages_cpp.dir/depend.make b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages_cpp.dir/depend.make new file mode 100644 index 0000000..38eae05 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages_cpp.dir/depend.make @@ -0,0 +1,3 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages_cpp.dir/progress.make b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages_cpp.dir/progress.make new file mode 100644 index 0000000..68e0bc5 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages_cpp.dir/progress.make @@ -0,0 +1,2 @@ +CMAKE_PROGRESS_1 = 7 + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages_lisp.dir/DependInfo.cmake b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages_lisp.dir/DependInfo.cmake new file mode 100644 index 0000000..85f8501 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages_lisp.dir/DependInfo.cmake @@ -0,0 +1,16 @@ +# The set of languages for which implicit dependencies are needed: +SET(CMAKE_DEPENDS_LANGUAGES + ) +# The set of files for implicit dependencies of each language: + +# Preprocessor definitions for this target. +SET(CMAKE_TARGET_DEFINITIONS + "ROS_BUILD_SHARED_LIBS=1" + "ROS_PACKAGE_NAME=\"rosaria\"" + "ROSCONSOLE_BACKEND_LOG4CXX" + "ADEPT_PKG" + ) + +# Targets to which this target links. +SET(CMAKE_TARGET_LINKED_INFO_FILES + ) diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages_lisp.dir/build.make b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages_lisp.dir/build.make new file mode 100644 index 0000000..08bbe82 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages_lisp.dir/build.make @@ -0,0 +1,70 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/lab1_5/ws/ws_linux/src + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/lab1_5/ws/ws_linux/build + +# Utility rule file for rosaria_generate_messages_lisp. + +# Include the progress variables for this target. +include rosaria/CMakeFiles/rosaria_generate_messages_lisp.dir/progress.make + +rosaria/CMakeFiles/rosaria_generate_messages_lisp: /home/lab1_5/ws/ws_linux/devel/share/common-lisp/ros/rosaria/msg/BumperState.lisp + +/home/lab1_5/ws/ws_linux/devel/share/common-lisp/ros/rosaria/msg/BumperState.lisp: /opt/ros/hydro/share/genlisp/cmake/../../../lib/genlisp/gen_lisp.py +/home/lab1_5/ws/ws_linux/devel/share/common-lisp/ros/rosaria/msg/BumperState.lisp: /home/lab1_5/ws/ws_linux/src/rosaria/msg/BumperState.msg +/home/lab1_5/ws/ws_linux/devel/share/common-lisp/ros/rosaria/msg/BumperState.lisp: /opt/ros/hydro/share/std_msgs/cmake/../msg/Header.msg + $(CMAKE_COMMAND) -E cmake_progress_report /home/lab1_5/ws/ws_linux/build/CMakeFiles $(CMAKE_PROGRESS_1) + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --blue --bold "Generating Lisp code from rosaria/BumperState.msg" + cd /home/lab1_5/ws/ws_linux/build/rosaria && ../catkin_generated/env_cached.sh /usr/bin/python /opt/ros/hydro/share/genlisp/cmake/../../../lib/genlisp/gen_lisp.py /home/lab1_5/ws/ws_linux/src/rosaria/msg/BumperState.msg -Irosaria:/home/lab1_5/ws/ws_linux/src/rosaria/msg -Igeometry_msgs:/opt/ros/hydro/share/geometry_msgs/cmake/../msg -Istd_msgs:/opt/ros/hydro/share/std_msgs/cmake/../msg -p rosaria -o /home/lab1_5/ws/ws_linux/devel/share/common-lisp/ros/rosaria/msg + +rosaria_generate_messages_lisp: rosaria/CMakeFiles/rosaria_generate_messages_lisp +rosaria_generate_messages_lisp: /home/lab1_5/ws/ws_linux/devel/share/common-lisp/ros/rosaria/msg/BumperState.lisp +rosaria_generate_messages_lisp: rosaria/CMakeFiles/rosaria_generate_messages_lisp.dir/build.make +.PHONY : rosaria_generate_messages_lisp + +# Rule to build all files generated by this target. +rosaria/CMakeFiles/rosaria_generate_messages_lisp.dir/build: rosaria_generate_messages_lisp +.PHONY : rosaria/CMakeFiles/rosaria_generate_messages_lisp.dir/build + +rosaria/CMakeFiles/rosaria_generate_messages_lisp.dir/clean: + cd /home/lab1_5/ws/ws_linux/build/rosaria && $(CMAKE_COMMAND) -P CMakeFiles/rosaria_generate_messages_lisp.dir/cmake_clean.cmake +.PHONY : rosaria/CMakeFiles/rosaria_generate_messages_lisp.dir/clean + +rosaria/CMakeFiles/rosaria_generate_messages_lisp.dir/depend: + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/lab1_5/ws/ws_linux/src /home/lab1_5/ws/ws_linux/src/rosaria /home/lab1_5/ws/ws_linux/build /home/lab1_5/ws/ws_linux/build/rosaria /home/lab1_5/ws/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages_lisp.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : rosaria/CMakeFiles/rosaria_generate_messages_lisp.dir/depend + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages_lisp.dir/cmake_clean.cmake b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages_lisp.dir/cmake_clean.cmake new file mode 100644 index 0000000..8aac6b3 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages_lisp.dir/cmake_clean.cmake @@ -0,0 +1,9 @@ +FILE(REMOVE_RECURSE + "CMakeFiles/rosaria_generate_messages_lisp" + "/home/lab1_5/ws/ws_linux/devel/share/common-lisp/ros/rosaria/msg/BumperState.lisp" +) + +# Per-language clean rules from dependency scanning. +FOREACH(lang) + INCLUDE(CMakeFiles/rosaria_generate_messages_lisp.dir/cmake_clean_${lang}.cmake OPTIONAL) +ENDFOREACH(lang) diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages_lisp.dir/depend.internal b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages_lisp.dir/depend.internal new file mode 100644 index 0000000..38eae05 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages_lisp.dir/depend.internal @@ -0,0 +1,3 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages_lisp.dir/depend.make b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages_lisp.dir/depend.make new file mode 100644 index 0000000..38eae05 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages_lisp.dir/depend.make @@ -0,0 +1,3 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages_lisp.dir/progress.make b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages_lisp.dir/progress.make new file mode 100644 index 0000000..c561fca --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages_lisp.dir/progress.make @@ -0,0 +1,2 @@ +CMAKE_PROGRESS_1 = 8 + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages_py.dir/DependInfo.cmake b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages_py.dir/DependInfo.cmake new file mode 100644 index 0000000..85f8501 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages_py.dir/DependInfo.cmake @@ -0,0 +1,16 @@ +# The set of languages for which implicit dependencies are needed: +SET(CMAKE_DEPENDS_LANGUAGES + ) +# The set of files for implicit dependencies of each language: + +# Preprocessor definitions for this target. +SET(CMAKE_TARGET_DEFINITIONS + "ROS_BUILD_SHARED_LIBS=1" + "ROS_PACKAGE_NAME=\"rosaria\"" + "ROSCONSOLE_BACKEND_LOG4CXX" + "ADEPT_PKG" + ) + +# Targets to which this target links. +SET(CMAKE_TARGET_LINKED_INFO_FILES + ) diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages_py.dir/build.make b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages_py.dir/build.make new file mode 100644 index 0000000..89f521b --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages_py.dir/build.make @@ -0,0 +1,78 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/lab1_5/ws/ws_linux/src + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/lab1_5/ws/ws_linux/build + +# Utility rule file for rosaria_generate_messages_py. + +# Include the progress variables for this target. +include rosaria/CMakeFiles/rosaria_generate_messages_py.dir/progress.make + +rosaria/CMakeFiles/rosaria_generate_messages_py: /home/lab1_5/ws/ws_linux/devel/lib/python2.7/dist-packages/rosaria/msg/_BumperState.py +rosaria/CMakeFiles/rosaria_generate_messages_py: /home/lab1_5/ws/ws_linux/devel/lib/python2.7/dist-packages/rosaria/msg/__init__.py + +/home/lab1_5/ws/ws_linux/devel/lib/python2.7/dist-packages/rosaria/msg/_BumperState.py: /opt/ros/hydro/share/genpy/cmake/../../../lib/genpy/genmsg_py.py +/home/lab1_5/ws/ws_linux/devel/lib/python2.7/dist-packages/rosaria/msg/_BumperState.py: /home/lab1_5/ws/ws_linux/src/rosaria/msg/BumperState.msg +/home/lab1_5/ws/ws_linux/devel/lib/python2.7/dist-packages/rosaria/msg/_BumperState.py: /opt/ros/hydro/share/std_msgs/cmake/../msg/Header.msg + $(CMAKE_COMMAND) -E cmake_progress_report /home/lab1_5/ws/ws_linux/build/CMakeFiles $(CMAKE_PROGRESS_1) + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --blue --bold "Generating Python from MSG rosaria/BumperState" + cd /home/lab1_5/ws/ws_linux/build/rosaria && ../catkin_generated/env_cached.sh /usr/bin/python /opt/ros/hydro/share/genpy/cmake/../../../lib/genpy/genmsg_py.py /home/lab1_5/ws/ws_linux/src/rosaria/msg/BumperState.msg -Irosaria:/home/lab1_5/ws/ws_linux/src/rosaria/msg -Igeometry_msgs:/opt/ros/hydro/share/geometry_msgs/cmake/../msg -Istd_msgs:/opt/ros/hydro/share/std_msgs/cmake/../msg -p rosaria -o /home/lab1_5/ws/ws_linux/devel/lib/python2.7/dist-packages/rosaria/msg + +/home/lab1_5/ws/ws_linux/devel/lib/python2.7/dist-packages/rosaria/msg/__init__.py: /opt/ros/hydro/share/genpy/cmake/../../../lib/genpy/genmsg_py.py +/home/lab1_5/ws/ws_linux/devel/lib/python2.7/dist-packages/rosaria/msg/__init__.py: /home/lab1_5/ws/ws_linux/devel/lib/python2.7/dist-packages/rosaria/msg/_BumperState.py + $(CMAKE_COMMAND) -E cmake_progress_report /home/lab1_5/ws/ws_linux/build/CMakeFiles $(CMAKE_PROGRESS_2) + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --blue --bold "Generating Python msg __init__.py for rosaria" + cd /home/lab1_5/ws/ws_linux/build/rosaria && ../catkin_generated/env_cached.sh /usr/bin/python /opt/ros/hydro/share/genpy/cmake/../../../lib/genpy/genmsg_py.py -o /home/lab1_5/ws/ws_linux/devel/lib/python2.7/dist-packages/rosaria/msg --initpy + +rosaria_generate_messages_py: rosaria/CMakeFiles/rosaria_generate_messages_py +rosaria_generate_messages_py: /home/lab1_5/ws/ws_linux/devel/lib/python2.7/dist-packages/rosaria/msg/_BumperState.py +rosaria_generate_messages_py: /home/lab1_5/ws/ws_linux/devel/lib/python2.7/dist-packages/rosaria/msg/__init__.py +rosaria_generate_messages_py: rosaria/CMakeFiles/rosaria_generate_messages_py.dir/build.make +.PHONY : rosaria_generate_messages_py + +# Rule to build all files generated by this target. +rosaria/CMakeFiles/rosaria_generate_messages_py.dir/build: rosaria_generate_messages_py +.PHONY : rosaria/CMakeFiles/rosaria_generate_messages_py.dir/build + +rosaria/CMakeFiles/rosaria_generate_messages_py.dir/clean: + cd /home/lab1_5/ws/ws_linux/build/rosaria && $(CMAKE_COMMAND) -P CMakeFiles/rosaria_generate_messages_py.dir/cmake_clean.cmake +.PHONY : rosaria/CMakeFiles/rosaria_generate_messages_py.dir/clean + +rosaria/CMakeFiles/rosaria_generate_messages_py.dir/depend: + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/lab1_5/ws/ws_linux/src /home/lab1_5/ws/ws_linux/src/rosaria /home/lab1_5/ws/ws_linux/build /home/lab1_5/ws/ws_linux/build/rosaria /home/lab1_5/ws/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages_py.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : rosaria/CMakeFiles/rosaria_generate_messages_py.dir/depend + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages_py.dir/cmake_clean.cmake b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages_py.dir/cmake_clean.cmake new file mode 100644 index 0000000..d1b1b54 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages_py.dir/cmake_clean.cmake @@ -0,0 +1,10 @@ +FILE(REMOVE_RECURSE + "CMakeFiles/rosaria_generate_messages_py" + "/home/lab1_5/ws/ws_linux/devel/lib/python2.7/dist-packages/rosaria/msg/_BumperState.py" + "/home/lab1_5/ws/ws_linux/devel/lib/python2.7/dist-packages/rosaria/msg/__init__.py" +) + +# Per-language clean rules from dependency scanning. +FOREACH(lang) + INCLUDE(CMakeFiles/rosaria_generate_messages_py.dir/cmake_clean_${lang}.cmake OPTIONAL) +ENDFOREACH(lang) diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages_py.dir/depend.internal b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages_py.dir/depend.internal new file mode 100644 index 0000000..38eae05 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages_py.dir/depend.internal @@ -0,0 +1,3 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages_py.dir/depend.make b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages_py.dir/depend.make new file mode 100644 index 0000000..38eae05 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages_py.dir/depend.make @@ -0,0 +1,3 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages_py.dir/progress.make b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages_py.dir/progress.make new file mode 100644 index 0000000..b700c2c --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_generate_messages_py.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = 9 +CMAKE_PROGRESS_2 = 10 + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_genlisp.dir/DependInfo.cmake b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_genlisp.dir/DependInfo.cmake new file mode 100644 index 0000000..85f8501 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_genlisp.dir/DependInfo.cmake @@ -0,0 +1,16 @@ +# The set of languages for which implicit dependencies are needed: +SET(CMAKE_DEPENDS_LANGUAGES + ) +# The set of files for implicit dependencies of each language: + +# Preprocessor definitions for this target. +SET(CMAKE_TARGET_DEFINITIONS + "ROS_BUILD_SHARED_LIBS=1" + "ROS_PACKAGE_NAME=\"rosaria\"" + "ROSCONSOLE_BACKEND_LOG4CXX" + "ADEPT_PKG" + ) + +# Targets to which this target links. +SET(CMAKE_TARGET_LINKED_INFO_FILES + ) diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_genlisp.dir/build.make b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_genlisp.dir/build.make new file mode 100644 index 0000000..c23883e --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_genlisp.dir/build.make @@ -0,0 +1,62 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/lab1_5/ws/ws_linux/src + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/lab1_5/ws/ws_linux/build + +# Utility rule file for rosaria_genlisp. + +# Include the progress variables for this target. +include rosaria/CMakeFiles/rosaria_genlisp.dir/progress.make + +rosaria/CMakeFiles/rosaria_genlisp: + +rosaria_genlisp: rosaria/CMakeFiles/rosaria_genlisp +rosaria_genlisp: rosaria/CMakeFiles/rosaria_genlisp.dir/build.make +.PHONY : rosaria_genlisp + +# Rule to build all files generated by this target. +rosaria/CMakeFiles/rosaria_genlisp.dir/build: rosaria_genlisp +.PHONY : rosaria/CMakeFiles/rosaria_genlisp.dir/build + +rosaria/CMakeFiles/rosaria_genlisp.dir/clean: + cd /home/lab1_5/ws/ws_linux/build/rosaria && $(CMAKE_COMMAND) -P CMakeFiles/rosaria_genlisp.dir/cmake_clean.cmake +.PHONY : rosaria/CMakeFiles/rosaria_genlisp.dir/clean + +rosaria/CMakeFiles/rosaria_genlisp.dir/depend: + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/lab1_5/ws/ws_linux/src /home/lab1_5/ws/ws_linux/src/rosaria /home/lab1_5/ws/ws_linux/build /home/lab1_5/ws/ws_linux/build/rosaria /home/lab1_5/ws/ws_linux/build/rosaria/CMakeFiles/rosaria_genlisp.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : rosaria/CMakeFiles/rosaria_genlisp.dir/depend + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_genlisp.dir/cmake_clean.cmake b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_genlisp.dir/cmake_clean.cmake new file mode 100644 index 0000000..d8e47ba --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_genlisp.dir/cmake_clean.cmake @@ -0,0 +1,8 @@ +FILE(REMOVE_RECURSE + "CMakeFiles/rosaria_genlisp" +) + +# Per-language clean rules from dependency scanning. +FOREACH(lang) + INCLUDE(CMakeFiles/rosaria_genlisp.dir/cmake_clean_${lang}.cmake OPTIONAL) +ENDFOREACH(lang) diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_genlisp.dir/progress.make b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_genlisp.dir/progress.make new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_genlisp.dir/progress.make @@ -0,0 +1 @@ + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_genpy.dir/DependInfo.cmake b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_genpy.dir/DependInfo.cmake new file mode 100644 index 0000000..85f8501 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_genpy.dir/DependInfo.cmake @@ -0,0 +1,16 @@ +# The set of languages for which implicit dependencies are needed: +SET(CMAKE_DEPENDS_LANGUAGES + ) +# The set of files for implicit dependencies of each language: + +# Preprocessor definitions for this target. +SET(CMAKE_TARGET_DEFINITIONS + "ROS_BUILD_SHARED_LIBS=1" + "ROS_PACKAGE_NAME=\"rosaria\"" + "ROSCONSOLE_BACKEND_LOG4CXX" + "ADEPT_PKG" + ) + +# Targets to which this target links. +SET(CMAKE_TARGET_LINKED_INFO_FILES + ) diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_genpy.dir/build.make b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_genpy.dir/build.make new file mode 100644 index 0000000..5996a94 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_genpy.dir/build.make @@ -0,0 +1,62 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/lab1_5/ws/ws_linux/src + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/lab1_5/ws/ws_linux/build + +# Utility rule file for rosaria_genpy. + +# Include the progress variables for this target. +include rosaria/CMakeFiles/rosaria_genpy.dir/progress.make + +rosaria/CMakeFiles/rosaria_genpy: + +rosaria_genpy: rosaria/CMakeFiles/rosaria_genpy +rosaria_genpy: rosaria/CMakeFiles/rosaria_genpy.dir/build.make +.PHONY : rosaria_genpy + +# Rule to build all files generated by this target. +rosaria/CMakeFiles/rosaria_genpy.dir/build: rosaria_genpy +.PHONY : rosaria/CMakeFiles/rosaria_genpy.dir/build + +rosaria/CMakeFiles/rosaria_genpy.dir/clean: + cd /home/lab1_5/ws/ws_linux/build/rosaria && $(CMAKE_COMMAND) -P CMakeFiles/rosaria_genpy.dir/cmake_clean.cmake +.PHONY : rosaria/CMakeFiles/rosaria_genpy.dir/clean + +rosaria/CMakeFiles/rosaria_genpy.dir/depend: + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/lab1_5/ws/ws_linux/src /home/lab1_5/ws/ws_linux/src/rosaria /home/lab1_5/ws/ws_linux/build /home/lab1_5/ws/ws_linux/build/rosaria /home/lab1_5/ws/ws_linux/build/rosaria/CMakeFiles/rosaria_genpy.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : rosaria/CMakeFiles/rosaria_genpy.dir/depend + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_genpy.dir/cmake_clean.cmake b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_genpy.dir/cmake_clean.cmake new file mode 100644 index 0000000..1d45df6 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_genpy.dir/cmake_clean.cmake @@ -0,0 +1,8 @@ +FILE(REMOVE_RECURSE + "CMakeFiles/rosaria_genpy" +) + +# Per-language clean rules from dependency scanning. +FOREACH(lang) + INCLUDE(CMakeFiles/rosaria_genpy.dir/cmake_clean_${lang}.cmake OPTIONAL) +ENDFOREACH(lang) diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_genpy.dir/progress.make b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_genpy.dir/progress.make new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosaria_genpy.dir/progress.make @@ -0,0 +1 @@ + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/roscpp_generate_messages_cpp.dir/DependInfo.cmake b/Legacy/ws_linux/build/rosaria/CMakeFiles/roscpp_generate_messages_cpp.dir/DependInfo.cmake new file mode 100644 index 0000000..85f8501 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/roscpp_generate_messages_cpp.dir/DependInfo.cmake @@ -0,0 +1,16 @@ +# The set of languages for which implicit dependencies are needed: +SET(CMAKE_DEPENDS_LANGUAGES + ) +# The set of files for implicit dependencies of each language: + +# Preprocessor definitions for this target. +SET(CMAKE_TARGET_DEFINITIONS + "ROS_BUILD_SHARED_LIBS=1" + "ROS_PACKAGE_NAME=\"rosaria\"" + "ROSCONSOLE_BACKEND_LOG4CXX" + "ADEPT_PKG" + ) + +# Targets to which this target links. +SET(CMAKE_TARGET_LINKED_INFO_FILES + ) diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/roscpp_generate_messages_cpp.dir/build.make b/Legacy/ws_linux/build/rosaria/CMakeFiles/roscpp_generate_messages_cpp.dir/build.make new file mode 100644 index 0000000..97a1596 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/roscpp_generate_messages_cpp.dir/build.make @@ -0,0 +1,62 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/lab1_5/ws/ws_linux/src + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/lab1_5/ws/ws_linux/build + +# Utility rule file for roscpp_generate_messages_cpp. + +# Include the progress variables for this target. +include rosaria/CMakeFiles/roscpp_generate_messages_cpp.dir/progress.make + +rosaria/CMakeFiles/roscpp_generate_messages_cpp: + +roscpp_generate_messages_cpp: rosaria/CMakeFiles/roscpp_generate_messages_cpp +roscpp_generate_messages_cpp: rosaria/CMakeFiles/roscpp_generate_messages_cpp.dir/build.make +.PHONY : roscpp_generate_messages_cpp + +# Rule to build all files generated by this target. +rosaria/CMakeFiles/roscpp_generate_messages_cpp.dir/build: roscpp_generate_messages_cpp +.PHONY : rosaria/CMakeFiles/roscpp_generate_messages_cpp.dir/build + +rosaria/CMakeFiles/roscpp_generate_messages_cpp.dir/clean: + cd /home/lab1_5/ws/ws_linux/build/rosaria && $(CMAKE_COMMAND) -P CMakeFiles/roscpp_generate_messages_cpp.dir/cmake_clean.cmake +.PHONY : rosaria/CMakeFiles/roscpp_generate_messages_cpp.dir/clean + +rosaria/CMakeFiles/roscpp_generate_messages_cpp.dir/depend: + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/lab1_5/ws/ws_linux/src /home/lab1_5/ws/ws_linux/src/rosaria /home/lab1_5/ws/ws_linux/build /home/lab1_5/ws/ws_linux/build/rosaria /home/lab1_5/ws/ws_linux/build/rosaria/CMakeFiles/roscpp_generate_messages_cpp.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : rosaria/CMakeFiles/roscpp_generate_messages_cpp.dir/depend + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/roscpp_generate_messages_cpp.dir/cmake_clean.cmake b/Legacy/ws_linux/build/rosaria/CMakeFiles/roscpp_generate_messages_cpp.dir/cmake_clean.cmake new file mode 100644 index 0000000..20c0902 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/roscpp_generate_messages_cpp.dir/cmake_clean.cmake @@ -0,0 +1,8 @@ +FILE(REMOVE_RECURSE + "CMakeFiles/roscpp_generate_messages_cpp" +) + +# Per-language clean rules from dependency scanning. +FOREACH(lang) + INCLUDE(CMakeFiles/roscpp_generate_messages_cpp.dir/cmake_clean_${lang}.cmake OPTIONAL) +ENDFOREACH(lang) diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/roscpp_generate_messages_cpp.dir/progress.make b/Legacy/ws_linux/build/rosaria/CMakeFiles/roscpp_generate_messages_cpp.dir/progress.make new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/roscpp_generate_messages_cpp.dir/progress.make @@ -0,0 +1 @@ + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/roscpp_generate_messages_lisp.dir/DependInfo.cmake b/Legacy/ws_linux/build/rosaria/CMakeFiles/roscpp_generate_messages_lisp.dir/DependInfo.cmake new file mode 100644 index 0000000..85f8501 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/roscpp_generate_messages_lisp.dir/DependInfo.cmake @@ -0,0 +1,16 @@ +# The set of languages for which implicit dependencies are needed: +SET(CMAKE_DEPENDS_LANGUAGES + ) +# The set of files for implicit dependencies of each language: + +# Preprocessor definitions for this target. +SET(CMAKE_TARGET_DEFINITIONS + "ROS_BUILD_SHARED_LIBS=1" + "ROS_PACKAGE_NAME=\"rosaria\"" + "ROSCONSOLE_BACKEND_LOG4CXX" + "ADEPT_PKG" + ) + +# Targets to which this target links. +SET(CMAKE_TARGET_LINKED_INFO_FILES + ) diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/roscpp_generate_messages_lisp.dir/build.make b/Legacy/ws_linux/build/rosaria/CMakeFiles/roscpp_generate_messages_lisp.dir/build.make new file mode 100644 index 0000000..be5af23 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/roscpp_generate_messages_lisp.dir/build.make @@ -0,0 +1,62 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/lab1_5/ws/ws_linux/src + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/lab1_5/ws/ws_linux/build + +# Utility rule file for roscpp_generate_messages_lisp. + +# Include the progress variables for this target. +include rosaria/CMakeFiles/roscpp_generate_messages_lisp.dir/progress.make + +rosaria/CMakeFiles/roscpp_generate_messages_lisp: + +roscpp_generate_messages_lisp: rosaria/CMakeFiles/roscpp_generate_messages_lisp +roscpp_generate_messages_lisp: rosaria/CMakeFiles/roscpp_generate_messages_lisp.dir/build.make +.PHONY : roscpp_generate_messages_lisp + +# Rule to build all files generated by this target. +rosaria/CMakeFiles/roscpp_generate_messages_lisp.dir/build: roscpp_generate_messages_lisp +.PHONY : rosaria/CMakeFiles/roscpp_generate_messages_lisp.dir/build + +rosaria/CMakeFiles/roscpp_generate_messages_lisp.dir/clean: + cd /home/lab1_5/ws/ws_linux/build/rosaria && $(CMAKE_COMMAND) -P CMakeFiles/roscpp_generate_messages_lisp.dir/cmake_clean.cmake +.PHONY : rosaria/CMakeFiles/roscpp_generate_messages_lisp.dir/clean + +rosaria/CMakeFiles/roscpp_generate_messages_lisp.dir/depend: + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/lab1_5/ws/ws_linux/src /home/lab1_5/ws/ws_linux/src/rosaria /home/lab1_5/ws/ws_linux/build /home/lab1_5/ws/ws_linux/build/rosaria /home/lab1_5/ws/ws_linux/build/rosaria/CMakeFiles/roscpp_generate_messages_lisp.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : rosaria/CMakeFiles/roscpp_generate_messages_lisp.dir/depend + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/roscpp_generate_messages_lisp.dir/cmake_clean.cmake b/Legacy/ws_linux/build/rosaria/CMakeFiles/roscpp_generate_messages_lisp.dir/cmake_clean.cmake new file mode 100644 index 0000000..0d54a3c --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/roscpp_generate_messages_lisp.dir/cmake_clean.cmake @@ -0,0 +1,8 @@ +FILE(REMOVE_RECURSE + "CMakeFiles/roscpp_generate_messages_lisp" +) + +# Per-language clean rules from dependency scanning. +FOREACH(lang) + INCLUDE(CMakeFiles/roscpp_generate_messages_lisp.dir/cmake_clean_${lang}.cmake OPTIONAL) +ENDFOREACH(lang) diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/roscpp_generate_messages_lisp.dir/progress.make b/Legacy/ws_linux/build/rosaria/CMakeFiles/roscpp_generate_messages_lisp.dir/progress.make new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/roscpp_generate_messages_lisp.dir/progress.make @@ -0,0 +1 @@ + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/roscpp_generate_messages_py.dir/DependInfo.cmake b/Legacy/ws_linux/build/rosaria/CMakeFiles/roscpp_generate_messages_py.dir/DependInfo.cmake new file mode 100644 index 0000000..85f8501 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/roscpp_generate_messages_py.dir/DependInfo.cmake @@ -0,0 +1,16 @@ +# The set of languages for which implicit dependencies are needed: +SET(CMAKE_DEPENDS_LANGUAGES + ) +# The set of files for implicit dependencies of each language: + +# Preprocessor definitions for this target. +SET(CMAKE_TARGET_DEFINITIONS + "ROS_BUILD_SHARED_LIBS=1" + "ROS_PACKAGE_NAME=\"rosaria\"" + "ROSCONSOLE_BACKEND_LOG4CXX" + "ADEPT_PKG" + ) + +# Targets to which this target links. +SET(CMAKE_TARGET_LINKED_INFO_FILES + ) diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/roscpp_generate_messages_py.dir/build.make b/Legacy/ws_linux/build/rosaria/CMakeFiles/roscpp_generate_messages_py.dir/build.make new file mode 100644 index 0000000..cc2f071 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/roscpp_generate_messages_py.dir/build.make @@ -0,0 +1,62 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/lab1_5/ws/ws_linux/src + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/lab1_5/ws/ws_linux/build + +# Utility rule file for roscpp_generate_messages_py. + +# Include the progress variables for this target. +include rosaria/CMakeFiles/roscpp_generate_messages_py.dir/progress.make + +rosaria/CMakeFiles/roscpp_generate_messages_py: + +roscpp_generate_messages_py: rosaria/CMakeFiles/roscpp_generate_messages_py +roscpp_generate_messages_py: rosaria/CMakeFiles/roscpp_generate_messages_py.dir/build.make +.PHONY : roscpp_generate_messages_py + +# Rule to build all files generated by this target. +rosaria/CMakeFiles/roscpp_generate_messages_py.dir/build: roscpp_generate_messages_py +.PHONY : rosaria/CMakeFiles/roscpp_generate_messages_py.dir/build + +rosaria/CMakeFiles/roscpp_generate_messages_py.dir/clean: + cd /home/lab1_5/ws/ws_linux/build/rosaria && $(CMAKE_COMMAND) -P CMakeFiles/roscpp_generate_messages_py.dir/cmake_clean.cmake +.PHONY : rosaria/CMakeFiles/roscpp_generate_messages_py.dir/clean + +rosaria/CMakeFiles/roscpp_generate_messages_py.dir/depend: + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/lab1_5/ws/ws_linux/src /home/lab1_5/ws/ws_linux/src/rosaria /home/lab1_5/ws/ws_linux/build /home/lab1_5/ws/ws_linux/build/rosaria /home/lab1_5/ws/ws_linux/build/rosaria/CMakeFiles/roscpp_generate_messages_py.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : rosaria/CMakeFiles/roscpp_generate_messages_py.dir/depend + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/roscpp_generate_messages_py.dir/cmake_clean.cmake b/Legacy/ws_linux/build/rosaria/CMakeFiles/roscpp_generate_messages_py.dir/cmake_clean.cmake new file mode 100644 index 0000000..7282dbb --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/roscpp_generate_messages_py.dir/cmake_clean.cmake @@ -0,0 +1,8 @@ +FILE(REMOVE_RECURSE + "CMakeFiles/roscpp_generate_messages_py" +) + +# Per-language clean rules from dependency scanning. +FOREACH(lang) + INCLUDE(CMakeFiles/roscpp_generate_messages_py.dir/cmake_clean_${lang}.cmake OPTIONAL) +ENDFOREACH(lang) diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/roscpp_generate_messages_py.dir/progress.make b/Legacy/ws_linux/build/rosaria/CMakeFiles/roscpp_generate_messages_py.dir/progress.make new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/roscpp_generate_messages_py.dir/progress.make @@ -0,0 +1 @@ + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/rosgraph_msgs_generate_messages_cpp.dir/DependInfo.cmake b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosgraph_msgs_generate_messages_cpp.dir/DependInfo.cmake new file mode 100644 index 0000000..85f8501 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosgraph_msgs_generate_messages_cpp.dir/DependInfo.cmake @@ -0,0 +1,16 @@ +# The set of languages for which implicit dependencies are needed: +SET(CMAKE_DEPENDS_LANGUAGES + ) +# The set of files for implicit dependencies of each language: + +# Preprocessor definitions for this target. +SET(CMAKE_TARGET_DEFINITIONS + "ROS_BUILD_SHARED_LIBS=1" + "ROS_PACKAGE_NAME=\"rosaria\"" + "ROSCONSOLE_BACKEND_LOG4CXX" + "ADEPT_PKG" + ) + +# Targets to which this target links. +SET(CMAKE_TARGET_LINKED_INFO_FILES + ) diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/rosgraph_msgs_generate_messages_cpp.dir/build.make b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosgraph_msgs_generate_messages_cpp.dir/build.make new file mode 100644 index 0000000..14b9faf --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosgraph_msgs_generate_messages_cpp.dir/build.make @@ -0,0 +1,62 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/lab1_5/ws/ws_linux/src + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/lab1_5/ws/ws_linux/build + +# Utility rule file for rosgraph_msgs_generate_messages_cpp. + +# Include the progress variables for this target. +include rosaria/CMakeFiles/rosgraph_msgs_generate_messages_cpp.dir/progress.make + +rosaria/CMakeFiles/rosgraph_msgs_generate_messages_cpp: + +rosgraph_msgs_generate_messages_cpp: rosaria/CMakeFiles/rosgraph_msgs_generate_messages_cpp +rosgraph_msgs_generate_messages_cpp: rosaria/CMakeFiles/rosgraph_msgs_generate_messages_cpp.dir/build.make +.PHONY : rosgraph_msgs_generate_messages_cpp + +# Rule to build all files generated by this target. +rosaria/CMakeFiles/rosgraph_msgs_generate_messages_cpp.dir/build: rosgraph_msgs_generate_messages_cpp +.PHONY : rosaria/CMakeFiles/rosgraph_msgs_generate_messages_cpp.dir/build + +rosaria/CMakeFiles/rosgraph_msgs_generate_messages_cpp.dir/clean: + cd /home/lab1_5/ws/ws_linux/build/rosaria && $(CMAKE_COMMAND) -P CMakeFiles/rosgraph_msgs_generate_messages_cpp.dir/cmake_clean.cmake +.PHONY : rosaria/CMakeFiles/rosgraph_msgs_generate_messages_cpp.dir/clean + +rosaria/CMakeFiles/rosgraph_msgs_generate_messages_cpp.dir/depend: + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/lab1_5/ws/ws_linux/src /home/lab1_5/ws/ws_linux/src/rosaria /home/lab1_5/ws/ws_linux/build /home/lab1_5/ws/ws_linux/build/rosaria /home/lab1_5/ws/ws_linux/build/rosaria/CMakeFiles/rosgraph_msgs_generate_messages_cpp.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : rosaria/CMakeFiles/rosgraph_msgs_generate_messages_cpp.dir/depend + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/rosgraph_msgs_generate_messages_cpp.dir/cmake_clean.cmake b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosgraph_msgs_generate_messages_cpp.dir/cmake_clean.cmake new file mode 100644 index 0000000..eff4ce5 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosgraph_msgs_generate_messages_cpp.dir/cmake_clean.cmake @@ -0,0 +1,8 @@ +FILE(REMOVE_RECURSE + "CMakeFiles/rosgraph_msgs_generate_messages_cpp" +) + +# Per-language clean rules from dependency scanning. +FOREACH(lang) + INCLUDE(CMakeFiles/rosgraph_msgs_generate_messages_cpp.dir/cmake_clean_${lang}.cmake OPTIONAL) +ENDFOREACH(lang) diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/rosgraph_msgs_generate_messages_cpp.dir/progress.make b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosgraph_msgs_generate_messages_cpp.dir/progress.make new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosgraph_msgs_generate_messages_cpp.dir/progress.make @@ -0,0 +1 @@ + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/rosgraph_msgs_generate_messages_lisp.dir/DependInfo.cmake b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosgraph_msgs_generate_messages_lisp.dir/DependInfo.cmake new file mode 100644 index 0000000..85f8501 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosgraph_msgs_generate_messages_lisp.dir/DependInfo.cmake @@ -0,0 +1,16 @@ +# The set of languages for which implicit dependencies are needed: +SET(CMAKE_DEPENDS_LANGUAGES + ) +# The set of files for implicit dependencies of each language: + +# Preprocessor definitions for this target. +SET(CMAKE_TARGET_DEFINITIONS + "ROS_BUILD_SHARED_LIBS=1" + "ROS_PACKAGE_NAME=\"rosaria\"" + "ROSCONSOLE_BACKEND_LOG4CXX" + "ADEPT_PKG" + ) + +# Targets to which this target links. +SET(CMAKE_TARGET_LINKED_INFO_FILES + ) diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/rosgraph_msgs_generate_messages_lisp.dir/build.make b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosgraph_msgs_generate_messages_lisp.dir/build.make new file mode 100644 index 0000000..e8a4be7 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosgraph_msgs_generate_messages_lisp.dir/build.make @@ -0,0 +1,62 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/lab1_5/ws/ws_linux/src + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/lab1_5/ws/ws_linux/build + +# Utility rule file for rosgraph_msgs_generate_messages_lisp. + +# Include the progress variables for this target. +include rosaria/CMakeFiles/rosgraph_msgs_generate_messages_lisp.dir/progress.make + +rosaria/CMakeFiles/rosgraph_msgs_generate_messages_lisp: + +rosgraph_msgs_generate_messages_lisp: rosaria/CMakeFiles/rosgraph_msgs_generate_messages_lisp +rosgraph_msgs_generate_messages_lisp: rosaria/CMakeFiles/rosgraph_msgs_generate_messages_lisp.dir/build.make +.PHONY : rosgraph_msgs_generate_messages_lisp + +# Rule to build all files generated by this target. +rosaria/CMakeFiles/rosgraph_msgs_generate_messages_lisp.dir/build: rosgraph_msgs_generate_messages_lisp +.PHONY : rosaria/CMakeFiles/rosgraph_msgs_generate_messages_lisp.dir/build + +rosaria/CMakeFiles/rosgraph_msgs_generate_messages_lisp.dir/clean: + cd /home/lab1_5/ws/ws_linux/build/rosaria && $(CMAKE_COMMAND) -P CMakeFiles/rosgraph_msgs_generate_messages_lisp.dir/cmake_clean.cmake +.PHONY : rosaria/CMakeFiles/rosgraph_msgs_generate_messages_lisp.dir/clean + +rosaria/CMakeFiles/rosgraph_msgs_generate_messages_lisp.dir/depend: + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/lab1_5/ws/ws_linux/src /home/lab1_5/ws/ws_linux/src/rosaria /home/lab1_5/ws/ws_linux/build /home/lab1_5/ws/ws_linux/build/rosaria /home/lab1_5/ws/ws_linux/build/rosaria/CMakeFiles/rosgraph_msgs_generate_messages_lisp.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : rosaria/CMakeFiles/rosgraph_msgs_generate_messages_lisp.dir/depend + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/rosgraph_msgs_generate_messages_lisp.dir/cmake_clean.cmake b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosgraph_msgs_generate_messages_lisp.dir/cmake_clean.cmake new file mode 100644 index 0000000..122b942 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosgraph_msgs_generate_messages_lisp.dir/cmake_clean.cmake @@ -0,0 +1,8 @@ +FILE(REMOVE_RECURSE + "CMakeFiles/rosgraph_msgs_generate_messages_lisp" +) + +# Per-language clean rules from dependency scanning. +FOREACH(lang) + INCLUDE(CMakeFiles/rosgraph_msgs_generate_messages_lisp.dir/cmake_clean_${lang}.cmake OPTIONAL) +ENDFOREACH(lang) diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/rosgraph_msgs_generate_messages_lisp.dir/progress.make b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosgraph_msgs_generate_messages_lisp.dir/progress.make new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosgraph_msgs_generate_messages_lisp.dir/progress.make @@ -0,0 +1 @@ + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/rosgraph_msgs_generate_messages_py.dir/DependInfo.cmake b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosgraph_msgs_generate_messages_py.dir/DependInfo.cmake new file mode 100644 index 0000000..85f8501 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosgraph_msgs_generate_messages_py.dir/DependInfo.cmake @@ -0,0 +1,16 @@ +# The set of languages for which implicit dependencies are needed: +SET(CMAKE_DEPENDS_LANGUAGES + ) +# The set of files for implicit dependencies of each language: + +# Preprocessor definitions for this target. +SET(CMAKE_TARGET_DEFINITIONS + "ROS_BUILD_SHARED_LIBS=1" + "ROS_PACKAGE_NAME=\"rosaria\"" + "ROSCONSOLE_BACKEND_LOG4CXX" + "ADEPT_PKG" + ) + +# Targets to which this target links. +SET(CMAKE_TARGET_LINKED_INFO_FILES + ) diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/rosgraph_msgs_generate_messages_py.dir/build.make b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosgraph_msgs_generate_messages_py.dir/build.make new file mode 100644 index 0000000..81a50a6 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosgraph_msgs_generate_messages_py.dir/build.make @@ -0,0 +1,62 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/lab1_5/ws/ws_linux/src + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/lab1_5/ws/ws_linux/build + +# Utility rule file for rosgraph_msgs_generate_messages_py. + +# Include the progress variables for this target. +include rosaria/CMakeFiles/rosgraph_msgs_generate_messages_py.dir/progress.make + +rosaria/CMakeFiles/rosgraph_msgs_generate_messages_py: + +rosgraph_msgs_generate_messages_py: rosaria/CMakeFiles/rosgraph_msgs_generate_messages_py +rosgraph_msgs_generate_messages_py: rosaria/CMakeFiles/rosgraph_msgs_generate_messages_py.dir/build.make +.PHONY : rosgraph_msgs_generate_messages_py + +# Rule to build all files generated by this target. +rosaria/CMakeFiles/rosgraph_msgs_generate_messages_py.dir/build: rosgraph_msgs_generate_messages_py +.PHONY : rosaria/CMakeFiles/rosgraph_msgs_generate_messages_py.dir/build + +rosaria/CMakeFiles/rosgraph_msgs_generate_messages_py.dir/clean: + cd /home/lab1_5/ws/ws_linux/build/rosaria && $(CMAKE_COMMAND) -P CMakeFiles/rosgraph_msgs_generate_messages_py.dir/cmake_clean.cmake +.PHONY : rosaria/CMakeFiles/rosgraph_msgs_generate_messages_py.dir/clean + +rosaria/CMakeFiles/rosgraph_msgs_generate_messages_py.dir/depend: + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/lab1_5/ws/ws_linux/src /home/lab1_5/ws/ws_linux/src/rosaria /home/lab1_5/ws/ws_linux/build /home/lab1_5/ws/ws_linux/build/rosaria /home/lab1_5/ws/ws_linux/build/rosaria/CMakeFiles/rosgraph_msgs_generate_messages_py.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : rosaria/CMakeFiles/rosgraph_msgs_generate_messages_py.dir/depend + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/rosgraph_msgs_generate_messages_py.dir/cmake_clean.cmake b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosgraph_msgs_generate_messages_py.dir/cmake_clean.cmake new file mode 100644 index 0000000..f400201 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosgraph_msgs_generate_messages_py.dir/cmake_clean.cmake @@ -0,0 +1,8 @@ +FILE(REMOVE_RECURSE + "CMakeFiles/rosgraph_msgs_generate_messages_py" +) + +# Per-language clean rules from dependency scanning. +FOREACH(lang) + INCLUDE(CMakeFiles/rosgraph_msgs_generate_messages_py.dir/cmake_clean_${lang}.cmake OPTIONAL) +ENDFOREACH(lang) diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/rosgraph_msgs_generate_messages_py.dir/progress.make b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosgraph_msgs_generate_messages_py.dir/progress.make new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/rosgraph_msgs_generate_messages_py.dir/progress.make @@ -0,0 +1 @@ + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/sensor_msgs_generate_messages_cpp.dir/DependInfo.cmake b/Legacy/ws_linux/build/rosaria/CMakeFiles/sensor_msgs_generate_messages_cpp.dir/DependInfo.cmake new file mode 100644 index 0000000..85f8501 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/sensor_msgs_generate_messages_cpp.dir/DependInfo.cmake @@ -0,0 +1,16 @@ +# The set of languages for which implicit dependencies are needed: +SET(CMAKE_DEPENDS_LANGUAGES + ) +# The set of files for implicit dependencies of each language: + +# Preprocessor definitions for this target. +SET(CMAKE_TARGET_DEFINITIONS + "ROS_BUILD_SHARED_LIBS=1" + "ROS_PACKAGE_NAME=\"rosaria\"" + "ROSCONSOLE_BACKEND_LOG4CXX" + "ADEPT_PKG" + ) + +# Targets to which this target links. +SET(CMAKE_TARGET_LINKED_INFO_FILES + ) diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/sensor_msgs_generate_messages_cpp.dir/build.make b/Legacy/ws_linux/build/rosaria/CMakeFiles/sensor_msgs_generate_messages_cpp.dir/build.make new file mode 100644 index 0000000..8986ecc --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/sensor_msgs_generate_messages_cpp.dir/build.make @@ -0,0 +1,62 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/lab1_5/ws/ws_linux/src + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/lab1_5/ws/ws_linux/build + +# Utility rule file for sensor_msgs_generate_messages_cpp. + +# Include the progress variables for this target. +include rosaria/CMakeFiles/sensor_msgs_generate_messages_cpp.dir/progress.make + +rosaria/CMakeFiles/sensor_msgs_generate_messages_cpp: + +sensor_msgs_generate_messages_cpp: rosaria/CMakeFiles/sensor_msgs_generate_messages_cpp +sensor_msgs_generate_messages_cpp: rosaria/CMakeFiles/sensor_msgs_generate_messages_cpp.dir/build.make +.PHONY : sensor_msgs_generate_messages_cpp + +# Rule to build all files generated by this target. +rosaria/CMakeFiles/sensor_msgs_generate_messages_cpp.dir/build: sensor_msgs_generate_messages_cpp +.PHONY : rosaria/CMakeFiles/sensor_msgs_generate_messages_cpp.dir/build + +rosaria/CMakeFiles/sensor_msgs_generate_messages_cpp.dir/clean: + cd /home/lab1_5/ws/ws_linux/build/rosaria && $(CMAKE_COMMAND) -P CMakeFiles/sensor_msgs_generate_messages_cpp.dir/cmake_clean.cmake +.PHONY : rosaria/CMakeFiles/sensor_msgs_generate_messages_cpp.dir/clean + +rosaria/CMakeFiles/sensor_msgs_generate_messages_cpp.dir/depend: + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/lab1_5/ws/ws_linux/src /home/lab1_5/ws/ws_linux/src/rosaria /home/lab1_5/ws/ws_linux/build /home/lab1_5/ws/ws_linux/build/rosaria /home/lab1_5/ws/ws_linux/build/rosaria/CMakeFiles/sensor_msgs_generate_messages_cpp.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : rosaria/CMakeFiles/sensor_msgs_generate_messages_cpp.dir/depend + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/sensor_msgs_generate_messages_cpp.dir/cmake_clean.cmake b/Legacy/ws_linux/build/rosaria/CMakeFiles/sensor_msgs_generate_messages_cpp.dir/cmake_clean.cmake new file mode 100644 index 0000000..9a8c5d4 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/sensor_msgs_generate_messages_cpp.dir/cmake_clean.cmake @@ -0,0 +1,8 @@ +FILE(REMOVE_RECURSE + "CMakeFiles/sensor_msgs_generate_messages_cpp" +) + +# Per-language clean rules from dependency scanning. +FOREACH(lang) + INCLUDE(CMakeFiles/sensor_msgs_generate_messages_cpp.dir/cmake_clean_${lang}.cmake OPTIONAL) +ENDFOREACH(lang) diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/sensor_msgs_generate_messages_cpp.dir/progress.make b/Legacy/ws_linux/build/rosaria/CMakeFiles/sensor_msgs_generate_messages_cpp.dir/progress.make new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/sensor_msgs_generate_messages_cpp.dir/progress.make @@ -0,0 +1 @@ + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/sensor_msgs_generate_messages_lisp.dir/DependInfo.cmake b/Legacy/ws_linux/build/rosaria/CMakeFiles/sensor_msgs_generate_messages_lisp.dir/DependInfo.cmake new file mode 100644 index 0000000..85f8501 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/sensor_msgs_generate_messages_lisp.dir/DependInfo.cmake @@ -0,0 +1,16 @@ +# The set of languages for which implicit dependencies are needed: +SET(CMAKE_DEPENDS_LANGUAGES + ) +# The set of files for implicit dependencies of each language: + +# Preprocessor definitions for this target. +SET(CMAKE_TARGET_DEFINITIONS + "ROS_BUILD_SHARED_LIBS=1" + "ROS_PACKAGE_NAME=\"rosaria\"" + "ROSCONSOLE_BACKEND_LOG4CXX" + "ADEPT_PKG" + ) + +# Targets to which this target links. +SET(CMAKE_TARGET_LINKED_INFO_FILES + ) diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/sensor_msgs_generate_messages_lisp.dir/build.make b/Legacy/ws_linux/build/rosaria/CMakeFiles/sensor_msgs_generate_messages_lisp.dir/build.make new file mode 100644 index 0000000..7e12270 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/sensor_msgs_generate_messages_lisp.dir/build.make @@ -0,0 +1,62 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/lab1_5/ws/ws_linux/src + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/lab1_5/ws/ws_linux/build + +# Utility rule file for sensor_msgs_generate_messages_lisp. + +# Include the progress variables for this target. +include rosaria/CMakeFiles/sensor_msgs_generate_messages_lisp.dir/progress.make + +rosaria/CMakeFiles/sensor_msgs_generate_messages_lisp: + +sensor_msgs_generate_messages_lisp: rosaria/CMakeFiles/sensor_msgs_generate_messages_lisp +sensor_msgs_generate_messages_lisp: rosaria/CMakeFiles/sensor_msgs_generate_messages_lisp.dir/build.make +.PHONY : sensor_msgs_generate_messages_lisp + +# Rule to build all files generated by this target. +rosaria/CMakeFiles/sensor_msgs_generate_messages_lisp.dir/build: sensor_msgs_generate_messages_lisp +.PHONY : rosaria/CMakeFiles/sensor_msgs_generate_messages_lisp.dir/build + +rosaria/CMakeFiles/sensor_msgs_generate_messages_lisp.dir/clean: + cd /home/lab1_5/ws/ws_linux/build/rosaria && $(CMAKE_COMMAND) -P CMakeFiles/sensor_msgs_generate_messages_lisp.dir/cmake_clean.cmake +.PHONY : rosaria/CMakeFiles/sensor_msgs_generate_messages_lisp.dir/clean + +rosaria/CMakeFiles/sensor_msgs_generate_messages_lisp.dir/depend: + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/lab1_5/ws/ws_linux/src /home/lab1_5/ws/ws_linux/src/rosaria /home/lab1_5/ws/ws_linux/build /home/lab1_5/ws/ws_linux/build/rosaria /home/lab1_5/ws/ws_linux/build/rosaria/CMakeFiles/sensor_msgs_generate_messages_lisp.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : rosaria/CMakeFiles/sensor_msgs_generate_messages_lisp.dir/depend + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/sensor_msgs_generate_messages_lisp.dir/cmake_clean.cmake b/Legacy/ws_linux/build/rosaria/CMakeFiles/sensor_msgs_generate_messages_lisp.dir/cmake_clean.cmake new file mode 100644 index 0000000..5fe672b --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/sensor_msgs_generate_messages_lisp.dir/cmake_clean.cmake @@ -0,0 +1,8 @@ +FILE(REMOVE_RECURSE + "CMakeFiles/sensor_msgs_generate_messages_lisp" +) + +# Per-language clean rules from dependency scanning. +FOREACH(lang) + INCLUDE(CMakeFiles/sensor_msgs_generate_messages_lisp.dir/cmake_clean_${lang}.cmake OPTIONAL) +ENDFOREACH(lang) diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/sensor_msgs_generate_messages_lisp.dir/progress.make b/Legacy/ws_linux/build/rosaria/CMakeFiles/sensor_msgs_generate_messages_lisp.dir/progress.make new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/sensor_msgs_generate_messages_lisp.dir/progress.make @@ -0,0 +1 @@ + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/sensor_msgs_generate_messages_py.dir/DependInfo.cmake b/Legacy/ws_linux/build/rosaria/CMakeFiles/sensor_msgs_generate_messages_py.dir/DependInfo.cmake new file mode 100644 index 0000000..85f8501 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/sensor_msgs_generate_messages_py.dir/DependInfo.cmake @@ -0,0 +1,16 @@ +# The set of languages for which implicit dependencies are needed: +SET(CMAKE_DEPENDS_LANGUAGES + ) +# The set of files for implicit dependencies of each language: + +# Preprocessor definitions for this target. +SET(CMAKE_TARGET_DEFINITIONS + "ROS_BUILD_SHARED_LIBS=1" + "ROS_PACKAGE_NAME=\"rosaria\"" + "ROSCONSOLE_BACKEND_LOG4CXX" + "ADEPT_PKG" + ) + +# Targets to which this target links. +SET(CMAKE_TARGET_LINKED_INFO_FILES + ) diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/sensor_msgs_generate_messages_py.dir/build.make b/Legacy/ws_linux/build/rosaria/CMakeFiles/sensor_msgs_generate_messages_py.dir/build.make new file mode 100644 index 0000000..64053b6 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/sensor_msgs_generate_messages_py.dir/build.make @@ -0,0 +1,62 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/lab1_5/ws/ws_linux/src + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/lab1_5/ws/ws_linux/build + +# Utility rule file for sensor_msgs_generate_messages_py. + +# Include the progress variables for this target. +include rosaria/CMakeFiles/sensor_msgs_generate_messages_py.dir/progress.make + +rosaria/CMakeFiles/sensor_msgs_generate_messages_py: + +sensor_msgs_generate_messages_py: rosaria/CMakeFiles/sensor_msgs_generate_messages_py +sensor_msgs_generate_messages_py: rosaria/CMakeFiles/sensor_msgs_generate_messages_py.dir/build.make +.PHONY : sensor_msgs_generate_messages_py + +# Rule to build all files generated by this target. +rosaria/CMakeFiles/sensor_msgs_generate_messages_py.dir/build: sensor_msgs_generate_messages_py +.PHONY : rosaria/CMakeFiles/sensor_msgs_generate_messages_py.dir/build + +rosaria/CMakeFiles/sensor_msgs_generate_messages_py.dir/clean: + cd /home/lab1_5/ws/ws_linux/build/rosaria && $(CMAKE_COMMAND) -P CMakeFiles/sensor_msgs_generate_messages_py.dir/cmake_clean.cmake +.PHONY : rosaria/CMakeFiles/sensor_msgs_generate_messages_py.dir/clean + +rosaria/CMakeFiles/sensor_msgs_generate_messages_py.dir/depend: + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/lab1_5/ws/ws_linux/src /home/lab1_5/ws/ws_linux/src/rosaria /home/lab1_5/ws/ws_linux/build /home/lab1_5/ws/ws_linux/build/rosaria /home/lab1_5/ws/ws_linux/build/rosaria/CMakeFiles/sensor_msgs_generate_messages_py.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : rosaria/CMakeFiles/sensor_msgs_generate_messages_py.dir/depend + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/sensor_msgs_generate_messages_py.dir/cmake_clean.cmake b/Legacy/ws_linux/build/rosaria/CMakeFiles/sensor_msgs_generate_messages_py.dir/cmake_clean.cmake new file mode 100644 index 0000000..87f1fb0 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/sensor_msgs_generate_messages_py.dir/cmake_clean.cmake @@ -0,0 +1,8 @@ +FILE(REMOVE_RECURSE + "CMakeFiles/sensor_msgs_generate_messages_py" +) + +# Per-language clean rules from dependency scanning. +FOREACH(lang) + INCLUDE(CMakeFiles/sensor_msgs_generate_messages_py.dir/cmake_clean_${lang}.cmake OPTIONAL) +ENDFOREACH(lang) diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/sensor_msgs_generate_messages_py.dir/progress.make b/Legacy/ws_linux/build/rosaria/CMakeFiles/sensor_msgs_generate_messages_py.dir/progress.make new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/sensor_msgs_generate_messages_py.dir/progress.make @@ -0,0 +1 @@ + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/tf2_msgs_generate_messages_cpp.dir/DependInfo.cmake b/Legacy/ws_linux/build/rosaria/CMakeFiles/tf2_msgs_generate_messages_cpp.dir/DependInfo.cmake new file mode 100644 index 0000000..85f8501 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/tf2_msgs_generate_messages_cpp.dir/DependInfo.cmake @@ -0,0 +1,16 @@ +# The set of languages for which implicit dependencies are needed: +SET(CMAKE_DEPENDS_LANGUAGES + ) +# The set of files for implicit dependencies of each language: + +# Preprocessor definitions for this target. +SET(CMAKE_TARGET_DEFINITIONS + "ROS_BUILD_SHARED_LIBS=1" + "ROS_PACKAGE_NAME=\"rosaria\"" + "ROSCONSOLE_BACKEND_LOG4CXX" + "ADEPT_PKG" + ) + +# Targets to which this target links. +SET(CMAKE_TARGET_LINKED_INFO_FILES + ) diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/tf2_msgs_generate_messages_cpp.dir/build.make b/Legacy/ws_linux/build/rosaria/CMakeFiles/tf2_msgs_generate_messages_cpp.dir/build.make new file mode 100644 index 0000000..a898e03 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/tf2_msgs_generate_messages_cpp.dir/build.make @@ -0,0 +1,62 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/lab1_5/ws/ws_linux/src + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/lab1_5/ws/ws_linux/build + +# Utility rule file for tf2_msgs_generate_messages_cpp. + +# Include the progress variables for this target. +include rosaria/CMakeFiles/tf2_msgs_generate_messages_cpp.dir/progress.make + +rosaria/CMakeFiles/tf2_msgs_generate_messages_cpp: + +tf2_msgs_generate_messages_cpp: rosaria/CMakeFiles/tf2_msgs_generate_messages_cpp +tf2_msgs_generate_messages_cpp: rosaria/CMakeFiles/tf2_msgs_generate_messages_cpp.dir/build.make +.PHONY : tf2_msgs_generate_messages_cpp + +# Rule to build all files generated by this target. +rosaria/CMakeFiles/tf2_msgs_generate_messages_cpp.dir/build: tf2_msgs_generate_messages_cpp +.PHONY : rosaria/CMakeFiles/tf2_msgs_generate_messages_cpp.dir/build + +rosaria/CMakeFiles/tf2_msgs_generate_messages_cpp.dir/clean: + cd /home/lab1_5/ws/ws_linux/build/rosaria && $(CMAKE_COMMAND) -P CMakeFiles/tf2_msgs_generate_messages_cpp.dir/cmake_clean.cmake +.PHONY : rosaria/CMakeFiles/tf2_msgs_generate_messages_cpp.dir/clean + +rosaria/CMakeFiles/tf2_msgs_generate_messages_cpp.dir/depend: + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/lab1_5/ws/ws_linux/src /home/lab1_5/ws/ws_linux/src/rosaria /home/lab1_5/ws/ws_linux/build /home/lab1_5/ws/ws_linux/build/rosaria /home/lab1_5/ws/ws_linux/build/rosaria/CMakeFiles/tf2_msgs_generate_messages_cpp.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : rosaria/CMakeFiles/tf2_msgs_generate_messages_cpp.dir/depend + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/tf2_msgs_generate_messages_cpp.dir/cmake_clean.cmake b/Legacy/ws_linux/build/rosaria/CMakeFiles/tf2_msgs_generate_messages_cpp.dir/cmake_clean.cmake new file mode 100644 index 0000000..57143f9 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/tf2_msgs_generate_messages_cpp.dir/cmake_clean.cmake @@ -0,0 +1,8 @@ +FILE(REMOVE_RECURSE + "CMakeFiles/tf2_msgs_generate_messages_cpp" +) + +# Per-language clean rules from dependency scanning. +FOREACH(lang) + INCLUDE(CMakeFiles/tf2_msgs_generate_messages_cpp.dir/cmake_clean_${lang}.cmake OPTIONAL) +ENDFOREACH(lang) diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/tf2_msgs_generate_messages_cpp.dir/progress.make b/Legacy/ws_linux/build/rosaria/CMakeFiles/tf2_msgs_generate_messages_cpp.dir/progress.make new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/tf2_msgs_generate_messages_cpp.dir/progress.make @@ -0,0 +1 @@ + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/tf2_msgs_generate_messages_lisp.dir/DependInfo.cmake b/Legacy/ws_linux/build/rosaria/CMakeFiles/tf2_msgs_generate_messages_lisp.dir/DependInfo.cmake new file mode 100644 index 0000000..85f8501 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/tf2_msgs_generate_messages_lisp.dir/DependInfo.cmake @@ -0,0 +1,16 @@ +# The set of languages for which implicit dependencies are needed: +SET(CMAKE_DEPENDS_LANGUAGES + ) +# The set of files for implicit dependencies of each language: + +# Preprocessor definitions for this target. +SET(CMAKE_TARGET_DEFINITIONS + "ROS_BUILD_SHARED_LIBS=1" + "ROS_PACKAGE_NAME=\"rosaria\"" + "ROSCONSOLE_BACKEND_LOG4CXX" + "ADEPT_PKG" + ) + +# Targets to which this target links. +SET(CMAKE_TARGET_LINKED_INFO_FILES + ) diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/tf2_msgs_generate_messages_lisp.dir/build.make b/Legacy/ws_linux/build/rosaria/CMakeFiles/tf2_msgs_generate_messages_lisp.dir/build.make new file mode 100644 index 0000000..1edeaf4 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/tf2_msgs_generate_messages_lisp.dir/build.make @@ -0,0 +1,62 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/lab1_5/ws/ws_linux/src + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/lab1_5/ws/ws_linux/build + +# Utility rule file for tf2_msgs_generate_messages_lisp. + +# Include the progress variables for this target. +include rosaria/CMakeFiles/tf2_msgs_generate_messages_lisp.dir/progress.make + +rosaria/CMakeFiles/tf2_msgs_generate_messages_lisp: + +tf2_msgs_generate_messages_lisp: rosaria/CMakeFiles/tf2_msgs_generate_messages_lisp +tf2_msgs_generate_messages_lisp: rosaria/CMakeFiles/tf2_msgs_generate_messages_lisp.dir/build.make +.PHONY : tf2_msgs_generate_messages_lisp + +# Rule to build all files generated by this target. +rosaria/CMakeFiles/tf2_msgs_generate_messages_lisp.dir/build: tf2_msgs_generate_messages_lisp +.PHONY : rosaria/CMakeFiles/tf2_msgs_generate_messages_lisp.dir/build + +rosaria/CMakeFiles/tf2_msgs_generate_messages_lisp.dir/clean: + cd /home/lab1_5/ws/ws_linux/build/rosaria && $(CMAKE_COMMAND) -P CMakeFiles/tf2_msgs_generate_messages_lisp.dir/cmake_clean.cmake +.PHONY : rosaria/CMakeFiles/tf2_msgs_generate_messages_lisp.dir/clean + +rosaria/CMakeFiles/tf2_msgs_generate_messages_lisp.dir/depend: + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/lab1_5/ws/ws_linux/src /home/lab1_5/ws/ws_linux/src/rosaria /home/lab1_5/ws/ws_linux/build /home/lab1_5/ws/ws_linux/build/rosaria /home/lab1_5/ws/ws_linux/build/rosaria/CMakeFiles/tf2_msgs_generate_messages_lisp.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : rosaria/CMakeFiles/tf2_msgs_generate_messages_lisp.dir/depend + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/tf2_msgs_generate_messages_lisp.dir/cmake_clean.cmake b/Legacy/ws_linux/build/rosaria/CMakeFiles/tf2_msgs_generate_messages_lisp.dir/cmake_clean.cmake new file mode 100644 index 0000000..bba5b76 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/tf2_msgs_generate_messages_lisp.dir/cmake_clean.cmake @@ -0,0 +1,8 @@ +FILE(REMOVE_RECURSE + "CMakeFiles/tf2_msgs_generate_messages_lisp" +) + +# Per-language clean rules from dependency scanning. +FOREACH(lang) + INCLUDE(CMakeFiles/tf2_msgs_generate_messages_lisp.dir/cmake_clean_${lang}.cmake OPTIONAL) +ENDFOREACH(lang) diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/tf2_msgs_generate_messages_lisp.dir/progress.make b/Legacy/ws_linux/build/rosaria/CMakeFiles/tf2_msgs_generate_messages_lisp.dir/progress.make new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/tf2_msgs_generate_messages_lisp.dir/progress.make @@ -0,0 +1 @@ + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/tf2_msgs_generate_messages_py.dir/DependInfo.cmake b/Legacy/ws_linux/build/rosaria/CMakeFiles/tf2_msgs_generate_messages_py.dir/DependInfo.cmake new file mode 100644 index 0000000..85f8501 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/tf2_msgs_generate_messages_py.dir/DependInfo.cmake @@ -0,0 +1,16 @@ +# The set of languages for which implicit dependencies are needed: +SET(CMAKE_DEPENDS_LANGUAGES + ) +# The set of files for implicit dependencies of each language: + +# Preprocessor definitions for this target. +SET(CMAKE_TARGET_DEFINITIONS + "ROS_BUILD_SHARED_LIBS=1" + "ROS_PACKAGE_NAME=\"rosaria\"" + "ROSCONSOLE_BACKEND_LOG4CXX" + "ADEPT_PKG" + ) + +# Targets to which this target links. +SET(CMAKE_TARGET_LINKED_INFO_FILES + ) diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/tf2_msgs_generate_messages_py.dir/build.make b/Legacy/ws_linux/build/rosaria/CMakeFiles/tf2_msgs_generate_messages_py.dir/build.make new file mode 100644 index 0000000..763c4b1 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/tf2_msgs_generate_messages_py.dir/build.make @@ -0,0 +1,62 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/lab1_5/ws/ws_linux/src + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/lab1_5/ws/ws_linux/build + +# Utility rule file for tf2_msgs_generate_messages_py. + +# Include the progress variables for this target. +include rosaria/CMakeFiles/tf2_msgs_generate_messages_py.dir/progress.make + +rosaria/CMakeFiles/tf2_msgs_generate_messages_py: + +tf2_msgs_generate_messages_py: rosaria/CMakeFiles/tf2_msgs_generate_messages_py +tf2_msgs_generate_messages_py: rosaria/CMakeFiles/tf2_msgs_generate_messages_py.dir/build.make +.PHONY : tf2_msgs_generate_messages_py + +# Rule to build all files generated by this target. +rosaria/CMakeFiles/tf2_msgs_generate_messages_py.dir/build: tf2_msgs_generate_messages_py +.PHONY : rosaria/CMakeFiles/tf2_msgs_generate_messages_py.dir/build + +rosaria/CMakeFiles/tf2_msgs_generate_messages_py.dir/clean: + cd /home/lab1_5/ws/ws_linux/build/rosaria && $(CMAKE_COMMAND) -P CMakeFiles/tf2_msgs_generate_messages_py.dir/cmake_clean.cmake +.PHONY : rosaria/CMakeFiles/tf2_msgs_generate_messages_py.dir/clean + +rosaria/CMakeFiles/tf2_msgs_generate_messages_py.dir/depend: + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/lab1_5/ws/ws_linux/src /home/lab1_5/ws/ws_linux/src/rosaria /home/lab1_5/ws/ws_linux/build /home/lab1_5/ws/ws_linux/build/rosaria /home/lab1_5/ws/ws_linux/build/rosaria/CMakeFiles/tf2_msgs_generate_messages_py.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : rosaria/CMakeFiles/tf2_msgs_generate_messages_py.dir/depend + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/tf2_msgs_generate_messages_py.dir/cmake_clean.cmake b/Legacy/ws_linux/build/rosaria/CMakeFiles/tf2_msgs_generate_messages_py.dir/cmake_clean.cmake new file mode 100644 index 0000000..cd378c0 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/tf2_msgs_generate_messages_py.dir/cmake_clean.cmake @@ -0,0 +1,8 @@ +FILE(REMOVE_RECURSE + "CMakeFiles/tf2_msgs_generate_messages_py" +) + +# Per-language clean rules from dependency scanning. +FOREACH(lang) + INCLUDE(CMakeFiles/tf2_msgs_generate_messages_py.dir/cmake_clean_${lang}.cmake OPTIONAL) +ENDFOREACH(lang) diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/tf2_msgs_generate_messages_py.dir/progress.make b/Legacy/ws_linux/build/rosaria/CMakeFiles/tf2_msgs_generate_messages_py.dir/progress.make new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/tf2_msgs_generate_messages_py.dir/progress.make @@ -0,0 +1 @@ + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/tf_generate_messages_cpp.dir/DependInfo.cmake b/Legacy/ws_linux/build/rosaria/CMakeFiles/tf_generate_messages_cpp.dir/DependInfo.cmake new file mode 100644 index 0000000..85f8501 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/tf_generate_messages_cpp.dir/DependInfo.cmake @@ -0,0 +1,16 @@ +# The set of languages for which implicit dependencies are needed: +SET(CMAKE_DEPENDS_LANGUAGES + ) +# The set of files for implicit dependencies of each language: + +# Preprocessor definitions for this target. +SET(CMAKE_TARGET_DEFINITIONS + "ROS_BUILD_SHARED_LIBS=1" + "ROS_PACKAGE_NAME=\"rosaria\"" + "ROSCONSOLE_BACKEND_LOG4CXX" + "ADEPT_PKG" + ) + +# Targets to which this target links. +SET(CMAKE_TARGET_LINKED_INFO_FILES + ) diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/tf_generate_messages_cpp.dir/build.make b/Legacy/ws_linux/build/rosaria/CMakeFiles/tf_generate_messages_cpp.dir/build.make new file mode 100644 index 0000000..15b95ff --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/tf_generate_messages_cpp.dir/build.make @@ -0,0 +1,62 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/lab1_5/ws/ws_linux/src + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/lab1_5/ws/ws_linux/build + +# Utility rule file for tf_generate_messages_cpp. + +# Include the progress variables for this target. +include rosaria/CMakeFiles/tf_generate_messages_cpp.dir/progress.make + +rosaria/CMakeFiles/tf_generate_messages_cpp: + +tf_generate_messages_cpp: rosaria/CMakeFiles/tf_generate_messages_cpp +tf_generate_messages_cpp: rosaria/CMakeFiles/tf_generate_messages_cpp.dir/build.make +.PHONY : tf_generate_messages_cpp + +# Rule to build all files generated by this target. +rosaria/CMakeFiles/tf_generate_messages_cpp.dir/build: tf_generate_messages_cpp +.PHONY : rosaria/CMakeFiles/tf_generate_messages_cpp.dir/build + +rosaria/CMakeFiles/tf_generate_messages_cpp.dir/clean: + cd /home/lab1_5/ws/ws_linux/build/rosaria && $(CMAKE_COMMAND) -P CMakeFiles/tf_generate_messages_cpp.dir/cmake_clean.cmake +.PHONY : rosaria/CMakeFiles/tf_generate_messages_cpp.dir/clean + +rosaria/CMakeFiles/tf_generate_messages_cpp.dir/depend: + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/lab1_5/ws/ws_linux/src /home/lab1_5/ws/ws_linux/src/rosaria /home/lab1_5/ws/ws_linux/build /home/lab1_5/ws/ws_linux/build/rosaria /home/lab1_5/ws/ws_linux/build/rosaria/CMakeFiles/tf_generate_messages_cpp.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : rosaria/CMakeFiles/tf_generate_messages_cpp.dir/depend + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/tf_generate_messages_cpp.dir/cmake_clean.cmake b/Legacy/ws_linux/build/rosaria/CMakeFiles/tf_generate_messages_cpp.dir/cmake_clean.cmake new file mode 100644 index 0000000..2ac63b1 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/tf_generate_messages_cpp.dir/cmake_clean.cmake @@ -0,0 +1,8 @@ +FILE(REMOVE_RECURSE + "CMakeFiles/tf_generate_messages_cpp" +) + +# Per-language clean rules from dependency scanning. +FOREACH(lang) + INCLUDE(CMakeFiles/tf_generate_messages_cpp.dir/cmake_clean_${lang}.cmake OPTIONAL) +ENDFOREACH(lang) diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/tf_generate_messages_cpp.dir/progress.make b/Legacy/ws_linux/build/rosaria/CMakeFiles/tf_generate_messages_cpp.dir/progress.make new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/tf_generate_messages_cpp.dir/progress.make @@ -0,0 +1 @@ + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/tf_generate_messages_lisp.dir/DependInfo.cmake b/Legacy/ws_linux/build/rosaria/CMakeFiles/tf_generate_messages_lisp.dir/DependInfo.cmake new file mode 100644 index 0000000..85f8501 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/tf_generate_messages_lisp.dir/DependInfo.cmake @@ -0,0 +1,16 @@ +# The set of languages for which implicit dependencies are needed: +SET(CMAKE_DEPENDS_LANGUAGES + ) +# The set of files for implicit dependencies of each language: + +# Preprocessor definitions for this target. +SET(CMAKE_TARGET_DEFINITIONS + "ROS_BUILD_SHARED_LIBS=1" + "ROS_PACKAGE_NAME=\"rosaria\"" + "ROSCONSOLE_BACKEND_LOG4CXX" + "ADEPT_PKG" + ) + +# Targets to which this target links. +SET(CMAKE_TARGET_LINKED_INFO_FILES + ) diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/tf_generate_messages_lisp.dir/build.make b/Legacy/ws_linux/build/rosaria/CMakeFiles/tf_generate_messages_lisp.dir/build.make new file mode 100644 index 0000000..d91f90a --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/tf_generate_messages_lisp.dir/build.make @@ -0,0 +1,62 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/lab1_5/ws/ws_linux/src + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/lab1_5/ws/ws_linux/build + +# Utility rule file for tf_generate_messages_lisp. + +# Include the progress variables for this target. +include rosaria/CMakeFiles/tf_generate_messages_lisp.dir/progress.make + +rosaria/CMakeFiles/tf_generate_messages_lisp: + +tf_generate_messages_lisp: rosaria/CMakeFiles/tf_generate_messages_lisp +tf_generate_messages_lisp: rosaria/CMakeFiles/tf_generate_messages_lisp.dir/build.make +.PHONY : tf_generate_messages_lisp + +# Rule to build all files generated by this target. +rosaria/CMakeFiles/tf_generate_messages_lisp.dir/build: tf_generate_messages_lisp +.PHONY : rosaria/CMakeFiles/tf_generate_messages_lisp.dir/build + +rosaria/CMakeFiles/tf_generate_messages_lisp.dir/clean: + cd /home/lab1_5/ws/ws_linux/build/rosaria && $(CMAKE_COMMAND) -P CMakeFiles/tf_generate_messages_lisp.dir/cmake_clean.cmake +.PHONY : rosaria/CMakeFiles/tf_generate_messages_lisp.dir/clean + +rosaria/CMakeFiles/tf_generate_messages_lisp.dir/depend: + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/lab1_5/ws/ws_linux/src /home/lab1_5/ws/ws_linux/src/rosaria /home/lab1_5/ws/ws_linux/build /home/lab1_5/ws/ws_linux/build/rosaria /home/lab1_5/ws/ws_linux/build/rosaria/CMakeFiles/tf_generate_messages_lisp.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : rosaria/CMakeFiles/tf_generate_messages_lisp.dir/depend + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/tf_generate_messages_lisp.dir/cmake_clean.cmake b/Legacy/ws_linux/build/rosaria/CMakeFiles/tf_generate_messages_lisp.dir/cmake_clean.cmake new file mode 100644 index 0000000..1c7d7e3 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/tf_generate_messages_lisp.dir/cmake_clean.cmake @@ -0,0 +1,8 @@ +FILE(REMOVE_RECURSE + "CMakeFiles/tf_generate_messages_lisp" +) + +# Per-language clean rules from dependency scanning. +FOREACH(lang) + INCLUDE(CMakeFiles/tf_generate_messages_lisp.dir/cmake_clean_${lang}.cmake OPTIONAL) +ENDFOREACH(lang) diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/tf_generate_messages_lisp.dir/progress.make b/Legacy/ws_linux/build/rosaria/CMakeFiles/tf_generate_messages_lisp.dir/progress.make new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/tf_generate_messages_lisp.dir/progress.make @@ -0,0 +1 @@ + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/tf_generate_messages_py.dir/DependInfo.cmake b/Legacy/ws_linux/build/rosaria/CMakeFiles/tf_generate_messages_py.dir/DependInfo.cmake new file mode 100644 index 0000000..85f8501 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/tf_generate_messages_py.dir/DependInfo.cmake @@ -0,0 +1,16 @@ +# The set of languages for which implicit dependencies are needed: +SET(CMAKE_DEPENDS_LANGUAGES + ) +# The set of files for implicit dependencies of each language: + +# Preprocessor definitions for this target. +SET(CMAKE_TARGET_DEFINITIONS + "ROS_BUILD_SHARED_LIBS=1" + "ROS_PACKAGE_NAME=\"rosaria\"" + "ROSCONSOLE_BACKEND_LOG4CXX" + "ADEPT_PKG" + ) + +# Targets to which this target links. +SET(CMAKE_TARGET_LINKED_INFO_FILES + ) diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/tf_generate_messages_py.dir/build.make b/Legacy/ws_linux/build/rosaria/CMakeFiles/tf_generate_messages_py.dir/build.make new file mode 100644 index 0000000..9853601 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/tf_generate_messages_py.dir/build.make @@ -0,0 +1,62 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/lab1_5/ws/ws_linux/src + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/lab1_5/ws/ws_linux/build + +# Utility rule file for tf_generate_messages_py. + +# Include the progress variables for this target. +include rosaria/CMakeFiles/tf_generate_messages_py.dir/progress.make + +rosaria/CMakeFiles/tf_generate_messages_py: + +tf_generate_messages_py: rosaria/CMakeFiles/tf_generate_messages_py +tf_generate_messages_py: rosaria/CMakeFiles/tf_generate_messages_py.dir/build.make +.PHONY : tf_generate_messages_py + +# Rule to build all files generated by this target. +rosaria/CMakeFiles/tf_generate_messages_py.dir/build: tf_generate_messages_py +.PHONY : rosaria/CMakeFiles/tf_generate_messages_py.dir/build + +rosaria/CMakeFiles/tf_generate_messages_py.dir/clean: + cd /home/lab1_5/ws/ws_linux/build/rosaria && $(CMAKE_COMMAND) -P CMakeFiles/tf_generate_messages_py.dir/cmake_clean.cmake +.PHONY : rosaria/CMakeFiles/tf_generate_messages_py.dir/clean + +rosaria/CMakeFiles/tf_generate_messages_py.dir/depend: + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/lab1_5/ws/ws_linux/src /home/lab1_5/ws/ws_linux/src/rosaria /home/lab1_5/ws/ws_linux/build /home/lab1_5/ws/ws_linux/build/rosaria /home/lab1_5/ws/ws_linux/build/rosaria/CMakeFiles/tf_generate_messages_py.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : rosaria/CMakeFiles/tf_generate_messages_py.dir/depend + diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/tf_generate_messages_py.dir/cmake_clean.cmake b/Legacy/ws_linux/build/rosaria/CMakeFiles/tf_generate_messages_py.dir/cmake_clean.cmake new file mode 100644 index 0000000..4b74511 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/tf_generate_messages_py.dir/cmake_clean.cmake @@ -0,0 +1,8 @@ +FILE(REMOVE_RECURSE + "CMakeFiles/tf_generate_messages_py" +) + +# Per-language clean rules from dependency scanning. +FOREACH(lang) + INCLUDE(CMakeFiles/tf_generate_messages_py.dir/cmake_clean_${lang}.cmake OPTIONAL) +ENDFOREACH(lang) diff --git a/Legacy/ws_linux/build/rosaria/CMakeFiles/tf_generate_messages_py.dir/progress.make b/Legacy/ws_linux/build/rosaria/CMakeFiles/tf_generate_messages_py.dir/progress.make new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CMakeFiles/tf_generate_messages_py.dir/progress.make @@ -0,0 +1 @@ + diff --git a/Legacy/ws_linux/build/rosaria/CTestTestfile.cmake b/Legacy/ws_linux/build/rosaria/CTestTestfile.cmake new file mode 100644 index 0000000..212fa0f --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/CTestTestfile.cmake @@ -0,0 +1,6 @@ +# CMake generated Testfile for +# Source directory: /home/lab1_5/ws/ws_linux/src/rosaria +# Build directory: /home/lab1_5/ws/ws_linux/build/rosaria +# +# This file includes the relevent testing commands required for +# testing this directory and lists subdirectories to be tested as well. diff --git a/Legacy/ws_linux/build/rosaria/Makefile b/Legacy/ws_linux/build/rosaria/Makefile new file mode 100644 index 0000000..540843f --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/Makefile @@ -0,0 +1,757 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +# Default target executed when no arguments are given to make. +default_target: all +.PHONY : default_target + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/lab1_5/ws/ws_linux/src + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/lab1_5/ws/ws_linux/build + +#============================================================================= +# Targets provided globally by CMake. + +# Special rule for the target edit_cache +edit_cache: + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running interactive CMake command-line interface..." + /usr/bin/cmake -i . +.PHONY : edit_cache + +# Special rule for the target edit_cache +edit_cache/fast: edit_cache +.PHONY : edit_cache/fast + +# Special rule for the target install +install: preinstall + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Install the project..." + /usr/bin/cmake -P cmake_install.cmake +.PHONY : install + +# Special rule for the target install +install/fast: preinstall/fast + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Install the project..." + /usr/bin/cmake -P cmake_install.cmake +.PHONY : install/fast + +# Special rule for the target install/local +install/local: preinstall + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Installing only the local directory..." + /usr/bin/cmake -DCMAKE_INSTALL_LOCAL_ONLY=1 -P cmake_install.cmake +.PHONY : install/local + +# Special rule for the target install/local +install/local/fast: install/local +.PHONY : install/local/fast + +# Special rule for the target install/strip +install/strip: preinstall + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Installing the project stripped..." + /usr/bin/cmake -DCMAKE_INSTALL_DO_STRIP=1 -P cmake_install.cmake +.PHONY : install/strip + +# Special rule for the target install/strip +install/strip/fast: install/strip +.PHONY : install/strip/fast + +# Special rule for the target list_install_components +list_install_components: + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Available install components are: \"Unspecified\"" +.PHONY : list_install_components + +# Special rule for the target list_install_components +list_install_components/fast: list_install_components +.PHONY : list_install_components/fast + +# Special rule for the target rebuild_cache +rebuild_cache: + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running CMake to regenerate build system..." + /usr/bin/cmake -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) +.PHONY : rebuild_cache + +# Special rule for the target rebuild_cache +rebuild_cache/fast: rebuild_cache +.PHONY : rebuild_cache/fast + +# Special rule for the target test +test: + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running tests..." + /usr/bin/ctest --force-new-ctest-process $(ARGS) +.PHONY : test + +# Special rule for the target test +test/fast: test +.PHONY : test/fast + +# The main all target +all: cmake_check_build_system + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -E cmake_progress_start /home/lab1_5/ws/ws_linux/build/CMakeFiles /home/lab1_5/ws/ws_linux/build/rosaria/CMakeFiles/progress.marks + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 rosaria/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/lab1_5/ws/ws_linux/build/CMakeFiles 0 +.PHONY : all + +# The main clean target +clean: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 rosaria/clean +.PHONY : clean + +# The main clean target +clean/fast: clean +.PHONY : clean/fast + +# Prepare targets for installation. +preinstall: all + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 rosaria/preinstall +.PHONY : preinstall + +# Prepare targets for installation. +preinstall/fast: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 rosaria/preinstall +.PHONY : preinstall/fast + +# clear depends +depend: + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 1 +.PHONY : depend + +# Convenience name for target. +rosaria/CMakeFiles/RosAria.dir/rule: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 rosaria/CMakeFiles/RosAria.dir/rule +.PHONY : rosaria/CMakeFiles/RosAria.dir/rule + +# Convenience name for target. +RosAria: rosaria/CMakeFiles/RosAria.dir/rule +.PHONY : RosAria + +# fast build rule for target. +RosAria/fast: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f rosaria/CMakeFiles/RosAria.dir/build.make rosaria/CMakeFiles/RosAria.dir/build +.PHONY : RosAria/fast + +# Convenience name for target. +rosaria/CMakeFiles/actionlib_generate_messages_cpp.dir/rule: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 rosaria/CMakeFiles/actionlib_generate_messages_cpp.dir/rule +.PHONY : rosaria/CMakeFiles/actionlib_generate_messages_cpp.dir/rule + +# Convenience name for target. +actionlib_generate_messages_cpp: rosaria/CMakeFiles/actionlib_generate_messages_cpp.dir/rule +.PHONY : actionlib_generate_messages_cpp + +# fast build rule for target. +actionlib_generate_messages_cpp/fast: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f rosaria/CMakeFiles/actionlib_generate_messages_cpp.dir/build.make rosaria/CMakeFiles/actionlib_generate_messages_cpp.dir/build +.PHONY : actionlib_generate_messages_cpp/fast + +# Convenience name for target. +rosaria/CMakeFiles/actionlib_generate_messages_lisp.dir/rule: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 rosaria/CMakeFiles/actionlib_generate_messages_lisp.dir/rule +.PHONY : rosaria/CMakeFiles/actionlib_generate_messages_lisp.dir/rule + +# Convenience name for target. +actionlib_generate_messages_lisp: rosaria/CMakeFiles/actionlib_generate_messages_lisp.dir/rule +.PHONY : actionlib_generate_messages_lisp + +# fast build rule for target. +actionlib_generate_messages_lisp/fast: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f rosaria/CMakeFiles/actionlib_generate_messages_lisp.dir/build.make rosaria/CMakeFiles/actionlib_generate_messages_lisp.dir/build +.PHONY : actionlib_generate_messages_lisp/fast + +# Convenience name for target. +rosaria/CMakeFiles/actionlib_generate_messages_py.dir/rule: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 rosaria/CMakeFiles/actionlib_generate_messages_py.dir/rule +.PHONY : rosaria/CMakeFiles/actionlib_generate_messages_py.dir/rule + +# Convenience name for target. +actionlib_generate_messages_py: rosaria/CMakeFiles/actionlib_generate_messages_py.dir/rule +.PHONY : actionlib_generate_messages_py + +# fast build rule for target. +actionlib_generate_messages_py/fast: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f rosaria/CMakeFiles/actionlib_generate_messages_py.dir/build.make rosaria/CMakeFiles/actionlib_generate_messages_py.dir/build +.PHONY : actionlib_generate_messages_py/fast + +# Convenience name for target. +rosaria/CMakeFiles/actionlib_msgs_generate_messages_cpp.dir/rule: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 rosaria/CMakeFiles/actionlib_msgs_generate_messages_cpp.dir/rule +.PHONY : rosaria/CMakeFiles/actionlib_msgs_generate_messages_cpp.dir/rule + +# Convenience name for target. +actionlib_msgs_generate_messages_cpp: rosaria/CMakeFiles/actionlib_msgs_generate_messages_cpp.dir/rule +.PHONY : actionlib_msgs_generate_messages_cpp + +# fast build rule for target. +actionlib_msgs_generate_messages_cpp/fast: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f rosaria/CMakeFiles/actionlib_msgs_generate_messages_cpp.dir/build.make rosaria/CMakeFiles/actionlib_msgs_generate_messages_cpp.dir/build +.PHONY : actionlib_msgs_generate_messages_cpp/fast + +# Convenience name for target. +rosaria/CMakeFiles/actionlib_msgs_generate_messages_lisp.dir/rule: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 rosaria/CMakeFiles/actionlib_msgs_generate_messages_lisp.dir/rule +.PHONY : rosaria/CMakeFiles/actionlib_msgs_generate_messages_lisp.dir/rule + +# Convenience name for target. +actionlib_msgs_generate_messages_lisp: rosaria/CMakeFiles/actionlib_msgs_generate_messages_lisp.dir/rule +.PHONY : actionlib_msgs_generate_messages_lisp + +# fast build rule for target. +actionlib_msgs_generate_messages_lisp/fast: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f rosaria/CMakeFiles/actionlib_msgs_generate_messages_lisp.dir/build.make rosaria/CMakeFiles/actionlib_msgs_generate_messages_lisp.dir/build +.PHONY : actionlib_msgs_generate_messages_lisp/fast + +# Convenience name for target. +rosaria/CMakeFiles/actionlib_msgs_generate_messages_py.dir/rule: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 rosaria/CMakeFiles/actionlib_msgs_generate_messages_py.dir/rule +.PHONY : rosaria/CMakeFiles/actionlib_msgs_generate_messages_py.dir/rule + +# Convenience name for target. +actionlib_msgs_generate_messages_py: rosaria/CMakeFiles/actionlib_msgs_generate_messages_py.dir/rule +.PHONY : actionlib_msgs_generate_messages_py + +# fast build rule for target. +actionlib_msgs_generate_messages_py/fast: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f rosaria/CMakeFiles/actionlib_msgs_generate_messages_py.dir/build.make rosaria/CMakeFiles/actionlib_msgs_generate_messages_py.dir/build +.PHONY : actionlib_msgs_generate_messages_py/fast + +# Convenience name for target. +rosaria/CMakeFiles/dynamic_reconfigure_gencfg.dir/rule: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 rosaria/CMakeFiles/dynamic_reconfigure_gencfg.dir/rule +.PHONY : rosaria/CMakeFiles/dynamic_reconfigure_gencfg.dir/rule + +# Convenience name for target. +dynamic_reconfigure_gencfg: rosaria/CMakeFiles/dynamic_reconfigure_gencfg.dir/rule +.PHONY : dynamic_reconfigure_gencfg + +# fast build rule for target. +dynamic_reconfigure_gencfg/fast: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f rosaria/CMakeFiles/dynamic_reconfigure_gencfg.dir/build.make rosaria/CMakeFiles/dynamic_reconfigure_gencfg.dir/build +.PHONY : dynamic_reconfigure_gencfg/fast + +# Convenience name for target. +rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_cpp.dir/rule: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_cpp.dir/rule +.PHONY : rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_cpp.dir/rule + +# Convenience name for target. +dynamic_reconfigure_generate_messages_cpp: rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_cpp.dir/rule +.PHONY : dynamic_reconfigure_generate_messages_cpp + +# fast build rule for target. +dynamic_reconfigure_generate_messages_cpp/fast: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_cpp.dir/build.make rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_cpp.dir/build +.PHONY : dynamic_reconfigure_generate_messages_cpp/fast + +# Convenience name for target. +rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_lisp.dir/rule: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_lisp.dir/rule +.PHONY : rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_lisp.dir/rule + +# Convenience name for target. +dynamic_reconfigure_generate_messages_lisp: rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_lisp.dir/rule +.PHONY : dynamic_reconfigure_generate_messages_lisp + +# fast build rule for target. +dynamic_reconfigure_generate_messages_lisp/fast: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_lisp.dir/build.make rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_lisp.dir/build +.PHONY : dynamic_reconfigure_generate_messages_lisp/fast + +# Convenience name for target. +rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_py.dir/rule: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_py.dir/rule +.PHONY : rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_py.dir/rule + +# Convenience name for target. +dynamic_reconfigure_generate_messages_py: rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_py.dir/rule +.PHONY : dynamic_reconfigure_generate_messages_py + +# fast build rule for target. +dynamic_reconfigure_generate_messages_py/fast: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_py.dir/build.make rosaria/CMakeFiles/dynamic_reconfigure_generate_messages_py.dir/build +.PHONY : dynamic_reconfigure_generate_messages_py/fast + +# Convenience name for target. +rosaria/CMakeFiles/nav_msgs_generate_messages_cpp.dir/rule: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 rosaria/CMakeFiles/nav_msgs_generate_messages_cpp.dir/rule +.PHONY : rosaria/CMakeFiles/nav_msgs_generate_messages_cpp.dir/rule + +# Convenience name for target. +nav_msgs_generate_messages_cpp: rosaria/CMakeFiles/nav_msgs_generate_messages_cpp.dir/rule +.PHONY : nav_msgs_generate_messages_cpp + +# fast build rule for target. +nav_msgs_generate_messages_cpp/fast: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f rosaria/CMakeFiles/nav_msgs_generate_messages_cpp.dir/build.make rosaria/CMakeFiles/nav_msgs_generate_messages_cpp.dir/build +.PHONY : nav_msgs_generate_messages_cpp/fast + +# Convenience name for target. +rosaria/CMakeFiles/nav_msgs_generate_messages_lisp.dir/rule: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 rosaria/CMakeFiles/nav_msgs_generate_messages_lisp.dir/rule +.PHONY : rosaria/CMakeFiles/nav_msgs_generate_messages_lisp.dir/rule + +# Convenience name for target. +nav_msgs_generate_messages_lisp: rosaria/CMakeFiles/nav_msgs_generate_messages_lisp.dir/rule +.PHONY : nav_msgs_generate_messages_lisp + +# fast build rule for target. +nav_msgs_generate_messages_lisp/fast: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f rosaria/CMakeFiles/nav_msgs_generate_messages_lisp.dir/build.make rosaria/CMakeFiles/nav_msgs_generate_messages_lisp.dir/build +.PHONY : nav_msgs_generate_messages_lisp/fast + +# Convenience name for target. +rosaria/CMakeFiles/nav_msgs_generate_messages_py.dir/rule: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 rosaria/CMakeFiles/nav_msgs_generate_messages_py.dir/rule +.PHONY : rosaria/CMakeFiles/nav_msgs_generate_messages_py.dir/rule + +# Convenience name for target. +nav_msgs_generate_messages_py: rosaria/CMakeFiles/nav_msgs_generate_messages_py.dir/rule +.PHONY : nav_msgs_generate_messages_py + +# fast build rule for target. +nav_msgs_generate_messages_py/fast: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f rosaria/CMakeFiles/nav_msgs_generate_messages_py.dir/build.make rosaria/CMakeFiles/nav_msgs_generate_messages_py.dir/build +.PHONY : nav_msgs_generate_messages_py/fast + +# Convenience name for target. +rosaria/CMakeFiles/rosaria_gencfg.dir/rule: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 rosaria/CMakeFiles/rosaria_gencfg.dir/rule +.PHONY : rosaria/CMakeFiles/rosaria_gencfg.dir/rule + +# Convenience name for target. +rosaria_gencfg: rosaria/CMakeFiles/rosaria_gencfg.dir/rule +.PHONY : rosaria_gencfg + +# fast build rule for target. +rosaria_gencfg/fast: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f rosaria/CMakeFiles/rosaria_gencfg.dir/build.make rosaria/CMakeFiles/rosaria_gencfg.dir/build +.PHONY : rosaria_gencfg/fast + +# Convenience name for target. +rosaria/CMakeFiles/rosaria_gencpp.dir/rule: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 rosaria/CMakeFiles/rosaria_gencpp.dir/rule +.PHONY : rosaria/CMakeFiles/rosaria_gencpp.dir/rule + +# Convenience name for target. +rosaria_gencpp: rosaria/CMakeFiles/rosaria_gencpp.dir/rule +.PHONY : rosaria_gencpp + +# fast build rule for target. +rosaria_gencpp/fast: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f rosaria/CMakeFiles/rosaria_gencpp.dir/build.make rosaria/CMakeFiles/rosaria_gencpp.dir/build +.PHONY : rosaria_gencpp/fast + +# Convenience name for target. +rosaria/CMakeFiles/rosaria_generate_messages.dir/rule: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 rosaria/CMakeFiles/rosaria_generate_messages.dir/rule +.PHONY : rosaria/CMakeFiles/rosaria_generate_messages.dir/rule + +# Convenience name for target. +rosaria_generate_messages: rosaria/CMakeFiles/rosaria_generate_messages.dir/rule +.PHONY : rosaria_generate_messages + +# fast build rule for target. +rosaria_generate_messages/fast: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f rosaria/CMakeFiles/rosaria_generate_messages.dir/build.make rosaria/CMakeFiles/rosaria_generate_messages.dir/build +.PHONY : rosaria_generate_messages/fast + +# Convenience name for target. +rosaria/CMakeFiles/rosaria_generate_messages_cpp.dir/rule: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 rosaria/CMakeFiles/rosaria_generate_messages_cpp.dir/rule +.PHONY : rosaria/CMakeFiles/rosaria_generate_messages_cpp.dir/rule + +# Convenience name for target. +rosaria_generate_messages_cpp: rosaria/CMakeFiles/rosaria_generate_messages_cpp.dir/rule +.PHONY : rosaria_generate_messages_cpp + +# fast build rule for target. +rosaria_generate_messages_cpp/fast: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f rosaria/CMakeFiles/rosaria_generate_messages_cpp.dir/build.make rosaria/CMakeFiles/rosaria_generate_messages_cpp.dir/build +.PHONY : rosaria_generate_messages_cpp/fast + +# Convenience name for target. +rosaria/CMakeFiles/rosaria_generate_messages_lisp.dir/rule: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 rosaria/CMakeFiles/rosaria_generate_messages_lisp.dir/rule +.PHONY : rosaria/CMakeFiles/rosaria_generate_messages_lisp.dir/rule + +# Convenience name for target. +rosaria_generate_messages_lisp: rosaria/CMakeFiles/rosaria_generate_messages_lisp.dir/rule +.PHONY : rosaria_generate_messages_lisp + +# fast build rule for target. +rosaria_generate_messages_lisp/fast: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f rosaria/CMakeFiles/rosaria_generate_messages_lisp.dir/build.make rosaria/CMakeFiles/rosaria_generate_messages_lisp.dir/build +.PHONY : rosaria_generate_messages_lisp/fast + +# Convenience name for target. +rosaria/CMakeFiles/rosaria_generate_messages_py.dir/rule: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 rosaria/CMakeFiles/rosaria_generate_messages_py.dir/rule +.PHONY : rosaria/CMakeFiles/rosaria_generate_messages_py.dir/rule + +# Convenience name for target. +rosaria_generate_messages_py: rosaria/CMakeFiles/rosaria_generate_messages_py.dir/rule +.PHONY : rosaria_generate_messages_py + +# fast build rule for target. +rosaria_generate_messages_py/fast: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f rosaria/CMakeFiles/rosaria_generate_messages_py.dir/build.make rosaria/CMakeFiles/rosaria_generate_messages_py.dir/build +.PHONY : rosaria_generate_messages_py/fast + +# Convenience name for target. +rosaria/CMakeFiles/rosaria_genlisp.dir/rule: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 rosaria/CMakeFiles/rosaria_genlisp.dir/rule +.PHONY : rosaria/CMakeFiles/rosaria_genlisp.dir/rule + +# Convenience name for target. +rosaria_genlisp: rosaria/CMakeFiles/rosaria_genlisp.dir/rule +.PHONY : rosaria_genlisp + +# fast build rule for target. +rosaria_genlisp/fast: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f rosaria/CMakeFiles/rosaria_genlisp.dir/build.make rosaria/CMakeFiles/rosaria_genlisp.dir/build +.PHONY : rosaria_genlisp/fast + +# Convenience name for target. +rosaria/CMakeFiles/rosaria_genpy.dir/rule: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 rosaria/CMakeFiles/rosaria_genpy.dir/rule +.PHONY : rosaria/CMakeFiles/rosaria_genpy.dir/rule + +# Convenience name for target. +rosaria_genpy: rosaria/CMakeFiles/rosaria_genpy.dir/rule +.PHONY : rosaria_genpy + +# fast build rule for target. +rosaria_genpy/fast: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f rosaria/CMakeFiles/rosaria_genpy.dir/build.make rosaria/CMakeFiles/rosaria_genpy.dir/build +.PHONY : rosaria_genpy/fast + +# Convenience name for target. +rosaria/CMakeFiles/roscpp_generate_messages_cpp.dir/rule: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 rosaria/CMakeFiles/roscpp_generate_messages_cpp.dir/rule +.PHONY : rosaria/CMakeFiles/roscpp_generate_messages_cpp.dir/rule + +# Convenience name for target. +roscpp_generate_messages_cpp: rosaria/CMakeFiles/roscpp_generate_messages_cpp.dir/rule +.PHONY : roscpp_generate_messages_cpp + +# fast build rule for target. +roscpp_generate_messages_cpp/fast: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f rosaria/CMakeFiles/roscpp_generate_messages_cpp.dir/build.make rosaria/CMakeFiles/roscpp_generate_messages_cpp.dir/build +.PHONY : roscpp_generate_messages_cpp/fast + +# Convenience name for target. +rosaria/CMakeFiles/roscpp_generate_messages_lisp.dir/rule: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 rosaria/CMakeFiles/roscpp_generate_messages_lisp.dir/rule +.PHONY : rosaria/CMakeFiles/roscpp_generate_messages_lisp.dir/rule + +# Convenience name for target. +roscpp_generate_messages_lisp: rosaria/CMakeFiles/roscpp_generate_messages_lisp.dir/rule +.PHONY : roscpp_generate_messages_lisp + +# fast build rule for target. +roscpp_generate_messages_lisp/fast: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f rosaria/CMakeFiles/roscpp_generate_messages_lisp.dir/build.make rosaria/CMakeFiles/roscpp_generate_messages_lisp.dir/build +.PHONY : roscpp_generate_messages_lisp/fast + +# Convenience name for target. +rosaria/CMakeFiles/roscpp_generate_messages_py.dir/rule: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 rosaria/CMakeFiles/roscpp_generate_messages_py.dir/rule +.PHONY : rosaria/CMakeFiles/roscpp_generate_messages_py.dir/rule + +# Convenience name for target. +roscpp_generate_messages_py: rosaria/CMakeFiles/roscpp_generate_messages_py.dir/rule +.PHONY : roscpp_generate_messages_py + +# fast build rule for target. +roscpp_generate_messages_py/fast: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f rosaria/CMakeFiles/roscpp_generate_messages_py.dir/build.make rosaria/CMakeFiles/roscpp_generate_messages_py.dir/build +.PHONY : roscpp_generate_messages_py/fast + +# Convenience name for target. +rosaria/CMakeFiles/rosgraph_msgs_generate_messages_cpp.dir/rule: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 rosaria/CMakeFiles/rosgraph_msgs_generate_messages_cpp.dir/rule +.PHONY : rosaria/CMakeFiles/rosgraph_msgs_generate_messages_cpp.dir/rule + +# Convenience name for target. +rosgraph_msgs_generate_messages_cpp: rosaria/CMakeFiles/rosgraph_msgs_generate_messages_cpp.dir/rule +.PHONY : rosgraph_msgs_generate_messages_cpp + +# fast build rule for target. +rosgraph_msgs_generate_messages_cpp/fast: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f rosaria/CMakeFiles/rosgraph_msgs_generate_messages_cpp.dir/build.make rosaria/CMakeFiles/rosgraph_msgs_generate_messages_cpp.dir/build +.PHONY : rosgraph_msgs_generate_messages_cpp/fast + +# Convenience name for target. +rosaria/CMakeFiles/rosgraph_msgs_generate_messages_lisp.dir/rule: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 rosaria/CMakeFiles/rosgraph_msgs_generate_messages_lisp.dir/rule +.PHONY : rosaria/CMakeFiles/rosgraph_msgs_generate_messages_lisp.dir/rule + +# Convenience name for target. +rosgraph_msgs_generate_messages_lisp: rosaria/CMakeFiles/rosgraph_msgs_generate_messages_lisp.dir/rule +.PHONY : rosgraph_msgs_generate_messages_lisp + +# fast build rule for target. +rosgraph_msgs_generate_messages_lisp/fast: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f rosaria/CMakeFiles/rosgraph_msgs_generate_messages_lisp.dir/build.make rosaria/CMakeFiles/rosgraph_msgs_generate_messages_lisp.dir/build +.PHONY : rosgraph_msgs_generate_messages_lisp/fast + +# Convenience name for target. +rosaria/CMakeFiles/rosgraph_msgs_generate_messages_py.dir/rule: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 rosaria/CMakeFiles/rosgraph_msgs_generate_messages_py.dir/rule +.PHONY : rosaria/CMakeFiles/rosgraph_msgs_generate_messages_py.dir/rule + +# Convenience name for target. +rosgraph_msgs_generate_messages_py: rosaria/CMakeFiles/rosgraph_msgs_generate_messages_py.dir/rule +.PHONY : rosgraph_msgs_generate_messages_py + +# fast build rule for target. +rosgraph_msgs_generate_messages_py/fast: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f rosaria/CMakeFiles/rosgraph_msgs_generate_messages_py.dir/build.make rosaria/CMakeFiles/rosgraph_msgs_generate_messages_py.dir/build +.PHONY : rosgraph_msgs_generate_messages_py/fast + +# Convenience name for target. +rosaria/CMakeFiles/sensor_msgs_generate_messages_cpp.dir/rule: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 rosaria/CMakeFiles/sensor_msgs_generate_messages_cpp.dir/rule +.PHONY : rosaria/CMakeFiles/sensor_msgs_generate_messages_cpp.dir/rule + +# Convenience name for target. +sensor_msgs_generate_messages_cpp: rosaria/CMakeFiles/sensor_msgs_generate_messages_cpp.dir/rule +.PHONY : sensor_msgs_generate_messages_cpp + +# fast build rule for target. +sensor_msgs_generate_messages_cpp/fast: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f rosaria/CMakeFiles/sensor_msgs_generate_messages_cpp.dir/build.make rosaria/CMakeFiles/sensor_msgs_generate_messages_cpp.dir/build +.PHONY : sensor_msgs_generate_messages_cpp/fast + +# Convenience name for target. +rosaria/CMakeFiles/sensor_msgs_generate_messages_lisp.dir/rule: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 rosaria/CMakeFiles/sensor_msgs_generate_messages_lisp.dir/rule +.PHONY : rosaria/CMakeFiles/sensor_msgs_generate_messages_lisp.dir/rule + +# Convenience name for target. +sensor_msgs_generate_messages_lisp: rosaria/CMakeFiles/sensor_msgs_generate_messages_lisp.dir/rule +.PHONY : sensor_msgs_generate_messages_lisp + +# fast build rule for target. +sensor_msgs_generate_messages_lisp/fast: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f rosaria/CMakeFiles/sensor_msgs_generate_messages_lisp.dir/build.make rosaria/CMakeFiles/sensor_msgs_generate_messages_lisp.dir/build +.PHONY : sensor_msgs_generate_messages_lisp/fast + +# Convenience name for target. +rosaria/CMakeFiles/sensor_msgs_generate_messages_py.dir/rule: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 rosaria/CMakeFiles/sensor_msgs_generate_messages_py.dir/rule +.PHONY : rosaria/CMakeFiles/sensor_msgs_generate_messages_py.dir/rule + +# Convenience name for target. +sensor_msgs_generate_messages_py: rosaria/CMakeFiles/sensor_msgs_generate_messages_py.dir/rule +.PHONY : sensor_msgs_generate_messages_py + +# fast build rule for target. +sensor_msgs_generate_messages_py/fast: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f rosaria/CMakeFiles/sensor_msgs_generate_messages_py.dir/build.make rosaria/CMakeFiles/sensor_msgs_generate_messages_py.dir/build +.PHONY : sensor_msgs_generate_messages_py/fast + +# Convenience name for target. +rosaria/CMakeFiles/tf2_msgs_generate_messages_cpp.dir/rule: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 rosaria/CMakeFiles/tf2_msgs_generate_messages_cpp.dir/rule +.PHONY : rosaria/CMakeFiles/tf2_msgs_generate_messages_cpp.dir/rule + +# Convenience name for target. +tf2_msgs_generate_messages_cpp: rosaria/CMakeFiles/tf2_msgs_generate_messages_cpp.dir/rule +.PHONY : tf2_msgs_generate_messages_cpp + +# fast build rule for target. +tf2_msgs_generate_messages_cpp/fast: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f rosaria/CMakeFiles/tf2_msgs_generate_messages_cpp.dir/build.make rosaria/CMakeFiles/tf2_msgs_generate_messages_cpp.dir/build +.PHONY : tf2_msgs_generate_messages_cpp/fast + +# Convenience name for target. +rosaria/CMakeFiles/tf2_msgs_generate_messages_lisp.dir/rule: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 rosaria/CMakeFiles/tf2_msgs_generate_messages_lisp.dir/rule +.PHONY : rosaria/CMakeFiles/tf2_msgs_generate_messages_lisp.dir/rule + +# Convenience name for target. +tf2_msgs_generate_messages_lisp: rosaria/CMakeFiles/tf2_msgs_generate_messages_lisp.dir/rule +.PHONY : tf2_msgs_generate_messages_lisp + +# fast build rule for target. +tf2_msgs_generate_messages_lisp/fast: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f rosaria/CMakeFiles/tf2_msgs_generate_messages_lisp.dir/build.make rosaria/CMakeFiles/tf2_msgs_generate_messages_lisp.dir/build +.PHONY : tf2_msgs_generate_messages_lisp/fast + +# Convenience name for target. +rosaria/CMakeFiles/tf2_msgs_generate_messages_py.dir/rule: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 rosaria/CMakeFiles/tf2_msgs_generate_messages_py.dir/rule +.PHONY : rosaria/CMakeFiles/tf2_msgs_generate_messages_py.dir/rule + +# Convenience name for target. +tf2_msgs_generate_messages_py: rosaria/CMakeFiles/tf2_msgs_generate_messages_py.dir/rule +.PHONY : tf2_msgs_generate_messages_py + +# fast build rule for target. +tf2_msgs_generate_messages_py/fast: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f rosaria/CMakeFiles/tf2_msgs_generate_messages_py.dir/build.make rosaria/CMakeFiles/tf2_msgs_generate_messages_py.dir/build +.PHONY : tf2_msgs_generate_messages_py/fast + +# Convenience name for target. +rosaria/CMakeFiles/tf_generate_messages_cpp.dir/rule: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 rosaria/CMakeFiles/tf_generate_messages_cpp.dir/rule +.PHONY : rosaria/CMakeFiles/tf_generate_messages_cpp.dir/rule + +# Convenience name for target. +tf_generate_messages_cpp: rosaria/CMakeFiles/tf_generate_messages_cpp.dir/rule +.PHONY : tf_generate_messages_cpp + +# fast build rule for target. +tf_generate_messages_cpp/fast: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f rosaria/CMakeFiles/tf_generate_messages_cpp.dir/build.make rosaria/CMakeFiles/tf_generate_messages_cpp.dir/build +.PHONY : tf_generate_messages_cpp/fast + +# Convenience name for target. +rosaria/CMakeFiles/tf_generate_messages_lisp.dir/rule: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 rosaria/CMakeFiles/tf_generate_messages_lisp.dir/rule +.PHONY : rosaria/CMakeFiles/tf_generate_messages_lisp.dir/rule + +# Convenience name for target. +tf_generate_messages_lisp: rosaria/CMakeFiles/tf_generate_messages_lisp.dir/rule +.PHONY : tf_generate_messages_lisp + +# fast build rule for target. +tf_generate_messages_lisp/fast: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f rosaria/CMakeFiles/tf_generate_messages_lisp.dir/build.make rosaria/CMakeFiles/tf_generate_messages_lisp.dir/build +.PHONY : tf_generate_messages_lisp/fast + +# Convenience name for target. +rosaria/CMakeFiles/tf_generate_messages_py.dir/rule: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 rosaria/CMakeFiles/tf_generate_messages_py.dir/rule +.PHONY : rosaria/CMakeFiles/tf_generate_messages_py.dir/rule + +# Convenience name for target. +tf_generate_messages_py: rosaria/CMakeFiles/tf_generate_messages_py.dir/rule +.PHONY : tf_generate_messages_py + +# fast build rule for target. +tf_generate_messages_py/fast: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f rosaria/CMakeFiles/tf_generate_messages_py.dir/build.make rosaria/CMakeFiles/tf_generate_messages_py.dir/build +.PHONY : tf_generate_messages_py/fast + +RosAria.o: RosAria.cpp.o +.PHONY : RosAria.o + +# target to build an object file +RosAria.cpp.o: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f rosaria/CMakeFiles/RosAria.dir/build.make rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.o +.PHONY : RosAria.cpp.o + +RosAria.i: RosAria.cpp.i +.PHONY : RosAria.i + +# target to preprocess a source file +RosAria.cpp.i: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f rosaria/CMakeFiles/RosAria.dir/build.make rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.i +.PHONY : RosAria.cpp.i + +RosAria.s: RosAria.cpp.s +.PHONY : RosAria.s + +# target to generate assembly for a file +RosAria.cpp.s: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f rosaria/CMakeFiles/RosAria.dir/build.make rosaria/CMakeFiles/RosAria.dir/RosAria.cpp.s +.PHONY : RosAria.cpp.s + +# Help Target +help: + @echo "The following are some of the valid targets for this Makefile:" + @echo "... all (the default if no target is provided)" + @echo "... clean" + @echo "... depend" + @echo "... RosAria" + @echo "... actionlib_generate_messages_cpp" + @echo "... actionlib_generate_messages_lisp" + @echo "... actionlib_generate_messages_py" + @echo "... actionlib_msgs_generate_messages_cpp" + @echo "... actionlib_msgs_generate_messages_lisp" + @echo "... actionlib_msgs_generate_messages_py" + @echo "... dynamic_reconfigure_gencfg" + @echo "... dynamic_reconfigure_generate_messages_cpp" + @echo "... dynamic_reconfigure_generate_messages_lisp" + @echo "... dynamic_reconfigure_generate_messages_py" + @echo "... edit_cache" + @echo "... install" + @echo "... install/local" + @echo "... install/strip" + @echo "... list_install_components" + @echo "... nav_msgs_generate_messages_cpp" + @echo "... nav_msgs_generate_messages_lisp" + @echo "... nav_msgs_generate_messages_py" + @echo "... rebuild_cache" + @echo "... rosaria_gencfg" + @echo "... rosaria_gencpp" + @echo "... rosaria_generate_messages" + @echo "... rosaria_generate_messages_cpp" + @echo "... rosaria_generate_messages_lisp" + @echo "... rosaria_generate_messages_py" + @echo "... rosaria_genlisp" + @echo "... rosaria_genpy" + @echo "... roscpp_generate_messages_cpp" + @echo "... roscpp_generate_messages_lisp" + @echo "... roscpp_generate_messages_py" + @echo "... rosgraph_msgs_generate_messages_cpp" + @echo "... rosgraph_msgs_generate_messages_lisp" + @echo "... rosgraph_msgs_generate_messages_py" + @echo "... sensor_msgs_generate_messages_cpp" + @echo "... sensor_msgs_generate_messages_lisp" + @echo "... sensor_msgs_generate_messages_py" + @echo "... test" + @echo "... tf2_msgs_generate_messages_cpp" + @echo "... tf2_msgs_generate_messages_lisp" + @echo "... tf2_msgs_generate_messages_py" + @echo "... tf_generate_messages_cpp" + @echo "... tf_generate_messages_lisp" + @echo "... tf_generate_messages_py" + @echo "... RosAria.o" + @echo "... RosAria.i" + @echo "... RosAria.s" +.PHONY : help + + + +#============================================================================= +# Special targets to cleanup operation of make. + +# Special rule to run CMake to check the build system integrity. +# No rule that depends on this can have commands that come from listfiles +# because they might be regenerated. +cmake_check_build_system: + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 0 +.PHONY : cmake_check_build_system + diff --git a/Legacy/ws_linux/build/rosaria/catkin_generated/installspace/rosaria-msg-extras.cmake b/Legacy/ws_linux/build/rosaria/catkin_generated/installspace/rosaria-msg-extras.cmake new file mode 100644 index 0000000..3cb9603 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/catkin_generated/installspace/rosaria-msg-extras.cmake @@ -0,0 +1,2 @@ +set(rosaria_MESSAGE_FILES "msg/BumperState.msg") +set(rosaria_SERVICE_FILES "") diff --git a/Legacy/ws_linux/build/rosaria/catkin_generated/installspace/rosaria-msg-paths-context.py b/Legacy/ws_linux/build/rosaria/catkin_generated/installspace/rosaria-msg-paths-context.py new file mode 100644 index 0000000..662d513 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/catkin_generated/installspace/rosaria-msg-paths-context.py @@ -0,0 +1,8 @@ +# generated from genmsg/cmake/pkg-msg-paths.context.in + +DEVELSPACE = 'FALSE' == 'TRUE' +INSTALLSPACE = 'TRUE' == 'TRUE' + +PROJECT_NAME = 'rosaria' +PKG_MSG_INCLUDE_DIRS = 'msg' +ARG_DEPENDENCIES = 'geometry_msgs;std_msgs' diff --git a/Legacy/ws_linux/build/rosaria/catkin_generated/installspace/rosaria-msg-paths.cmake b/Legacy/ws_linux/build/rosaria/catkin_generated/installspace/rosaria-msg-paths.cmake new file mode 100644 index 0000000..f963a4d --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/catkin_generated/installspace/rosaria-msg-paths.cmake @@ -0,0 +1,5 @@ +# generated from genmsg/cmake/pkg-msg-paths.cmake.em + +# message include dirs in installspace +_prepend_path("${rosaria_DIR}/.." "msg" rosaria_MSG_INCLUDE_DIRS UNIQUE) +set(rosaria_MSG_DEPENDENCIES geometry_msgs;std_msgs) diff --git a/Legacy/ws_linux/build/rosaria/catkin_generated/installspace/rosaria.pc b/Legacy/ws_linux/build/rosaria/catkin_generated/installspace/rosaria.pc new file mode 100644 index 0000000..f052f52 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/catkin_generated/installspace/rosaria.pc @@ -0,0 +1,8 @@ +prefix=/home/lab1_5/ws/ws_linux/install + +Name: rosaria +Description: Description of rosaria +Version: 0.9.0 +Cflags: -I/home/lab1_5/ws/ws_linux/install/include +Libs: -L/home/lab1_5/ws/ws_linux/install/lib +Requires: roscpp nav_msgs geometry_msgs sensor_msgs tf diff --git a/Legacy/ws_linux/build/rosaria/catkin_generated/installspace/rosariaConfig-version.cmake b/Legacy/ws_linux/build/rosaria/catkin_generated/installspace/rosariaConfig-version.cmake new file mode 100644 index 0000000..0df8aa0 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/catkin_generated/installspace/rosariaConfig-version.cmake @@ -0,0 +1,14 @@ +# generated from catkin/cmake/template/pkgConfig-version.cmake.in +set(PACKAGE_VERSION "0.9.0") + +set(PACKAGE_VERSION_EXACT False) +set(PACKAGE_VERSION_COMPATIBLE False) + +if("${PACKAGE_FIND_VERSION}" VERSION_EQUAL "${PACKAGE_VERSION}") + set(PACKAGE_VERSION_EXACT True) + set(PACKAGE_VERSION_COMPATIBLE True) +endif() + +if("${PACKAGE_FIND_VERSION}" VERSION_LESS "${PACKAGE_VERSION}") + set(PACKAGE_VERSION_COMPATIBLE True) +endif() diff --git a/Legacy/ws_linux/build/rosaria/catkin_generated/installspace/rosariaConfig.cmake b/Legacy/ws_linux/build/rosaria/catkin_generated/installspace/rosariaConfig.cmake new file mode 100644 index 0000000..aa7aa4c --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/catkin_generated/installspace/rosariaConfig.cmake @@ -0,0 +1,191 @@ +# generated from catkin/cmake/template/pkgConfig.cmake.in + +# append elements to a list and remove existing duplicates from the list +# copied from catkin/cmake/list_append_deduplicate.cmake to keep pkgConfig +# self contained +macro(_list_append_deduplicate listname) + if(NOT "${ARGN}" STREQUAL "") + if(${listname}) + list(REMOVE_ITEM ${listname} ${ARGN}) + endif() + list(APPEND ${listname} ${ARGN}) + endif() +endmacro() + +# append elements to a list if they are not already in the list +# copied from catkin/cmake/list_append_unique.cmake to keep pkgConfig +# self contained +macro(_list_append_unique listname) + foreach(_item ${ARGN}) + list(FIND ${listname} ${_item} _index) + if(_index EQUAL -1) + list(APPEND ${listname} ${_item}) + endif() + endforeach() +endmacro() + +# pack a list of libraries with optional build configuration keywords +# copied from catkin/cmake/catkin_libraries.cmake to keep pkgConfig +# self contained +macro(_pack_libraries_with_build_configuration VAR) + set(${VAR} "") + set(_argn ${ARGN}) + list(LENGTH _argn _count) + set(_index 0) + while(${_index} LESS ${_count}) + list(GET _argn ${_index} lib) + if("${lib}" MATCHES "^debug|optimized|general$") + math(EXPR _index "${_index} + 1") + if(${_index} EQUAL ${_count}) + message(FATAL_ERROR "_pack_libraries_with_build_configuration() the list of libraries '${ARGN}' ends with '${lib}' which is a build configuration keyword and must be followed by a library") + endif() + list(GET _argn ${_index} library) + list(APPEND ${VAR} "${lib}${CATKIN_BUILD_CONFIGURATION_KEYWORD_SEPARATOR}${library}") + else() + list(APPEND ${VAR} "${lib}") + endif() + math(EXPR _index "${_index} + 1") + endwhile() +endmacro() + +# unpack a list of libraries with optional build configuration keyword prefixes +# copied from catkin/cmake/catkin_libraries.cmake to keep pkgConfig +# self contained +macro(_unpack_libraries_with_build_configuration VAR) + set(${VAR} "") + foreach(lib ${ARGN}) + string(REGEX REPLACE "^(debug|optimized|general)${CATKIN_BUILD_CONFIGURATION_KEYWORD_SEPARATOR}(.+)$" "\\1;\\2" lib "${lib}") + list(APPEND ${VAR} "${lib}") + endforeach() +endmacro() + + +if(rosaria_CONFIG_INCLUDED) + return() +endif() +set(rosaria_CONFIG_INCLUDED TRUE) + +# set variables for source/devel/install prefixes +if("FALSE" STREQUAL "TRUE") + set(rosaria_SOURCE_PREFIX /home/lab1_5/ws/ws_linux/src/rosaria) + set(rosaria_DEVEL_PREFIX /home/lab1_5/ws/ws_linux/devel) + set(rosaria_INSTALL_PREFIX "") + set(rosaria_PREFIX ${rosaria_DEVEL_PREFIX}) +else() + set(rosaria_SOURCE_PREFIX "") + set(rosaria_DEVEL_PREFIX "") + set(rosaria_INSTALL_PREFIX /home/lab1_5/ws/ws_linux/install) + set(rosaria_PREFIX ${rosaria_INSTALL_PREFIX}) +endif() + +# warn when using a deprecated package +if(NOT "" STREQUAL "") + set(_msg "WARNING: package 'rosaria' is deprecated") + # append custom deprecation text if available + if(NOT "" STREQUAL "TRUE") + set(_msg "${_msg} ()") + endif() + message("${_msg}") +endif() + +# flag project as catkin-based to distinguish if a find_package()-ed project is a catkin project +set(rosaria_FOUND_CATKIN_PROJECT TRUE) + +if(NOT "include" STREQUAL "") + set(rosaria_INCLUDE_DIRS "") + set(_include_dirs "include") + foreach(idir ${_include_dirs}) + if(IS_ABSOLUTE ${idir} AND IS_DIRECTORY ${idir}) + set(include ${idir}) + elseif("${idir}" STREQUAL "include") + get_filename_component(include "${rosaria_DIR}/../../../include" ABSOLUTE) + if(NOT IS_DIRECTORY ${include}) + message(FATAL_ERROR "Project 'rosaria' specifies '${idir}' as an include dir, which is not found. It does not exist in '${include}'. Ask the maintainer 'Srećko Jurić-Kavelj , Ivan Marković , Reed Hedges ' to fix it.") + endif() + else() + message(FATAL_ERROR "Project 'rosaria' specifies '${idir}' as an include dir, which is not found. It does neither exist as an absolute directory nor in '/home/lab1_5/ws/ws_linux/install/${idir}'. Ask the maintainer 'Srećko Jurić-Kavelj , Ivan Marković , Reed Hedges ' to fix it.") + endif() + _list_append_unique(rosaria_INCLUDE_DIRS ${include}) + endforeach() +endif() + +set(libraries "") +foreach(library ${libraries}) + # keep build configuration keywords, target names and absolute libraries as-is + if("${library}" MATCHES "^debug|optimized|general$") + list(APPEND rosaria_LIBRARIES ${library}) + elseif(TARGET ${library}) + list(APPEND rosaria_LIBRARIES ${library}) + elseif(IS_ABSOLUTE ${library}) + list(APPEND rosaria_LIBRARIES ${library}) + else() + set(lib_path "") + set(lib "${library}-NOTFOUND") + # since the path where the library is found is returned we have to iterate over the paths manually + foreach(path /home/lab1_5/ws/ws_linux/install/lib;/home/lab1_5/ws/ws_linux/devel/lib;/home/lab1_5/ws/ws_xeno/devel/lib;/home/lab1_5/ws/ws_isolated/install_isolated/lib;/opt/ros/hydro/lib) + find_library(lib ${library} + PATHS ${path} + NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH) + if(lib) + set(lib_path ${path}) + break() + endif() + endforeach() + if(lib) + _list_append_unique(rosaria_LIBRARY_DIRS ${lib_path}) + list(APPEND rosaria_LIBRARIES ${lib}) + else() + # as a fall back for non-catkin libraries try to search globally + find_library(lib ${library}) + if(NOT lib) + message(FATAL_ERROR "Project '${PROJECT_NAME}' tried to find library '${library}'. The library is neither a target nor built/installed properly. Did you compile project 'rosaria'? Did you find_package() it before the subdirectory containing its code is included?") + endif() + list(APPEND rosaria_LIBRARIES ${lib}) + endif() + endif() +endforeach() + +set(rosaria_EXPORTED_TARGETS "rosaria_gencfg;rosaria_generate_messages_cpp;rosaria_generate_messages_lisp;rosaria_generate_messages_py") +# create dummy targets for exported code generation targets to make life of users easier +foreach(t ${rosaria_EXPORTED_TARGETS}) + if(NOT TARGET ${t}) + add_custom_target(${t}) + endif() +endforeach() + +set(depends "roscpp;nav_msgs;geometry_msgs;sensor_msgs;tf") +foreach(depend ${depends}) + string(REPLACE " " ";" depend_list ${depend}) + # the package name of the dependency must be kept in a unique variable so that it is not overwritten in recursive calls + list(GET depend_list 0 rosaria_dep) + list(LENGTH depend_list count) + if(${count} EQUAL 1) + # simple dependencies must only be find_package()-ed once + if(NOT ${rosaria_dep}_FOUND) + find_package(${rosaria_dep} REQUIRED) + endif() + else() + # dependencies with components must be find_package()-ed again + list(REMOVE_AT depend_list 0) + find_package(${rosaria_dep} REQUIRED ${depend_list}) + endif() + _list_append_unique(rosaria_INCLUDE_DIRS ${${rosaria_dep}_INCLUDE_DIRS}) + + # merge build configuration keywords with library names to correctly deduplicate + _pack_libraries_with_build_configuration(rosaria_LIBRARIES ${rosaria_LIBRARIES}) + _pack_libraries_with_build_configuration(_libraries ${${rosaria_dep}_LIBRARIES}) + _list_append_deduplicate(rosaria_LIBRARIES ${_libraries}) + # undo build configuration keyword merging after deduplication + _unpack_libraries_with_build_configuration(rosaria_LIBRARIES ${rosaria_LIBRARIES}) + + _list_append_unique(rosaria_LIBRARY_DIRS ${${rosaria_dep}_LIBRARY_DIRS}) + list(APPEND rosaria_EXPORTED_TARGETS ${${rosaria_dep}_EXPORTED_TARGETS}) +endforeach() + +set(pkg_cfg_extras "rosaria-msg-extras.cmake") +foreach(extra ${pkg_cfg_extras}) + if(NOT IS_ABSOLUTE ${extra}) + set(extra ${rosaria_DIR}/${extra}) + endif() + include(${extra}) +endforeach() diff --git a/Legacy/ws_linux/build/rosaria/catkin_generated/ordered_paths.cmake b/Legacy/ws_linux/build/rosaria/catkin_generated/ordered_paths.cmake new file mode 100644 index 0000000..3b5d318 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/catkin_generated/ordered_paths.cmake @@ -0,0 +1 @@ +set(ORDERED_PATHS "/opt/ros/hydro/lib") \ No newline at end of file diff --git a/Legacy/ws_linux/build/rosaria/catkin_generated/package.cmake b/Legacy/ws_linux/build/rosaria/catkin_generated/package.cmake new file mode 100644 index 0000000..84507ae --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/catkin_generated/package.cmake @@ -0,0 +1,7 @@ +set(_CATKIN_CURRENT_PACKAGE "rosaria") +set(rosaria_MAINTAINER "Srećko Jurić-Kavelj , Ivan Marković , Reed Hedges ") +set(rosaria_DEPRECATED "") +set(rosaria_VERSION "0.9.0") +set(rosaria_BUILD_DEPENDS "message_generation" "libaria" "roscpp" "nav_msgs" "geometry_msgs" "sensor_msgs" "std_msgs" "tf" "dynamic_reconfigure" "std_msgs") +set(rosaria_RUN_DEPENDS "libaria" "roscpp" "nav_msgs" "geometry_msgs" "sensor_msgs" "tf" "dynamic_reconfigure") +set(rosaria_BUILDTOOL_DEPENDS "catkin") \ No newline at end of file diff --git a/Legacy/ws_linux/build/rosaria/catkin_generated/pkg.develspace.context.pc.py b/Legacy/ws_linux/build/rosaria/catkin_generated/pkg.develspace.context.pc.py new file mode 100644 index 0000000..72e3bd5 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/catkin_generated/pkg.develspace.context.pc.py @@ -0,0 +1,8 @@ +# generated from catkin/cmake/template/pkg.context.pc.in +CATKIN_PACKAGE_PREFIX = "" +PROJECT_PKG_CONFIG_INCLUDE_DIRS = "/home/lab1_5/ws/ws_linux/devel/include".split(';') if "/home/lab1_5/ws/ws_linux/devel/include" != "" else [] +PROJECT_CATKIN_DEPENDS = "roscpp;nav_msgs;geometry_msgs;sensor_msgs;tf".replace(';', ' ') +PKG_CONFIG_LIBRARIES_WITH_PREFIX = "".split(';') if "" != "" else [] +PROJECT_NAME = "rosaria" +PROJECT_SPACE_DIR = "/home/lab1_5/ws/ws_linux/devel" +PROJECT_VERSION = "0.9.0" diff --git a/Legacy/ws_linux/build/rosaria/catkin_generated/pkg.installspace.context.pc.py b/Legacy/ws_linux/build/rosaria/catkin_generated/pkg.installspace.context.pc.py new file mode 100644 index 0000000..c28e17b --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/catkin_generated/pkg.installspace.context.pc.py @@ -0,0 +1,8 @@ +# generated from catkin/cmake/template/pkg.context.pc.in +CATKIN_PACKAGE_PREFIX = "" +PROJECT_PKG_CONFIG_INCLUDE_DIRS = "/home/lab1_5/ws/ws_linux/install/include".split(';') if "/home/lab1_5/ws/ws_linux/install/include" != "" else [] +PROJECT_CATKIN_DEPENDS = "roscpp;nav_msgs;geometry_msgs;sensor_msgs;tf".replace(';', ' ') +PKG_CONFIG_LIBRARIES_WITH_PREFIX = "".split(';') if "" != "" else [] +PROJECT_NAME = "rosaria" +PROJECT_SPACE_DIR = "/home/lab1_5/ws/ws_linux/install" +PROJECT_VERSION = "0.9.0" diff --git a/Legacy/ws_linux/build/rosaria/catkin_generated/rosaria-msg-extras.cmake.develspace.in b/Legacy/ws_linux/build/rosaria/catkin_generated/rosaria-msg-extras.cmake.develspace.in new file mode 100644 index 0000000..01b9d0d --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/catkin_generated/rosaria-msg-extras.cmake.develspace.in @@ -0,0 +1,2 @@ +set(rosaria_MESSAGE_FILES "/home/lab1_5/ws/ws_linux/src/rosaria/msg/BumperState.msg") +set(rosaria_SERVICE_FILES "") diff --git a/Legacy/ws_linux/build/rosaria/catkin_generated/rosaria-msg-extras.cmake.installspace.in b/Legacy/ws_linux/build/rosaria/catkin_generated/rosaria-msg-extras.cmake.installspace.in new file mode 100644 index 0000000..3cb9603 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/catkin_generated/rosaria-msg-extras.cmake.installspace.in @@ -0,0 +1,2 @@ +set(rosaria_MESSAGE_FILES "msg/BumperState.msg") +set(rosaria_SERVICE_FILES "") diff --git a/Legacy/ws_linux/build/rosaria/catkin_generated/rosaria-msg-paths-context.py b/Legacy/ws_linux/build/rosaria/catkin_generated/rosaria-msg-paths-context.py new file mode 100644 index 0000000..2266d3c --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/catkin_generated/rosaria-msg-paths-context.py @@ -0,0 +1,8 @@ +# generated from genmsg/cmake/pkg-msg-paths.context.in + +DEVELSPACE = 'TRUE' == 'TRUE' +INSTALLSPACE = 'FALSE' == 'TRUE' + +PROJECT_NAME = 'rosaria' +PKG_MSG_INCLUDE_DIRS = '/home/lab1_5/ws/ws_linux/src/rosaria/msg' +ARG_DEPENDENCIES = 'geometry_msgs;std_msgs' diff --git a/package.xml b/Legacy/ws_linux/build/rosaria/catkin_generated/stamps/rosaria/package.xml.stamp similarity index 100% rename from package.xml rename to Legacy/ws_linux/build/rosaria/catkin_generated/stamps/rosaria/package.xml.stamp diff --git a/Legacy/ws_linux/build/rosaria/catkin_generated/stamps/rosaria/pkg-genmsg.cmake.em.stamp b/Legacy/ws_linux/build/rosaria/catkin_generated/stamps/rosaria/pkg-genmsg.cmake.em.stamp new file mode 100644 index 0000000..5182859 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/catkin_generated/stamps/rosaria/pkg-genmsg.cmake.em.stamp @@ -0,0 +1,141 @@ +# generated from genmsg/cmake/pkg-genmsg.cmake.em + +@{ +import os +import sys + +import genmsg +import genmsg.base +genmsg.base.log_verbose('GENMSG_VERBOSE' in os.environ) +import genmsg.deps +import genmsg.gentools + +# split incoming variables +messages = messages_str.split(';') if messages_str != '' else [] +services = services_str.split(';') if services_str != '' else [] +dependencies = dependencies_str.split(';') if dependencies_str != '' else [] +dep_search_paths = dep_include_paths_str.split(';') if dep_include_paths_str != '' else [] + +dep_search_paths_dict = {} +dep_search_paths_tuple_list = [] +is_even = True +for val in dep_search_paths: + if is_even: + dep_search_paths_dict.setdefault(val, []) + val_prev = val + is_even = False + else: + dep_search_paths_dict[val_prev].append(val) + dep_search_paths_tuple_list.append((val_prev, val)) + is_even = True +dep_search_paths = dep_search_paths_dict + +if not messages and not services: + print('message(WARNING "Invoking generate_messages() without having added any message or service file before.\nYou should either add add_message_files() and/or add_service_files() calls or remove the invocation of generate_messages().")') + +msg_deps = {} +for m in messages: + try: + msg_deps[m] = genmsg.deps.find_msg_dependencies(pkg_name, m, dep_search_paths) + except genmsg.MsgNotFound as e: + print('message(FATAL_ERROR "Could not find messages which \'%s\' depends on. Did you forget to specify generate_messages(DEPENDENCIES ...)?\n%s")' % (m, str(e))) + +srv_deps = {} +for s in services: + try: + srv_deps[s] = genmsg.deps.find_srv_dependencies(pkg_name, s, dep_search_paths) + except genmsg.MsgNotFound as e: + print('message(FATAL_ERROR "Could not find messages which \'%s\' depends on. Did you forget to specify generate_messages(DEPENDENCIES ...)?\n%s")' % (s, str(e))) + +}@ +message(STATUS "@(pkg_name): @(len(messages)) messages, @(len(services)) services") + +set(MSG_I_FLAGS "@(';'.join(["-I%s:%s" % (dep, dir) for dep, dir in dep_search_paths_tuple_list]))") + +# Find all generators +@[if langs]@ +@[for l in langs.split(';')]@ +find_package(@l REQUIRED) +@[end for]@ +@[end if]@ + +add_custom_target(@(pkg_name)_generate_messages ALL) + +# +# langs = @langs +# + +@[if langs]@ +@[for l in langs.split(';')]@ +### Section generating for lang: @l +### Generating Messages +@[for m in msg_deps.keys()]@ +_generate_msg_@(l[3:])(@pkg_name + "@m" + "${MSG_I_FLAGS}" + "@(';'.join(msg_deps[m]).replace("\\","/"))" + ${CATKIN_DEVEL_PREFIX}/${@(l)_INSTALL_DIR}/@pkg_name +) +@[end for]@# messages + +### Generating Services +@[for s in srv_deps.keys()]@ +_generate_srv_@(l[3:])(@pkg_name + "@s" + "${MSG_I_FLAGS}" + "@(';'.join(srv_deps[s]).replace("\\","/"))" + ${CATKIN_DEVEL_PREFIX}/${@(l)_INSTALL_DIR}/@pkg_name +) +@[end for]@# services + +### Generating Module File +_generate_module_@(l[3:])(@pkg_name + ${CATKIN_DEVEL_PREFIX}/${@(l)_INSTALL_DIR}/@pkg_name + "${ALL_GEN_OUTPUT_FILES_@(l[3:])}" +) + +add_custom_target(@(pkg_name)_generate_messages_@(l[3:]) + DEPENDS ${ALL_GEN_OUTPUT_FILES_@(l[3:])} +) +add_dependencies(@(pkg_name)_generate_messages @(pkg_name)_generate_messages_@(l[3:])) + +# target for backward compatibility +add_custom_target(@(pkg_name)_@(l)) +add_dependencies(@(pkg_name)_@(l) @(pkg_name)_generate_messages_@(l[3:])) + +# register target for catkin_package(EXPORTED_TARGETS) +list(APPEND ${PROJECT_NAME}_EXPORTED_TARGETS @(pkg_name)_generate_messages_@(l[3:])) + +@[end for]@# langs +@[end if]@ + +@[if langs]@ +@[for l in langs.split(';')]@ + +if(@(l)_INSTALL_DIR AND EXISTS ${CATKIN_DEVEL_PREFIX}/${@(l)_INSTALL_DIR}/@pkg_name) +@[if l == 'genpy']@ + install(CODE "execute_process(COMMAND \"@(PYTHON_EXECUTABLE)\" -m compileall \"${CATKIN_DEVEL_PREFIX}/${@(l)_INSTALL_DIR}/@pkg_name\")") +@[end if]@ + # install generated code + install( + DIRECTORY ${CATKIN_DEVEL_PREFIX}/${@(l)_INSTALL_DIR}/@pkg_name + DESTINATION ${@(l)_INSTALL_DIR} +@[if l == 'genpy' and package_has_static_sources]@ + # skip all init files + PATTERN "__init__.py" EXCLUDE + PATTERN "__init__.pyc" EXCLUDE + ) + # install init files which are not in the root folder of the generated code + install( + DIRECTORY ${CATKIN_DEVEL_PREFIX}/${@(l)_INSTALL_DIR}/@pkg_name + DESTINATION ${@(l)_INSTALL_DIR} + FILES_MATCHING + REGEX "${CATKIN_DEVEL_PREFIX}/${@(l)_INSTALL_DIR}/@(pkg_name)/.+/__init__.pyc?$" +@[end if]@ + ) +endif() +@[for d in dependencies]@ +add_dependencies(@(pkg_name)_generate_messages_@(l[3:]) @(d)_generate_messages_@(l[3:])) +@[end for]@# dependencies +@[end for]@# langs +@[end if]@ diff --git a/Legacy/ws_linux/build/rosaria/catkin_generated/stamps/rosaria/pkg-msg-paths.cmake.em.stamp b/Legacy/ws_linux/build/rosaria/catkin_generated/stamps/rosaria/pkg-msg-paths.cmake.em.stamp new file mode 100644 index 0000000..eb6f88a --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/catkin_generated/stamps/rosaria/pkg-msg-paths.cmake.em.stamp @@ -0,0 +1,10 @@ +# generated from genmsg/cmake/pkg-msg-paths.cmake.em + +@[if DEVELSPACE]@ +# message include dirs in develspace +set(@(PROJECT_NAME)_MSG_INCLUDE_DIRS "@(PKG_MSG_INCLUDE_DIRS)") +@[else]@ +# message include dirs in installspace +_prepend_path("${@(PROJECT_NAME)_DIR}/.." "@(PKG_MSG_INCLUDE_DIRS)" @(PROJECT_NAME)_MSG_INCLUDE_DIRS UNIQUE) +@[end if]@ +set(@(PROJECT_NAME)_MSG_DEPENDENCIES @(ARG_DEPENDENCIES)) diff --git a/Legacy/ws_linux/build/rosaria/catkin_generated/stamps/rosaria/pkg.pc.em.stamp b/Legacy/ws_linux/build/rosaria/catkin_generated/stamps/rosaria/pkg.pc.em.stamp new file mode 100644 index 0000000..a4f7257 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/catkin_generated/stamps/rosaria/pkg.pc.em.stamp @@ -0,0 +1,8 @@ +prefix=@PROJECT_SPACE_DIR + +Name: @(CATKIN_PACKAGE_PREFIX + PROJECT_NAME) +Description: Description of @PROJECT_NAME +Version: @PROJECT_VERSION +Cflags: @(' '.join(['-I%s' % include for include in PROJECT_PKG_CONFIG_INCLUDE_DIRS])) +Libs: -L@PROJECT_SPACE_DIR/lib @(' '.join(PKG_CONFIG_LIBRARIES_WITH_PREFIX)) +Requires: @(PROJECT_CATKIN_DEPENDS) diff --git a/Legacy/ws_linux/build/rosaria/cmake/rosaria-genmsg-context.py b/Legacy/ws_linux/build/rosaria/cmake/rosaria-genmsg-context.py new file mode 100644 index 0000000..030edc0 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/cmake/rosaria-genmsg-context.py @@ -0,0 +1,10 @@ +# generated from genmsg/cmake/pkg-genmsg.context.in + +messages_str = "/home/lab1_5/ws/ws_linux/src/rosaria/msg/BumperState.msg" +services_str = "" +pkg_name = "rosaria" +dependencies_str = "geometry_msgs;std_msgs" +langs = "gencpp;genlisp;genpy" +dep_include_paths_str = "rosaria;/home/lab1_5/ws/ws_linux/src/rosaria/msg;geometry_msgs;/opt/ros/hydro/share/geometry_msgs/cmake/../msg;std_msgs;/opt/ros/hydro/share/std_msgs/cmake/../msg" +PYTHON_EXECUTABLE = "/usr/bin/python" +package_has_static_sources = '' == 'TRUE' diff --git a/Legacy/ws_linux/build/rosaria/cmake/rosaria-genmsg.cmake b/Legacy/ws_linux/build/rosaria/cmake/rosaria-genmsg.cmake new file mode 100644 index 0000000..81b8118 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/cmake/rosaria-genmsg.cmake @@ -0,0 +1,136 @@ +# generated from genmsg/cmake/pkg-genmsg.cmake.em + +message(STATUS "rosaria: 1 messages, 0 services") + +set(MSG_I_FLAGS "-Irosaria:/home/lab1_5/ws/ws_linux/src/rosaria/msg;-Igeometry_msgs:/opt/ros/hydro/share/geometry_msgs/cmake/../msg;-Istd_msgs:/opt/ros/hydro/share/std_msgs/cmake/../msg") + +# Find all generators +find_package(gencpp REQUIRED) +find_package(genlisp REQUIRED) +find_package(genpy REQUIRED) + +add_custom_target(rosaria_generate_messages ALL) + +# +# langs = gencpp;genlisp;genpy +# + +### Section generating for lang: gencpp +### Generating Messages +_generate_msg_cpp(rosaria + "/home/lab1_5/ws/ws_linux/src/rosaria/msg/BumperState.msg" + "${MSG_I_FLAGS}" + "/opt/ros/hydro/share/std_msgs/cmake/../msg/Header.msg" + ${CATKIN_DEVEL_PREFIX}/${gencpp_INSTALL_DIR}/rosaria +) + +### Generating Services + +### Generating Module File +_generate_module_cpp(rosaria + ${CATKIN_DEVEL_PREFIX}/${gencpp_INSTALL_DIR}/rosaria + "${ALL_GEN_OUTPUT_FILES_cpp}" +) + +add_custom_target(rosaria_generate_messages_cpp + DEPENDS ${ALL_GEN_OUTPUT_FILES_cpp} +) +add_dependencies(rosaria_generate_messages rosaria_generate_messages_cpp) + +# target for backward compatibility +add_custom_target(rosaria_gencpp) +add_dependencies(rosaria_gencpp rosaria_generate_messages_cpp) + +# register target for catkin_package(EXPORTED_TARGETS) +list(APPEND ${PROJECT_NAME}_EXPORTED_TARGETS rosaria_generate_messages_cpp) + +### Section generating for lang: genlisp +### Generating Messages +_generate_msg_lisp(rosaria + "/home/lab1_5/ws/ws_linux/src/rosaria/msg/BumperState.msg" + "${MSG_I_FLAGS}" + "/opt/ros/hydro/share/std_msgs/cmake/../msg/Header.msg" + ${CATKIN_DEVEL_PREFIX}/${genlisp_INSTALL_DIR}/rosaria +) + +### Generating Services + +### Generating Module File +_generate_module_lisp(rosaria + ${CATKIN_DEVEL_PREFIX}/${genlisp_INSTALL_DIR}/rosaria + "${ALL_GEN_OUTPUT_FILES_lisp}" +) + +add_custom_target(rosaria_generate_messages_lisp + DEPENDS ${ALL_GEN_OUTPUT_FILES_lisp} +) +add_dependencies(rosaria_generate_messages rosaria_generate_messages_lisp) + +# target for backward compatibility +add_custom_target(rosaria_genlisp) +add_dependencies(rosaria_genlisp rosaria_generate_messages_lisp) + +# register target for catkin_package(EXPORTED_TARGETS) +list(APPEND ${PROJECT_NAME}_EXPORTED_TARGETS rosaria_generate_messages_lisp) + +### Section generating for lang: genpy +### Generating Messages +_generate_msg_py(rosaria + "/home/lab1_5/ws/ws_linux/src/rosaria/msg/BumperState.msg" + "${MSG_I_FLAGS}" + "/opt/ros/hydro/share/std_msgs/cmake/../msg/Header.msg" + ${CATKIN_DEVEL_PREFIX}/${genpy_INSTALL_DIR}/rosaria +) + +### Generating Services + +### Generating Module File +_generate_module_py(rosaria + ${CATKIN_DEVEL_PREFIX}/${genpy_INSTALL_DIR}/rosaria + "${ALL_GEN_OUTPUT_FILES_py}" +) + +add_custom_target(rosaria_generate_messages_py + DEPENDS ${ALL_GEN_OUTPUT_FILES_py} +) +add_dependencies(rosaria_generate_messages rosaria_generate_messages_py) + +# target for backward compatibility +add_custom_target(rosaria_genpy) +add_dependencies(rosaria_genpy rosaria_generate_messages_py) + +# register target for catkin_package(EXPORTED_TARGETS) +list(APPEND ${PROJECT_NAME}_EXPORTED_TARGETS rosaria_generate_messages_py) + + + +if(gencpp_INSTALL_DIR AND EXISTS ${CATKIN_DEVEL_PREFIX}/${gencpp_INSTALL_DIR}/rosaria) + # install generated code + install( + DIRECTORY ${CATKIN_DEVEL_PREFIX}/${gencpp_INSTALL_DIR}/rosaria + DESTINATION ${gencpp_INSTALL_DIR} + ) +endif() +add_dependencies(rosaria_generate_messages_cpp geometry_msgs_generate_messages_cpp) +add_dependencies(rosaria_generate_messages_cpp std_msgs_generate_messages_cpp) + +if(genlisp_INSTALL_DIR AND EXISTS ${CATKIN_DEVEL_PREFIX}/${genlisp_INSTALL_DIR}/rosaria) + # install generated code + install( + DIRECTORY ${CATKIN_DEVEL_PREFIX}/${genlisp_INSTALL_DIR}/rosaria + DESTINATION ${genlisp_INSTALL_DIR} + ) +endif() +add_dependencies(rosaria_generate_messages_lisp geometry_msgs_generate_messages_lisp) +add_dependencies(rosaria_generate_messages_lisp std_msgs_generate_messages_lisp) + +if(genpy_INSTALL_DIR AND EXISTS ${CATKIN_DEVEL_PREFIX}/${genpy_INSTALL_DIR}/rosaria) + install(CODE "execute_process(COMMAND \"/usr/bin/python\" -m compileall \"${CATKIN_DEVEL_PREFIX}/${genpy_INSTALL_DIR}/rosaria\")") + # install generated code + install( + DIRECTORY ${CATKIN_DEVEL_PREFIX}/${genpy_INSTALL_DIR}/rosaria + DESTINATION ${genpy_INSTALL_DIR} + ) +endif() +add_dependencies(rosaria_generate_messages_py geometry_msgs_generate_messages_py) +add_dependencies(rosaria_generate_messages_py std_msgs_generate_messages_py) diff --git a/Legacy/ws_linux/build/rosaria/cmake_install.cmake b/Legacy/ws_linux/build/rosaria/cmake_install.cmake new file mode 100644 index 0000000..bb57709 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria/cmake_install.cmake @@ -0,0 +1,111 @@ +# Install script for directory: /home/lab1_5/ws/ws_linux/src/rosaria + +# Set the install prefix +IF(NOT DEFINED CMAKE_INSTALL_PREFIX) + SET(CMAKE_INSTALL_PREFIX "/home/lab1_5/ws/ws_linux/install") +ENDIF(NOT DEFINED CMAKE_INSTALL_PREFIX) +STRING(REGEX REPLACE "/$" "" CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}") + +# Set the install configuration name. +IF(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME) + IF(BUILD_TYPE) + STRING(REGEX REPLACE "^[^A-Za-z0-9_]+" "" + CMAKE_INSTALL_CONFIG_NAME "${BUILD_TYPE}") + ELSE(BUILD_TYPE) + SET(CMAKE_INSTALL_CONFIG_NAME "") + ENDIF(BUILD_TYPE) + MESSAGE(STATUS "Install configuration: \"${CMAKE_INSTALL_CONFIG_NAME}\"") +ENDIF(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME) + +# Set the component getting installed. +IF(NOT CMAKE_INSTALL_COMPONENT) + IF(COMPONENT) + MESSAGE(STATUS "Install component: \"${COMPONENT}\"") + SET(CMAKE_INSTALL_COMPONENT "${COMPONENT}") + ELSE(COMPONENT) + SET(CMAKE_INSTALL_COMPONENT) + ENDIF(COMPONENT) +ENDIF(NOT CMAKE_INSTALL_COMPONENT) + +# Install shared libraries without execute permission? +IF(NOT DEFINED CMAKE_INSTALL_SO_NO_EXE) + SET(CMAKE_INSTALL_SO_NO_EXE "1") +ENDIF(NOT DEFINED CMAKE_INSTALL_SO_NO_EXE) + +IF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + FILE(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/share/rosaria/msg" TYPE FILE FILES "/home/lab1_5/ws/ws_linux/src/rosaria/msg/BumperState.msg") +ENDIF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + +IF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + FILE(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/include/rosaria" TYPE FILE FILES "/home/lab1_5/ws/ws_linux/devel/include/rosaria/RosAriaConfig.h") +ENDIF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + +IF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + FILE(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/lib/python2.7/dist-packages/rosaria" TYPE FILE FILES "/home/lab1_5/ws/ws_linux/devel/lib/python2.7/dist-packages/rosaria/__init__.py") +ENDIF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + +IF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + execute_process(COMMAND "/usr/bin/python" -m compileall "/home/lab1_5/ws/ws_linux/devel/lib/python2.7/dist-packages/rosaria/cfg") +ENDIF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + +IF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + FILE(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/lib/python2.7/dist-packages/rosaria" TYPE DIRECTORY FILES "/home/lab1_5/ws/ws_linux/devel/lib/python2.7/dist-packages/rosaria/cfg") +ENDIF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + +IF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + FILE(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/share/rosaria/cmake" TYPE FILE FILES "/home/lab1_5/ws/ws_linux/build/rosaria/catkin_generated/installspace/rosaria-msg-paths.cmake") +ENDIF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + +IF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + FILE(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/include" TYPE DIRECTORY FILES "/home/lab1_5/ws/ws_linux/devel/include/rosaria") +ENDIF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + +IF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + FILE(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/share/common-lisp/ros" TYPE DIRECTORY FILES "/home/lab1_5/ws/ws_linux/devel/share/common-lisp/ros/rosaria") +ENDIF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + +IF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + execute_process(COMMAND "/usr/bin/python" -m compileall "/home/lab1_5/ws/ws_linux/devel/lib/python2.7/dist-packages/rosaria") +ENDIF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + +IF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + FILE(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/lib/python2.7/dist-packages" TYPE DIRECTORY FILES "/home/lab1_5/ws/ws_linux/devel/lib/python2.7/dist-packages/rosaria") +ENDIF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + +IF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + FILE(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/lib/pkgconfig" TYPE FILE FILES "/home/lab1_5/ws/ws_linux/build/rosaria/catkin_generated/installspace/rosaria.pc") +ENDIF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + +IF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + FILE(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/share/rosaria/cmake" TYPE FILE FILES "/home/lab1_5/ws/ws_linux/build/rosaria/catkin_generated/installspace/rosaria-msg-extras.cmake") +ENDIF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + +IF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + FILE(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/share/rosaria/cmake" TYPE FILE FILES + "/home/lab1_5/ws/ws_linux/build/rosaria/catkin_generated/installspace/rosariaConfig.cmake" + "/home/lab1_5/ws/ws_linux/build/rosaria/catkin_generated/installspace/rosariaConfig-version.cmake" + ) +ENDIF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + +IF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + FILE(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/share/rosaria" TYPE FILE FILES "/home/lab1_5/ws/ws_linux/src/rosaria/package.xml") +ENDIF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + +IF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + IF(EXISTS "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/lib/rosaria/RosAria" AND + NOT IS_SYMLINK "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/lib/rosaria/RosAria") + FILE(RPATH_CHECK + FILE "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/lib/rosaria/RosAria" + RPATH "") + ENDIF() + FILE(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/lib/rosaria" TYPE EXECUTABLE FILES "/home/lab1_5/ws/ws_linux/devel/lib/rosaria/RosAria") + IF(EXISTS "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/lib/rosaria/RosAria" AND + NOT IS_SYMLINK "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/lib/rosaria/RosAria") + FILE(RPATH_REMOVE + FILE "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/lib/rosaria/RosAria") + IF(CMAKE_INSTALL_DO_STRIP) + EXECUTE_PROCESS(COMMAND "/usr/bin/strip" "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/lib/rosaria/RosAria") + ENDIF(CMAKE_INSTALL_DO_STRIP) + ENDIF() +ENDIF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + diff --git a/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/CMakeDirectoryInformation.cmake b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/CMakeDirectoryInformation.cmake new file mode 100644 index 0000000..4e991dd --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/CMakeDirectoryInformation.cmake @@ -0,0 +1,24 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +# Relative path conversion top directories. +SET(CMAKE_RELATIVE_PATH_TOP_SOURCE "/home/lab1_5/ws/ws_linux/src") +SET(CMAKE_RELATIVE_PATH_TOP_BINARY "/home/lab1_5/ws/ws_linux/build") + +# Force unix paths in dependencies. +SET(CMAKE_FORCE_UNIX_PATHS 1) + +# The C and CXX include file search paths: +SET(CMAKE_C_INCLUDE_PATH + "/home/lab1_5/ws/ws_linux/devel/include" + "/opt/ros/hydro/include" + ) +SET(CMAKE_CXX_INCLUDE_PATH ${CMAKE_C_INCLUDE_PATH}) +SET(CMAKE_Fortran_INCLUDE_PATH ${CMAKE_C_INCLUDE_PATH}) +SET(CMAKE_ASM_INCLUDE_PATH ${CMAKE_C_INCLUDE_PATH}) + +# The C and CXX include file regular expressions for this directory. +SET(CMAKE_C_INCLUDE_REGEX_SCAN "^.*$") +SET(CMAKE_C_INCLUDE_REGEX_COMPLAIN "^$") +SET(CMAKE_CXX_INCLUDE_REGEX_SCAN ${CMAKE_C_INCLUDE_REGEX_SCAN}) +SET(CMAKE_CXX_INCLUDE_REGEX_COMPLAIN ${CMAKE_C_INCLUDE_REGEX_COMPLAIN}) diff --git a/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_cpp.dir/DependInfo.cmake b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_cpp.dir/DependInfo.cmake new file mode 100644 index 0000000..8bc32e3 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_cpp.dir/DependInfo.cmake @@ -0,0 +1,13 @@ +# The set of languages for which implicit dependencies are needed: +SET(CMAKE_DEPENDS_LANGUAGES + ) +# The set of files for implicit dependencies of each language: + +# Preprocessor definitions for this target. +SET(CMAKE_TARGET_DEFINITIONS + "ROS_BUILD_SHARED_LIBS=1" + ) + +# Targets to which this target links. +SET(CMAKE_TARGET_LINKED_INFO_FILES + ) diff --git a/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_cpp.dir/build.make b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_cpp.dir/build.make new file mode 100644 index 0000000..bb02bbd --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_cpp.dir/build.make @@ -0,0 +1,62 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/lab1_5/ws/ws_linux/src + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/lab1_5/ws/ws_linux/build + +# Utility rule file for geometry_msgs_generate_messages_cpp. + +# Include the progress variables for this target. +include rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_cpp.dir/progress.make + +rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_cpp: + +geometry_msgs_generate_messages_cpp: rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_cpp +geometry_msgs_generate_messages_cpp: rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_cpp.dir/build.make +.PHONY : geometry_msgs_generate_messages_cpp + +# Rule to build all files generated by this target. +rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_cpp.dir/build: geometry_msgs_generate_messages_cpp +.PHONY : rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_cpp.dir/build + +rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_cpp.dir/clean: + cd /home/lab1_5/ws/ws_linux/build/rosaria_msgs && $(CMAKE_COMMAND) -P CMakeFiles/geometry_msgs_generate_messages_cpp.dir/cmake_clean.cmake +.PHONY : rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_cpp.dir/clean + +rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_cpp.dir/depend: + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/lab1_5/ws/ws_linux/src /home/lab1_5/ws/ws_linux/src/rosaria_msgs /home/lab1_5/ws/ws_linux/build /home/lab1_5/ws/ws_linux/build/rosaria_msgs /home/lab1_5/ws/ws_linux/build/rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_cpp.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_cpp.dir/depend + diff --git a/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_cpp.dir/cmake_clean.cmake b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_cpp.dir/cmake_clean.cmake new file mode 100644 index 0000000..7604a6c --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_cpp.dir/cmake_clean.cmake @@ -0,0 +1,8 @@ +FILE(REMOVE_RECURSE + "CMakeFiles/geometry_msgs_generate_messages_cpp" +) + +# Per-language clean rules from dependency scanning. +FOREACH(lang) + INCLUDE(CMakeFiles/geometry_msgs_generate_messages_cpp.dir/cmake_clean_${lang}.cmake OPTIONAL) +ENDFOREACH(lang) diff --git a/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_cpp.dir/depend.internal b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_cpp.dir/depend.internal new file mode 100644 index 0000000..38eae05 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_cpp.dir/depend.internal @@ -0,0 +1,3 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + diff --git a/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_cpp.dir/depend.make b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_cpp.dir/depend.make new file mode 100644 index 0000000..38eae05 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_cpp.dir/depend.make @@ -0,0 +1,3 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + diff --git a/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_cpp.dir/progress.make b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_cpp.dir/progress.make new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_cpp.dir/progress.make @@ -0,0 +1 @@ + diff --git a/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_lisp.dir/DependInfo.cmake b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_lisp.dir/DependInfo.cmake new file mode 100644 index 0000000..8bc32e3 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_lisp.dir/DependInfo.cmake @@ -0,0 +1,13 @@ +# The set of languages for which implicit dependencies are needed: +SET(CMAKE_DEPENDS_LANGUAGES + ) +# The set of files for implicit dependencies of each language: + +# Preprocessor definitions for this target. +SET(CMAKE_TARGET_DEFINITIONS + "ROS_BUILD_SHARED_LIBS=1" + ) + +# Targets to which this target links. +SET(CMAKE_TARGET_LINKED_INFO_FILES + ) diff --git a/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_lisp.dir/build.make b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_lisp.dir/build.make new file mode 100644 index 0000000..77d2dec --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_lisp.dir/build.make @@ -0,0 +1,62 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/lab1_5/ws/ws_linux/src + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/lab1_5/ws/ws_linux/build + +# Utility rule file for geometry_msgs_generate_messages_lisp. + +# Include the progress variables for this target. +include rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_lisp.dir/progress.make + +rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_lisp: + +geometry_msgs_generate_messages_lisp: rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_lisp +geometry_msgs_generate_messages_lisp: rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_lisp.dir/build.make +.PHONY : geometry_msgs_generate_messages_lisp + +# Rule to build all files generated by this target. +rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_lisp.dir/build: geometry_msgs_generate_messages_lisp +.PHONY : rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_lisp.dir/build + +rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_lisp.dir/clean: + cd /home/lab1_5/ws/ws_linux/build/rosaria_msgs && $(CMAKE_COMMAND) -P CMakeFiles/geometry_msgs_generate_messages_lisp.dir/cmake_clean.cmake +.PHONY : rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_lisp.dir/clean + +rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_lisp.dir/depend: + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/lab1_5/ws/ws_linux/src /home/lab1_5/ws/ws_linux/src/rosaria_msgs /home/lab1_5/ws/ws_linux/build /home/lab1_5/ws/ws_linux/build/rosaria_msgs /home/lab1_5/ws/ws_linux/build/rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_lisp.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_lisp.dir/depend + diff --git a/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_lisp.dir/cmake_clean.cmake b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_lisp.dir/cmake_clean.cmake new file mode 100644 index 0000000..71acf8d --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_lisp.dir/cmake_clean.cmake @@ -0,0 +1,8 @@ +FILE(REMOVE_RECURSE + "CMakeFiles/geometry_msgs_generate_messages_lisp" +) + +# Per-language clean rules from dependency scanning. +FOREACH(lang) + INCLUDE(CMakeFiles/geometry_msgs_generate_messages_lisp.dir/cmake_clean_${lang}.cmake OPTIONAL) +ENDFOREACH(lang) diff --git a/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_lisp.dir/depend.internal b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_lisp.dir/depend.internal new file mode 100644 index 0000000..38eae05 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_lisp.dir/depend.internal @@ -0,0 +1,3 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + diff --git a/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_lisp.dir/depend.make b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_lisp.dir/depend.make new file mode 100644 index 0000000..38eae05 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_lisp.dir/depend.make @@ -0,0 +1,3 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + diff --git a/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_lisp.dir/progress.make b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_lisp.dir/progress.make new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_lisp.dir/progress.make @@ -0,0 +1 @@ + diff --git a/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_py.dir/DependInfo.cmake b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_py.dir/DependInfo.cmake new file mode 100644 index 0000000..8bc32e3 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_py.dir/DependInfo.cmake @@ -0,0 +1,13 @@ +# The set of languages for which implicit dependencies are needed: +SET(CMAKE_DEPENDS_LANGUAGES + ) +# The set of files for implicit dependencies of each language: + +# Preprocessor definitions for this target. +SET(CMAKE_TARGET_DEFINITIONS + "ROS_BUILD_SHARED_LIBS=1" + ) + +# Targets to which this target links. +SET(CMAKE_TARGET_LINKED_INFO_FILES + ) diff --git a/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_py.dir/build.make b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_py.dir/build.make new file mode 100644 index 0000000..7318be8 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_py.dir/build.make @@ -0,0 +1,62 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/lab1_5/ws/ws_linux/src + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/lab1_5/ws/ws_linux/build + +# Utility rule file for geometry_msgs_generate_messages_py. + +# Include the progress variables for this target. +include rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_py.dir/progress.make + +rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_py: + +geometry_msgs_generate_messages_py: rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_py +geometry_msgs_generate_messages_py: rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_py.dir/build.make +.PHONY : geometry_msgs_generate_messages_py + +# Rule to build all files generated by this target. +rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_py.dir/build: geometry_msgs_generate_messages_py +.PHONY : rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_py.dir/build + +rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_py.dir/clean: + cd /home/lab1_5/ws/ws_linux/build/rosaria_msgs && $(CMAKE_COMMAND) -P CMakeFiles/geometry_msgs_generate_messages_py.dir/cmake_clean.cmake +.PHONY : rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_py.dir/clean + +rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_py.dir/depend: + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/lab1_5/ws/ws_linux/src /home/lab1_5/ws/ws_linux/src/rosaria_msgs /home/lab1_5/ws/ws_linux/build /home/lab1_5/ws/ws_linux/build/rosaria_msgs /home/lab1_5/ws/ws_linux/build/rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_py.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_py.dir/depend + diff --git a/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_py.dir/cmake_clean.cmake b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_py.dir/cmake_clean.cmake new file mode 100644 index 0000000..ec52fbc --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_py.dir/cmake_clean.cmake @@ -0,0 +1,8 @@ +FILE(REMOVE_RECURSE + "CMakeFiles/geometry_msgs_generate_messages_py" +) + +# Per-language clean rules from dependency scanning. +FOREACH(lang) + INCLUDE(CMakeFiles/geometry_msgs_generate_messages_py.dir/cmake_clean_${lang}.cmake OPTIONAL) +ENDFOREACH(lang) diff --git a/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_py.dir/depend.internal b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_py.dir/depend.internal new file mode 100644 index 0000000..38eae05 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_py.dir/depend.internal @@ -0,0 +1,3 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + diff --git a/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_py.dir/depend.make b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_py.dir/depend.make new file mode 100644 index 0000000..38eae05 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_py.dir/depend.make @@ -0,0 +1,3 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + diff --git a/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_py.dir/progress.make b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_py.dir/progress.make new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_py.dir/progress.make @@ -0,0 +1 @@ + diff --git a/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/progress.marks b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/progress.marks new file mode 100644 index 0000000..7f8f011 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/progress.marks @@ -0,0 +1 @@ +7 diff --git a/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_gencpp.dir/DependInfo.cmake b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_gencpp.dir/DependInfo.cmake new file mode 100644 index 0000000..8bc32e3 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_gencpp.dir/DependInfo.cmake @@ -0,0 +1,13 @@ +# The set of languages for which implicit dependencies are needed: +SET(CMAKE_DEPENDS_LANGUAGES + ) +# The set of files for implicit dependencies of each language: + +# Preprocessor definitions for this target. +SET(CMAKE_TARGET_DEFINITIONS + "ROS_BUILD_SHARED_LIBS=1" + ) + +# Targets to which this target links. +SET(CMAKE_TARGET_LINKED_INFO_FILES + ) diff --git a/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_gencpp.dir/build.make b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_gencpp.dir/build.make new file mode 100644 index 0000000..89580c8 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_gencpp.dir/build.make @@ -0,0 +1,62 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/lab1_5/ws/ws_linux/src + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/lab1_5/ws/ws_linux/build + +# Utility rule file for rosaria_msgs_gencpp. + +# Include the progress variables for this target. +include rosaria_msgs/CMakeFiles/rosaria_msgs_gencpp.dir/progress.make + +rosaria_msgs/CMakeFiles/rosaria_msgs_gencpp: + +rosaria_msgs_gencpp: rosaria_msgs/CMakeFiles/rosaria_msgs_gencpp +rosaria_msgs_gencpp: rosaria_msgs/CMakeFiles/rosaria_msgs_gencpp.dir/build.make +.PHONY : rosaria_msgs_gencpp + +# Rule to build all files generated by this target. +rosaria_msgs/CMakeFiles/rosaria_msgs_gencpp.dir/build: rosaria_msgs_gencpp +.PHONY : rosaria_msgs/CMakeFiles/rosaria_msgs_gencpp.dir/build + +rosaria_msgs/CMakeFiles/rosaria_msgs_gencpp.dir/clean: + cd /home/lab1_5/ws/ws_linux/build/rosaria_msgs && $(CMAKE_COMMAND) -P CMakeFiles/rosaria_msgs_gencpp.dir/cmake_clean.cmake +.PHONY : rosaria_msgs/CMakeFiles/rosaria_msgs_gencpp.dir/clean + +rosaria_msgs/CMakeFiles/rosaria_msgs_gencpp.dir/depend: + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/lab1_5/ws/ws_linux/src /home/lab1_5/ws/ws_linux/src/rosaria_msgs /home/lab1_5/ws/ws_linux/build /home/lab1_5/ws/ws_linux/build/rosaria_msgs /home/lab1_5/ws/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_gencpp.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : rosaria_msgs/CMakeFiles/rosaria_msgs_gencpp.dir/depend + diff --git a/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_gencpp.dir/cmake_clean.cmake b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_gencpp.dir/cmake_clean.cmake new file mode 100644 index 0000000..2545aab --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_gencpp.dir/cmake_clean.cmake @@ -0,0 +1,8 @@ +FILE(REMOVE_RECURSE + "CMakeFiles/rosaria_msgs_gencpp" +) + +# Per-language clean rules from dependency scanning. +FOREACH(lang) + INCLUDE(CMakeFiles/rosaria_msgs_gencpp.dir/cmake_clean_${lang}.cmake OPTIONAL) +ENDFOREACH(lang) diff --git a/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_gencpp.dir/progress.make b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_gencpp.dir/progress.make new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_gencpp.dir/progress.make @@ -0,0 +1 @@ + diff --git a/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages.dir/DependInfo.cmake b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages.dir/DependInfo.cmake new file mode 100644 index 0000000..8bc32e3 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages.dir/DependInfo.cmake @@ -0,0 +1,13 @@ +# The set of languages for which implicit dependencies are needed: +SET(CMAKE_DEPENDS_LANGUAGES + ) +# The set of files for implicit dependencies of each language: + +# Preprocessor definitions for this target. +SET(CMAKE_TARGET_DEFINITIONS + "ROS_BUILD_SHARED_LIBS=1" + ) + +# Targets to which this target links. +SET(CMAKE_TARGET_LINKED_INFO_FILES + ) diff --git a/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages.dir/build.make b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages.dir/build.make new file mode 100644 index 0000000..797a3f1 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages.dir/build.make @@ -0,0 +1,62 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/lab1_5/ws/ws_linux/src + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/lab1_5/ws/ws_linux/build + +# Utility rule file for rosaria_msgs_generate_messages. + +# Include the progress variables for this target. +include rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages.dir/progress.make + +rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages: + +rosaria_msgs_generate_messages: rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages +rosaria_msgs_generate_messages: rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages.dir/build.make +.PHONY : rosaria_msgs_generate_messages + +# Rule to build all files generated by this target. +rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages.dir/build: rosaria_msgs_generate_messages +.PHONY : rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages.dir/build + +rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages.dir/clean: + cd /home/lab1_5/ws/ws_linux/build/rosaria_msgs && $(CMAKE_COMMAND) -P CMakeFiles/rosaria_msgs_generate_messages.dir/cmake_clean.cmake +.PHONY : rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages.dir/clean + +rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages.dir/depend: + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/lab1_5/ws/ws_linux/src /home/lab1_5/ws/ws_linux/src/rosaria_msgs /home/lab1_5/ws/ws_linux/build /home/lab1_5/ws/ws_linux/build/rosaria_msgs /home/lab1_5/ws/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages.dir/depend + diff --git a/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages.dir/cmake_clean.cmake b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages.dir/cmake_clean.cmake new file mode 100644 index 0000000..64b8c4f --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages.dir/cmake_clean.cmake @@ -0,0 +1,8 @@ +FILE(REMOVE_RECURSE + "CMakeFiles/rosaria_msgs_generate_messages" +) + +# Per-language clean rules from dependency scanning. +FOREACH(lang) + INCLUDE(CMakeFiles/rosaria_msgs_generate_messages.dir/cmake_clean_${lang}.cmake OPTIONAL) +ENDFOREACH(lang) diff --git a/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages.dir/depend.internal b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages.dir/depend.internal new file mode 100644 index 0000000..38eae05 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages.dir/depend.internal @@ -0,0 +1,3 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + diff --git a/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages.dir/depend.make b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages.dir/depend.make new file mode 100644 index 0000000..38eae05 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages.dir/depend.make @@ -0,0 +1,3 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + diff --git a/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages.dir/progress.make b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages.dir/progress.make new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages.dir/progress.make @@ -0,0 +1 @@ + diff --git a/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_cpp.dir/DependInfo.cmake b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_cpp.dir/DependInfo.cmake new file mode 100644 index 0000000..8bc32e3 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_cpp.dir/DependInfo.cmake @@ -0,0 +1,13 @@ +# The set of languages for which implicit dependencies are needed: +SET(CMAKE_DEPENDS_LANGUAGES + ) +# The set of files for implicit dependencies of each language: + +# Preprocessor definitions for this target. +SET(CMAKE_TARGET_DEFINITIONS + "ROS_BUILD_SHARED_LIBS=1" + ) + +# Targets to which this target links. +SET(CMAKE_TARGET_LINKED_INFO_FILES + ) diff --git a/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_cpp.dir/build.make b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_cpp.dir/build.make new file mode 100644 index 0000000..56ff59e --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_cpp.dir/build.make @@ -0,0 +1,85 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/lab1_5/ws/ws_linux/src + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/lab1_5/ws/ws_linux/build + +# Utility rule file for rosaria_msgs_generate_messages_cpp. + +# Include the progress variables for this target. +include rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_cpp.dir/progress.make + +rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_cpp: /home/lab1_5/ws/ws_linux/devel/include/rosaria_msgs/RobotInfoMsg.h +rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_cpp: /home/lab1_5/ws/ws_linux/devel/include/rosaria_msgs/RestrictionsMsg.h + +/home/lab1_5/ws/ws_linux/devel/include/rosaria_msgs/RobotInfoMsg.h: /opt/ros/hydro/share/gencpp/cmake/../../../lib/gencpp/gen_cpp.py +/home/lab1_5/ws/ws_linux/devel/include/rosaria_msgs/RobotInfoMsg.h: /home/lab1_5/ws/ws_linux/src/rosaria_msgs/msg/RobotInfoMsg.msg +/home/lab1_5/ws/ws_linux/devel/include/rosaria_msgs/RobotInfoMsg.h: /opt/ros/hydro/share/geometry_msgs/cmake/../msg/Twist.msg +/home/lab1_5/ws/ws_linux/devel/include/rosaria_msgs/RobotInfoMsg.h: /opt/ros/hydro/share/std_msgs/cmake/../msg/Float64.msg +/home/lab1_5/ws/ws_linux/devel/include/rosaria_msgs/RobotInfoMsg.h: /opt/ros/hydro/share/std_msgs/cmake/../msg/UInt8.msg +/home/lab1_5/ws/ws_linux/devel/include/rosaria_msgs/RobotInfoMsg.h: /opt/ros/hydro/share/geometry_msgs/cmake/../msg/Vector3.msg +/home/lab1_5/ws/ws_linux/devel/include/rosaria_msgs/RobotInfoMsg.h: /opt/ros/hydro/share/std_msgs/cmake/../msg/Bool.msg +/home/lab1_5/ws/ws_linux/devel/include/rosaria_msgs/RobotInfoMsg.h: /opt/ros/hydro/share/gencpp/cmake/../msg.h.template + $(CMAKE_COMMAND) -E cmake_progress_report /home/lab1_5/ws/ws_linux/build/CMakeFiles $(CMAKE_PROGRESS_1) + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --blue --bold "Generating C++ code from rosaria_msgs/RobotInfoMsg.msg" + cd /home/lab1_5/ws/ws_linux/build/rosaria_msgs && ../catkin_generated/env_cached.sh /usr/bin/python /opt/ros/hydro/share/gencpp/cmake/../../../lib/gencpp/gen_cpp.py /home/lab1_5/ws/ws_linux/src/rosaria_msgs/msg/RobotInfoMsg.msg -Irosaria_msgs:/home/lab1_5/ws/ws_linux/src/rosaria_msgs/msg -Istd_msgs:/opt/ros/hydro/share/std_msgs/cmake/../msg -Igeometry_msgs:/opt/ros/hydro/share/geometry_msgs/cmake/../msg -p rosaria_msgs -o /home/lab1_5/ws/ws_linux/devel/include/rosaria_msgs -e /opt/ros/hydro/share/gencpp/cmake/.. + +/home/lab1_5/ws/ws_linux/devel/include/rosaria_msgs/RestrictionsMsg.h: /opt/ros/hydro/share/gencpp/cmake/../../../lib/gencpp/gen_cpp.py +/home/lab1_5/ws/ws_linux/devel/include/rosaria_msgs/RestrictionsMsg.h: /home/lab1_5/ws/ws_linux/src/rosaria_msgs/msg/RestrictionsMsg.msg +/home/lab1_5/ws/ws_linux/devel/include/rosaria_msgs/RestrictionsMsg.h: /opt/ros/hydro/share/std_msgs/cmake/../msg/Float64.msg +/home/lab1_5/ws/ws_linux/devel/include/rosaria_msgs/RestrictionsMsg.h: /opt/ros/hydro/share/gencpp/cmake/../msg.h.template + $(CMAKE_COMMAND) -E cmake_progress_report /home/lab1_5/ws/ws_linux/build/CMakeFiles $(CMAKE_PROGRESS_2) + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --blue --bold "Generating C++ code from rosaria_msgs/RestrictionsMsg.msg" + cd /home/lab1_5/ws/ws_linux/build/rosaria_msgs && ../catkin_generated/env_cached.sh /usr/bin/python /opt/ros/hydro/share/gencpp/cmake/../../../lib/gencpp/gen_cpp.py /home/lab1_5/ws/ws_linux/src/rosaria_msgs/msg/RestrictionsMsg.msg -Irosaria_msgs:/home/lab1_5/ws/ws_linux/src/rosaria_msgs/msg -Istd_msgs:/opt/ros/hydro/share/std_msgs/cmake/../msg -Igeometry_msgs:/opt/ros/hydro/share/geometry_msgs/cmake/../msg -p rosaria_msgs -o /home/lab1_5/ws/ws_linux/devel/include/rosaria_msgs -e /opt/ros/hydro/share/gencpp/cmake/.. + +rosaria_msgs_generate_messages_cpp: rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_cpp +rosaria_msgs_generate_messages_cpp: /home/lab1_5/ws/ws_linux/devel/include/rosaria_msgs/RobotInfoMsg.h +rosaria_msgs_generate_messages_cpp: /home/lab1_5/ws/ws_linux/devel/include/rosaria_msgs/RestrictionsMsg.h +rosaria_msgs_generate_messages_cpp: rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_cpp.dir/build.make +.PHONY : rosaria_msgs_generate_messages_cpp + +# Rule to build all files generated by this target. +rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_cpp.dir/build: rosaria_msgs_generate_messages_cpp +.PHONY : rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_cpp.dir/build + +rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_cpp.dir/clean: + cd /home/lab1_5/ws/ws_linux/build/rosaria_msgs && $(CMAKE_COMMAND) -P CMakeFiles/rosaria_msgs_generate_messages_cpp.dir/cmake_clean.cmake +.PHONY : rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_cpp.dir/clean + +rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_cpp.dir/depend: + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/lab1_5/ws/ws_linux/src /home/lab1_5/ws/ws_linux/src/rosaria_msgs /home/lab1_5/ws/ws_linux/build /home/lab1_5/ws/ws_linux/build/rosaria_msgs /home/lab1_5/ws/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_cpp.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_cpp.dir/depend + diff --git a/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_cpp.dir/cmake_clean.cmake b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_cpp.dir/cmake_clean.cmake new file mode 100644 index 0000000..908b1ea --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_cpp.dir/cmake_clean.cmake @@ -0,0 +1,10 @@ +FILE(REMOVE_RECURSE + "CMakeFiles/rosaria_msgs_generate_messages_cpp" + "/home/lab1_5/ws/ws_linux/devel/include/rosaria_msgs/RobotInfoMsg.h" + "/home/lab1_5/ws/ws_linux/devel/include/rosaria_msgs/RestrictionsMsg.h" +) + +# Per-language clean rules from dependency scanning. +FOREACH(lang) + INCLUDE(CMakeFiles/rosaria_msgs_generate_messages_cpp.dir/cmake_clean_${lang}.cmake OPTIONAL) +ENDFOREACH(lang) diff --git a/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_cpp.dir/depend.internal b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_cpp.dir/depend.internal new file mode 100644 index 0000000..38eae05 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_cpp.dir/depend.internal @@ -0,0 +1,3 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + diff --git a/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_cpp.dir/depend.make b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_cpp.dir/depend.make new file mode 100644 index 0000000..38eae05 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_cpp.dir/depend.make @@ -0,0 +1,3 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + diff --git a/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_cpp.dir/progress.make b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_cpp.dir/progress.make new file mode 100644 index 0000000..596289c --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_cpp.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = 11 +CMAKE_PROGRESS_2 = 12 + diff --git a/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_lisp.dir/DependInfo.cmake b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_lisp.dir/DependInfo.cmake new file mode 100644 index 0000000..8bc32e3 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_lisp.dir/DependInfo.cmake @@ -0,0 +1,13 @@ +# The set of languages for which implicit dependencies are needed: +SET(CMAKE_DEPENDS_LANGUAGES + ) +# The set of files for implicit dependencies of each language: + +# Preprocessor definitions for this target. +SET(CMAKE_TARGET_DEFINITIONS + "ROS_BUILD_SHARED_LIBS=1" + ) + +# Targets to which this target links. +SET(CMAKE_TARGET_LINKED_INFO_FILES + ) diff --git a/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_lisp.dir/build.make b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_lisp.dir/build.make new file mode 100644 index 0000000..2e49e1a --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_lisp.dir/build.make @@ -0,0 +1,83 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/lab1_5/ws/ws_linux/src + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/lab1_5/ws/ws_linux/build + +# Utility rule file for rosaria_msgs_generate_messages_lisp. + +# Include the progress variables for this target. +include rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_lisp.dir/progress.make + +rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_lisp: /home/lab1_5/ws/ws_linux/devel/share/common-lisp/ros/rosaria_msgs/msg/RobotInfoMsg.lisp +rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_lisp: /home/lab1_5/ws/ws_linux/devel/share/common-lisp/ros/rosaria_msgs/msg/RestrictionsMsg.lisp + +/home/lab1_5/ws/ws_linux/devel/share/common-lisp/ros/rosaria_msgs/msg/RobotInfoMsg.lisp: /opt/ros/hydro/share/genlisp/cmake/../../../lib/genlisp/gen_lisp.py +/home/lab1_5/ws/ws_linux/devel/share/common-lisp/ros/rosaria_msgs/msg/RobotInfoMsg.lisp: /home/lab1_5/ws/ws_linux/src/rosaria_msgs/msg/RobotInfoMsg.msg +/home/lab1_5/ws/ws_linux/devel/share/common-lisp/ros/rosaria_msgs/msg/RobotInfoMsg.lisp: /opt/ros/hydro/share/geometry_msgs/cmake/../msg/Twist.msg +/home/lab1_5/ws/ws_linux/devel/share/common-lisp/ros/rosaria_msgs/msg/RobotInfoMsg.lisp: /opt/ros/hydro/share/std_msgs/cmake/../msg/Float64.msg +/home/lab1_5/ws/ws_linux/devel/share/common-lisp/ros/rosaria_msgs/msg/RobotInfoMsg.lisp: /opt/ros/hydro/share/std_msgs/cmake/../msg/UInt8.msg +/home/lab1_5/ws/ws_linux/devel/share/common-lisp/ros/rosaria_msgs/msg/RobotInfoMsg.lisp: /opt/ros/hydro/share/geometry_msgs/cmake/../msg/Vector3.msg +/home/lab1_5/ws/ws_linux/devel/share/common-lisp/ros/rosaria_msgs/msg/RobotInfoMsg.lisp: /opt/ros/hydro/share/std_msgs/cmake/../msg/Bool.msg + $(CMAKE_COMMAND) -E cmake_progress_report /home/lab1_5/ws/ws_linux/build/CMakeFiles $(CMAKE_PROGRESS_1) + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --blue --bold "Generating Lisp code from rosaria_msgs/RobotInfoMsg.msg" + cd /home/lab1_5/ws/ws_linux/build/rosaria_msgs && ../catkin_generated/env_cached.sh /usr/bin/python /opt/ros/hydro/share/genlisp/cmake/../../../lib/genlisp/gen_lisp.py /home/lab1_5/ws/ws_linux/src/rosaria_msgs/msg/RobotInfoMsg.msg -Irosaria_msgs:/home/lab1_5/ws/ws_linux/src/rosaria_msgs/msg -Istd_msgs:/opt/ros/hydro/share/std_msgs/cmake/../msg -Igeometry_msgs:/opt/ros/hydro/share/geometry_msgs/cmake/../msg -p rosaria_msgs -o /home/lab1_5/ws/ws_linux/devel/share/common-lisp/ros/rosaria_msgs/msg + +/home/lab1_5/ws/ws_linux/devel/share/common-lisp/ros/rosaria_msgs/msg/RestrictionsMsg.lisp: /opt/ros/hydro/share/genlisp/cmake/../../../lib/genlisp/gen_lisp.py +/home/lab1_5/ws/ws_linux/devel/share/common-lisp/ros/rosaria_msgs/msg/RestrictionsMsg.lisp: /home/lab1_5/ws/ws_linux/src/rosaria_msgs/msg/RestrictionsMsg.msg +/home/lab1_5/ws/ws_linux/devel/share/common-lisp/ros/rosaria_msgs/msg/RestrictionsMsg.lisp: /opt/ros/hydro/share/std_msgs/cmake/../msg/Float64.msg + $(CMAKE_COMMAND) -E cmake_progress_report /home/lab1_5/ws/ws_linux/build/CMakeFiles $(CMAKE_PROGRESS_2) + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --blue --bold "Generating Lisp code from rosaria_msgs/RestrictionsMsg.msg" + cd /home/lab1_5/ws/ws_linux/build/rosaria_msgs && ../catkin_generated/env_cached.sh /usr/bin/python /opt/ros/hydro/share/genlisp/cmake/../../../lib/genlisp/gen_lisp.py /home/lab1_5/ws/ws_linux/src/rosaria_msgs/msg/RestrictionsMsg.msg -Irosaria_msgs:/home/lab1_5/ws/ws_linux/src/rosaria_msgs/msg -Istd_msgs:/opt/ros/hydro/share/std_msgs/cmake/../msg -Igeometry_msgs:/opt/ros/hydro/share/geometry_msgs/cmake/../msg -p rosaria_msgs -o /home/lab1_5/ws/ws_linux/devel/share/common-lisp/ros/rosaria_msgs/msg + +rosaria_msgs_generate_messages_lisp: rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_lisp +rosaria_msgs_generate_messages_lisp: /home/lab1_5/ws/ws_linux/devel/share/common-lisp/ros/rosaria_msgs/msg/RobotInfoMsg.lisp +rosaria_msgs_generate_messages_lisp: /home/lab1_5/ws/ws_linux/devel/share/common-lisp/ros/rosaria_msgs/msg/RestrictionsMsg.lisp +rosaria_msgs_generate_messages_lisp: rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_lisp.dir/build.make +.PHONY : rosaria_msgs_generate_messages_lisp + +# Rule to build all files generated by this target. +rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_lisp.dir/build: rosaria_msgs_generate_messages_lisp +.PHONY : rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_lisp.dir/build + +rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_lisp.dir/clean: + cd /home/lab1_5/ws/ws_linux/build/rosaria_msgs && $(CMAKE_COMMAND) -P CMakeFiles/rosaria_msgs_generate_messages_lisp.dir/cmake_clean.cmake +.PHONY : rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_lisp.dir/clean + +rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_lisp.dir/depend: + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/lab1_5/ws/ws_linux/src /home/lab1_5/ws/ws_linux/src/rosaria_msgs /home/lab1_5/ws/ws_linux/build /home/lab1_5/ws/ws_linux/build/rosaria_msgs /home/lab1_5/ws/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_lisp.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_lisp.dir/depend + diff --git a/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_lisp.dir/cmake_clean.cmake b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_lisp.dir/cmake_clean.cmake new file mode 100644 index 0000000..6391df9 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_lisp.dir/cmake_clean.cmake @@ -0,0 +1,10 @@ +FILE(REMOVE_RECURSE + "CMakeFiles/rosaria_msgs_generate_messages_lisp" + "/home/lab1_5/ws/ws_linux/devel/share/common-lisp/ros/rosaria_msgs/msg/RobotInfoMsg.lisp" + "/home/lab1_5/ws/ws_linux/devel/share/common-lisp/ros/rosaria_msgs/msg/RestrictionsMsg.lisp" +) + +# Per-language clean rules from dependency scanning. +FOREACH(lang) + INCLUDE(CMakeFiles/rosaria_msgs_generate_messages_lisp.dir/cmake_clean_${lang}.cmake OPTIONAL) +ENDFOREACH(lang) diff --git a/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_lisp.dir/depend.internal b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_lisp.dir/depend.internal new file mode 100644 index 0000000..38eae05 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_lisp.dir/depend.internal @@ -0,0 +1,3 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + diff --git a/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_lisp.dir/depend.make b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_lisp.dir/depend.make new file mode 100644 index 0000000..38eae05 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_lisp.dir/depend.make @@ -0,0 +1,3 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + diff --git a/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_lisp.dir/progress.make b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_lisp.dir/progress.make new file mode 100644 index 0000000..d92f75a --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_lisp.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = 13 +CMAKE_PROGRESS_2 = 14 + diff --git a/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_py.dir/DependInfo.cmake b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_py.dir/DependInfo.cmake new file mode 100644 index 0000000..8bc32e3 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_py.dir/DependInfo.cmake @@ -0,0 +1,13 @@ +# The set of languages for which implicit dependencies are needed: +SET(CMAKE_DEPENDS_LANGUAGES + ) +# The set of files for implicit dependencies of each language: + +# Preprocessor definitions for this target. +SET(CMAKE_TARGET_DEFINITIONS + "ROS_BUILD_SHARED_LIBS=1" + ) + +# Targets to which this target links. +SET(CMAKE_TARGET_LINKED_INFO_FILES + ) diff --git a/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_py.dir/build.make b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_py.dir/build.make new file mode 100644 index 0000000..c84c9b0 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_py.dir/build.make @@ -0,0 +1,92 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/lab1_5/ws/ws_linux/src + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/lab1_5/ws/ws_linux/build + +# Utility rule file for rosaria_msgs_generate_messages_py. + +# Include the progress variables for this target. +include rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_py.dir/progress.make + +rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_py: /home/lab1_5/ws/ws_linux/devel/lib/python2.7/dist-packages/rosaria_msgs/msg/_RobotInfoMsg.py +rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_py: /home/lab1_5/ws/ws_linux/devel/lib/python2.7/dist-packages/rosaria_msgs/msg/_RestrictionsMsg.py +rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_py: /home/lab1_5/ws/ws_linux/devel/lib/python2.7/dist-packages/rosaria_msgs/msg/__init__.py + +/home/lab1_5/ws/ws_linux/devel/lib/python2.7/dist-packages/rosaria_msgs/msg/_RobotInfoMsg.py: /opt/ros/hydro/share/genpy/cmake/../../../lib/genpy/genmsg_py.py +/home/lab1_5/ws/ws_linux/devel/lib/python2.7/dist-packages/rosaria_msgs/msg/_RobotInfoMsg.py: /home/lab1_5/ws/ws_linux/src/rosaria_msgs/msg/RobotInfoMsg.msg +/home/lab1_5/ws/ws_linux/devel/lib/python2.7/dist-packages/rosaria_msgs/msg/_RobotInfoMsg.py: /opt/ros/hydro/share/geometry_msgs/cmake/../msg/Twist.msg +/home/lab1_5/ws/ws_linux/devel/lib/python2.7/dist-packages/rosaria_msgs/msg/_RobotInfoMsg.py: /opt/ros/hydro/share/std_msgs/cmake/../msg/Float64.msg +/home/lab1_5/ws/ws_linux/devel/lib/python2.7/dist-packages/rosaria_msgs/msg/_RobotInfoMsg.py: /opt/ros/hydro/share/std_msgs/cmake/../msg/UInt8.msg +/home/lab1_5/ws/ws_linux/devel/lib/python2.7/dist-packages/rosaria_msgs/msg/_RobotInfoMsg.py: /opt/ros/hydro/share/geometry_msgs/cmake/../msg/Vector3.msg +/home/lab1_5/ws/ws_linux/devel/lib/python2.7/dist-packages/rosaria_msgs/msg/_RobotInfoMsg.py: /opt/ros/hydro/share/std_msgs/cmake/../msg/Bool.msg + $(CMAKE_COMMAND) -E cmake_progress_report /home/lab1_5/ws/ws_linux/build/CMakeFiles $(CMAKE_PROGRESS_1) + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --blue --bold "Generating Python from MSG rosaria_msgs/RobotInfoMsg" + cd /home/lab1_5/ws/ws_linux/build/rosaria_msgs && ../catkin_generated/env_cached.sh /usr/bin/python /opt/ros/hydro/share/genpy/cmake/../../../lib/genpy/genmsg_py.py /home/lab1_5/ws/ws_linux/src/rosaria_msgs/msg/RobotInfoMsg.msg -Irosaria_msgs:/home/lab1_5/ws/ws_linux/src/rosaria_msgs/msg -Istd_msgs:/opt/ros/hydro/share/std_msgs/cmake/../msg -Igeometry_msgs:/opt/ros/hydro/share/geometry_msgs/cmake/../msg -p rosaria_msgs -o /home/lab1_5/ws/ws_linux/devel/lib/python2.7/dist-packages/rosaria_msgs/msg + +/home/lab1_5/ws/ws_linux/devel/lib/python2.7/dist-packages/rosaria_msgs/msg/_RestrictionsMsg.py: /opt/ros/hydro/share/genpy/cmake/../../../lib/genpy/genmsg_py.py +/home/lab1_5/ws/ws_linux/devel/lib/python2.7/dist-packages/rosaria_msgs/msg/_RestrictionsMsg.py: /home/lab1_5/ws/ws_linux/src/rosaria_msgs/msg/RestrictionsMsg.msg +/home/lab1_5/ws/ws_linux/devel/lib/python2.7/dist-packages/rosaria_msgs/msg/_RestrictionsMsg.py: /opt/ros/hydro/share/std_msgs/cmake/../msg/Float64.msg + $(CMAKE_COMMAND) -E cmake_progress_report /home/lab1_5/ws/ws_linux/build/CMakeFiles $(CMAKE_PROGRESS_2) + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --blue --bold "Generating Python from MSG rosaria_msgs/RestrictionsMsg" + cd /home/lab1_5/ws/ws_linux/build/rosaria_msgs && ../catkin_generated/env_cached.sh /usr/bin/python /opt/ros/hydro/share/genpy/cmake/../../../lib/genpy/genmsg_py.py /home/lab1_5/ws/ws_linux/src/rosaria_msgs/msg/RestrictionsMsg.msg -Irosaria_msgs:/home/lab1_5/ws/ws_linux/src/rosaria_msgs/msg -Istd_msgs:/opt/ros/hydro/share/std_msgs/cmake/../msg -Igeometry_msgs:/opt/ros/hydro/share/geometry_msgs/cmake/../msg -p rosaria_msgs -o /home/lab1_5/ws/ws_linux/devel/lib/python2.7/dist-packages/rosaria_msgs/msg + +/home/lab1_5/ws/ws_linux/devel/lib/python2.7/dist-packages/rosaria_msgs/msg/__init__.py: /opt/ros/hydro/share/genpy/cmake/../../../lib/genpy/genmsg_py.py +/home/lab1_5/ws/ws_linux/devel/lib/python2.7/dist-packages/rosaria_msgs/msg/__init__.py: /home/lab1_5/ws/ws_linux/devel/lib/python2.7/dist-packages/rosaria_msgs/msg/_RobotInfoMsg.py +/home/lab1_5/ws/ws_linux/devel/lib/python2.7/dist-packages/rosaria_msgs/msg/__init__.py: /home/lab1_5/ws/ws_linux/devel/lib/python2.7/dist-packages/rosaria_msgs/msg/_RestrictionsMsg.py + $(CMAKE_COMMAND) -E cmake_progress_report /home/lab1_5/ws/ws_linux/build/CMakeFiles $(CMAKE_PROGRESS_3) + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --blue --bold "Generating Python msg __init__.py for rosaria_msgs" + cd /home/lab1_5/ws/ws_linux/build/rosaria_msgs && ../catkin_generated/env_cached.sh /usr/bin/python /opt/ros/hydro/share/genpy/cmake/../../../lib/genpy/genmsg_py.py -o /home/lab1_5/ws/ws_linux/devel/lib/python2.7/dist-packages/rosaria_msgs/msg --initpy + +rosaria_msgs_generate_messages_py: rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_py +rosaria_msgs_generate_messages_py: /home/lab1_5/ws/ws_linux/devel/lib/python2.7/dist-packages/rosaria_msgs/msg/_RobotInfoMsg.py +rosaria_msgs_generate_messages_py: /home/lab1_5/ws/ws_linux/devel/lib/python2.7/dist-packages/rosaria_msgs/msg/_RestrictionsMsg.py +rosaria_msgs_generate_messages_py: /home/lab1_5/ws/ws_linux/devel/lib/python2.7/dist-packages/rosaria_msgs/msg/__init__.py +rosaria_msgs_generate_messages_py: rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_py.dir/build.make +.PHONY : rosaria_msgs_generate_messages_py + +# Rule to build all files generated by this target. +rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_py.dir/build: rosaria_msgs_generate_messages_py +.PHONY : rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_py.dir/build + +rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_py.dir/clean: + cd /home/lab1_5/ws/ws_linux/build/rosaria_msgs && $(CMAKE_COMMAND) -P CMakeFiles/rosaria_msgs_generate_messages_py.dir/cmake_clean.cmake +.PHONY : rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_py.dir/clean + +rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_py.dir/depend: + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/lab1_5/ws/ws_linux/src /home/lab1_5/ws/ws_linux/src/rosaria_msgs /home/lab1_5/ws/ws_linux/build /home/lab1_5/ws/ws_linux/build/rosaria_msgs /home/lab1_5/ws/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_py.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_py.dir/depend + diff --git a/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_py.dir/cmake_clean.cmake b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_py.dir/cmake_clean.cmake new file mode 100644 index 0000000..2a70c06 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_py.dir/cmake_clean.cmake @@ -0,0 +1,11 @@ +FILE(REMOVE_RECURSE + "CMakeFiles/rosaria_msgs_generate_messages_py" + "/home/lab1_5/ws/ws_linux/devel/lib/python2.7/dist-packages/rosaria_msgs/msg/_RobotInfoMsg.py" + "/home/lab1_5/ws/ws_linux/devel/lib/python2.7/dist-packages/rosaria_msgs/msg/_RestrictionsMsg.py" + "/home/lab1_5/ws/ws_linux/devel/lib/python2.7/dist-packages/rosaria_msgs/msg/__init__.py" +) + +# Per-language clean rules from dependency scanning. +FOREACH(lang) + INCLUDE(CMakeFiles/rosaria_msgs_generate_messages_py.dir/cmake_clean_${lang}.cmake OPTIONAL) +ENDFOREACH(lang) diff --git a/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_py.dir/depend.internal b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_py.dir/depend.internal new file mode 100644 index 0000000..38eae05 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_py.dir/depend.internal @@ -0,0 +1,3 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + diff --git a/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_py.dir/depend.make b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_py.dir/depend.make new file mode 100644 index 0000000..38eae05 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_py.dir/depend.make @@ -0,0 +1,3 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + diff --git a/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_py.dir/progress.make b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_py.dir/progress.make new file mode 100644 index 0000000..06dbb11 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_py.dir/progress.make @@ -0,0 +1,4 @@ +CMAKE_PROGRESS_1 = 15 +CMAKE_PROGRESS_2 = 16 +CMAKE_PROGRESS_3 = 17 + diff --git a/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_genlisp.dir/DependInfo.cmake b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_genlisp.dir/DependInfo.cmake new file mode 100644 index 0000000..8bc32e3 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_genlisp.dir/DependInfo.cmake @@ -0,0 +1,13 @@ +# The set of languages for which implicit dependencies are needed: +SET(CMAKE_DEPENDS_LANGUAGES + ) +# The set of files for implicit dependencies of each language: + +# Preprocessor definitions for this target. +SET(CMAKE_TARGET_DEFINITIONS + "ROS_BUILD_SHARED_LIBS=1" + ) + +# Targets to which this target links. +SET(CMAKE_TARGET_LINKED_INFO_FILES + ) diff --git a/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_genlisp.dir/build.make b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_genlisp.dir/build.make new file mode 100644 index 0000000..385029c --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_genlisp.dir/build.make @@ -0,0 +1,62 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/lab1_5/ws/ws_linux/src + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/lab1_5/ws/ws_linux/build + +# Utility rule file for rosaria_msgs_genlisp. + +# Include the progress variables for this target. +include rosaria_msgs/CMakeFiles/rosaria_msgs_genlisp.dir/progress.make + +rosaria_msgs/CMakeFiles/rosaria_msgs_genlisp: + +rosaria_msgs_genlisp: rosaria_msgs/CMakeFiles/rosaria_msgs_genlisp +rosaria_msgs_genlisp: rosaria_msgs/CMakeFiles/rosaria_msgs_genlisp.dir/build.make +.PHONY : rosaria_msgs_genlisp + +# Rule to build all files generated by this target. +rosaria_msgs/CMakeFiles/rosaria_msgs_genlisp.dir/build: rosaria_msgs_genlisp +.PHONY : rosaria_msgs/CMakeFiles/rosaria_msgs_genlisp.dir/build + +rosaria_msgs/CMakeFiles/rosaria_msgs_genlisp.dir/clean: + cd /home/lab1_5/ws/ws_linux/build/rosaria_msgs && $(CMAKE_COMMAND) -P CMakeFiles/rosaria_msgs_genlisp.dir/cmake_clean.cmake +.PHONY : rosaria_msgs/CMakeFiles/rosaria_msgs_genlisp.dir/clean + +rosaria_msgs/CMakeFiles/rosaria_msgs_genlisp.dir/depend: + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/lab1_5/ws/ws_linux/src /home/lab1_5/ws/ws_linux/src/rosaria_msgs /home/lab1_5/ws/ws_linux/build /home/lab1_5/ws/ws_linux/build/rosaria_msgs /home/lab1_5/ws/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_genlisp.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : rosaria_msgs/CMakeFiles/rosaria_msgs_genlisp.dir/depend + diff --git a/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_genlisp.dir/cmake_clean.cmake b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_genlisp.dir/cmake_clean.cmake new file mode 100644 index 0000000..f42aa50 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_genlisp.dir/cmake_clean.cmake @@ -0,0 +1,8 @@ +FILE(REMOVE_RECURSE + "CMakeFiles/rosaria_msgs_genlisp" +) + +# Per-language clean rules from dependency scanning. +FOREACH(lang) + INCLUDE(CMakeFiles/rosaria_msgs_genlisp.dir/cmake_clean_${lang}.cmake OPTIONAL) +ENDFOREACH(lang) diff --git a/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_genlisp.dir/progress.make b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_genlisp.dir/progress.make new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_genlisp.dir/progress.make @@ -0,0 +1 @@ + diff --git a/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_genpy.dir/DependInfo.cmake b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_genpy.dir/DependInfo.cmake new file mode 100644 index 0000000..8bc32e3 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_genpy.dir/DependInfo.cmake @@ -0,0 +1,13 @@ +# The set of languages for which implicit dependencies are needed: +SET(CMAKE_DEPENDS_LANGUAGES + ) +# The set of files for implicit dependencies of each language: + +# Preprocessor definitions for this target. +SET(CMAKE_TARGET_DEFINITIONS + "ROS_BUILD_SHARED_LIBS=1" + ) + +# Targets to which this target links. +SET(CMAKE_TARGET_LINKED_INFO_FILES + ) diff --git a/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_genpy.dir/build.make b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_genpy.dir/build.make new file mode 100644 index 0000000..a77ce1e --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_genpy.dir/build.make @@ -0,0 +1,62 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/lab1_5/ws/ws_linux/src + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/lab1_5/ws/ws_linux/build + +# Utility rule file for rosaria_msgs_genpy. + +# Include the progress variables for this target. +include rosaria_msgs/CMakeFiles/rosaria_msgs_genpy.dir/progress.make + +rosaria_msgs/CMakeFiles/rosaria_msgs_genpy: + +rosaria_msgs_genpy: rosaria_msgs/CMakeFiles/rosaria_msgs_genpy +rosaria_msgs_genpy: rosaria_msgs/CMakeFiles/rosaria_msgs_genpy.dir/build.make +.PHONY : rosaria_msgs_genpy + +# Rule to build all files generated by this target. +rosaria_msgs/CMakeFiles/rosaria_msgs_genpy.dir/build: rosaria_msgs_genpy +.PHONY : rosaria_msgs/CMakeFiles/rosaria_msgs_genpy.dir/build + +rosaria_msgs/CMakeFiles/rosaria_msgs_genpy.dir/clean: + cd /home/lab1_5/ws/ws_linux/build/rosaria_msgs && $(CMAKE_COMMAND) -P CMakeFiles/rosaria_msgs_genpy.dir/cmake_clean.cmake +.PHONY : rosaria_msgs/CMakeFiles/rosaria_msgs_genpy.dir/clean + +rosaria_msgs/CMakeFiles/rosaria_msgs_genpy.dir/depend: + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/lab1_5/ws/ws_linux/src /home/lab1_5/ws/ws_linux/src/rosaria_msgs /home/lab1_5/ws/ws_linux/build /home/lab1_5/ws/ws_linux/build/rosaria_msgs /home/lab1_5/ws/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_genpy.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : rosaria_msgs/CMakeFiles/rosaria_msgs_genpy.dir/depend + diff --git a/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_genpy.dir/cmake_clean.cmake b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_genpy.dir/cmake_clean.cmake new file mode 100644 index 0000000..eb9e13f --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_genpy.dir/cmake_clean.cmake @@ -0,0 +1,8 @@ +FILE(REMOVE_RECURSE + "CMakeFiles/rosaria_msgs_genpy" +) + +# Per-language clean rules from dependency scanning. +FOREACH(lang) + INCLUDE(CMakeFiles/rosaria_msgs_genpy.dir/cmake_clean_${lang}.cmake OPTIONAL) +ENDFOREACH(lang) diff --git a/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_genpy.dir/progress.make b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_genpy.dir/progress.make new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/rosaria_msgs_genpy.dir/progress.make @@ -0,0 +1 @@ + diff --git a/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/std_msgs_generate_messages_cpp.dir/DependInfo.cmake b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/std_msgs_generate_messages_cpp.dir/DependInfo.cmake new file mode 100644 index 0000000..8bc32e3 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/std_msgs_generate_messages_cpp.dir/DependInfo.cmake @@ -0,0 +1,13 @@ +# The set of languages for which implicit dependencies are needed: +SET(CMAKE_DEPENDS_LANGUAGES + ) +# The set of files for implicit dependencies of each language: + +# Preprocessor definitions for this target. +SET(CMAKE_TARGET_DEFINITIONS + "ROS_BUILD_SHARED_LIBS=1" + ) + +# Targets to which this target links. +SET(CMAKE_TARGET_LINKED_INFO_FILES + ) diff --git a/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/std_msgs_generate_messages_cpp.dir/build.make b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/std_msgs_generate_messages_cpp.dir/build.make new file mode 100644 index 0000000..4ea0533 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/std_msgs_generate_messages_cpp.dir/build.make @@ -0,0 +1,62 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/lab1_5/ws/ws_linux/src + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/lab1_5/ws/ws_linux/build + +# Utility rule file for std_msgs_generate_messages_cpp. + +# Include the progress variables for this target. +include rosaria_msgs/CMakeFiles/std_msgs_generate_messages_cpp.dir/progress.make + +rosaria_msgs/CMakeFiles/std_msgs_generate_messages_cpp: + +std_msgs_generate_messages_cpp: rosaria_msgs/CMakeFiles/std_msgs_generate_messages_cpp +std_msgs_generate_messages_cpp: rosaria_msgs/CMakeFiles/std_msgs_generate_messages_cpp.dir/build.make +.PHONY : std_msgs_generate_messages_cpp + +# Rule to build all files generated by this target. +rosaria_msgs/CMakeFiles/std_msgs_generate_messages_cpp.dir/build: std_msgs_generate_messages_cpp +.PHONY : rosaria_msgs/CMakeFiles/std_msgs_generate_messages_cpp.dir/build + +rosaria_msgs/CMakeFiles/std_msgs_generate_messages_cpp.dir/clean: + cd /home/lab1_5/ws/ws_linux/build/rosaria_msgs && $(CMAKE_COMMAND) -P CMakeFiles/std_msgs_generate_messages_cpp.dir/cmake_clean.cmake +.PHONY : rosaria_msgs/CMakeFiles/std_msgs_generate_messages_cpp.dir/clean + +rosaria_msgs/CMakeFiles/std_msgs_generate_messages_cpp.dir/depend: + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/lab1_5/ws/ws_linux/src /home/lab1_5/ws/ws_linux/src/rosaria_msgs /home/lab1_5/ws/ws_linux/build /home/lab1_5/ws/ws_linux/build/rosaria_msgs /home/lab1_5/ws/ws_linux/build/rosaria_msgs/CMakeFiles/std_msgs_generate_messages_cpp.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : rosaria_msgs/CMakeFiles/std_msgs_generate_messages_cpp.dir/depend + diff --git a/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/std_msgs_generate_messages_cpp.dir/cmake_clean.cmake b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/std_msgs_generate_messages_cpp.dir/cmake_clean.cmake new file mode 100644 index 0000000..6d9f3cf --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/std_msgs_generate_messages_cpp.dir/cmake_clean.cmake @@ -0,0 +1,8 @@ +FILE(REMOVE_RECURSE + "CMakeFiles/std_msgs_generate_messages_cpp" +) + +# Per-language clean rules from dependency scanning. +FOREACH(lang) + INCLUDE(CMakeFiles/std_msgs_generate_messages_cpp.dir/cmake_clean_${lang}.cmake OPTIONAL) +ENDFOREACH(lang) diff --git a/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/std_msgs_generate_messages_cpp.dir/depend.internal b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/std_msgs_generate_messages_cpp.dir/depend.internal new file mode 100644 index 0000000..38eae05 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/std_msgs_generate_messages_cpp.dir/depend.internal @@ -0,0 +1,3 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + diff --git a/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/std_msgs_generate_messages_cpp.dir/depend.make b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/std_msgs_generate_messages_cpp.dir/depend.make new file mode 100644 index 0000000..38eae05 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/std_msgs_generate_messages_cpp.dir/depend.make @@ -0,0 +1,3 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + diff --git a/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/std_msgs_generate_messages_cpp.dir/progress.make b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/std_msgs_generate_messages_cpp.dir/progress.make new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/std_msgs_generate_messages_cpp.dir/progress.make @@ -0,0 +1 @@ + diff --git a/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/std_msgs_generate_messages_lisp.dir/DependInfo.cmake b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/std_msgs_generate_messages_lisp.dir/DependInfo.cmake new file mode 100644 index 0000000..8bc32e3 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/std_msgs_generate_messages_lisp.dir/DependInfo.cmake @@ -0,0 +1,13 @@ +# The set of languages for which implicit dependencies are needed: +SET(CMAKE_DEPENDS_LANGUAGES + ) +# The set of files for implicit dependencies of each language: + +# Preprocessor definitions for this target. +SET(CMAKE_TARGET_DEFINITIONS + "ROS_BUILD_SHARED_LIBS=1" + ) + +# Targets to which this target links. +SET(CMAKE_TARGET_LINKED_INFO_FILES + ) diff --git a/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/std_msgs_generate_messages_lisp.dir/build.make b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/std_msgs_generate_messages_lisp.dir/build.make new file mode 100644 index 0000000..7e0e5b3 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/std_msgs_generate_messages_lisp.dir/build.make @@ -0,0 +1,62 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/lab1_5/ws/ws_linux/src + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/lab1_5/ws/ws_linux/build + +# Utility rule file for std_msgs_generate_messages_lisp. + +# Include the progress variables for this target. +include rosaria_msgs/CMakeFiles/std_msgs_generate_messages_lisp.dir/progress.make + +rosaria_msgs/CMakeFiles/std_msgs_generate_messages_lisp: + +std_msgs_generate_messages_lisp: rosaria_msgs/CMakeFiles/std_msgs_generate_messages_lisp +std_msgs_generate_messages_lisp: rosaria_msgs/CMakeFiles/std_msgs_generate_messages_lisp.dir/build.make +.PHONY : std_msgs_generate_messages_lisp + +# Rule to build all files generated by this target. +rosaria_msgs/CMakeFiles/std_msgs_generate_messages_lisp.dir/build: std_msgs_generate_messages_lisp +.PHONY : rosaria_msgs/CMakeFiles/std_msgs_generate_messages_lisp.dir/build + +rosaria_msgs/CMakeFiles/std_msgs_generate_messages_lisp.dir/clean: + cd /home/lab1_5/ws/ws_linux/build/rosaria_msgs && $(CMAKE_COMMAND) -P CMakeFiles/std_msgs_generate_messages_lisp.dir/cmake_clean.cmake +.PHONY : rosaria_msgs/CMakeFiles/std_msgs_generate_messages_lisp.dir/clean + +rosaria_msgs/CMakeFiles/std_msgs_generate_messages_lisp.dir/depend: + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/lab1_5/ws/ws_linux/src /home/lab1_5/ws/ws_linux/src/rosaria_msgs /home/lab1_5/ws/ws_linux/build /home/lab1_5/ws/ws_linux/build/rosaria_msgs /home/lab1_5/ws/ws_linux/build/rosaria_msgs/CMakeFiles/std_msgs_generate_messages_lisp.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : rosaria_msgs/CMakeFiles/std_msgs_generate_messages_lisp.dir/depend + diff --git a/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/std_msgs_generate_messages_lisp.dir/cmake_clean.cmake b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/std_msgs_generate_messages_lisp.dir/cmake_clean.cmake new file mode 100644 index 0000000..1629779 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/std_msgs_generate_messages_lisp.dir/cmake_clean.cmake @@ -0,0 +1,8 @@ +FILE(REMOVE_RECURSE + "CMakeFiles/std_msgs_generate_messages_lisp" +) + +# Per-language clean rules from dependency scanning. +FOREACH(lang) + INCLUDE(CMakeFiles/std_msgs_generate_messages_lisp.dir/cmake_clean_${lang}.cmake OPTIONAL) +ENDFOREACH(lang) diff --git a/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/std_msgs_generate_messages_lisp.dir/depend.internal b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/std_msgs_generate_messages_lisp.dir/depend.internal new file mode 100644 index 0000000..38eae05 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/std_msgs_generate_messages_lisp.dir/depend.internal @@ -0,0 +1,3 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + diff --git a/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/std_msgs_generate_messages_lisp.dir/depend.make b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/std_msgs_generate_messages_lisp.dir/depend.make new file mode 100644 index 0000000..38eae05 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/std_msgs_generate_messages_lisp.dir/depend.make @@ -0,0 +1,3 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + diff --git a/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/std_msgs_generate_messages_lisp.dir/progress.make b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/std_msgs_generate_messages_lisp.dir/progress.make new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/std_msgs_generate_messages_lisp.dir/progress.make @@ -0,0 +1 @@ + diff --git a/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/std_msgs_generate_messages_py.dir/DependInfo.cmake b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/std_msgs_generate_messages_py.dir/DependInfo.cmake new file mode 100644 index 0000000..8bc32e3 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/std_msgs_generate_messages_py.dir/DependInfo.cmake @@ -0,0 +1,13 @@ +# The set of languages for which implicit dependencies are needed: +SET(CMAKE_DEPENDS_LANGUAGES + ) +# The set of files for implicit dependencies of each language: + +# Preprocessor definitions for this target. +SET(CMAKE_TARGET_DEFINITIONS + "ROS_BUILD_SHARED_LIBS=1" + ) + +# Targets to which this target links. +SET(CMAKE_TARGET_LINKED_INFO_FILES + ) diff --git a/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/std_msgs_generate_messages_py.dir/build.make b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/std_msgs_generate_messages_py.dir/build.make new file mode 100644 index 0000000..c1e4d16 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/std_msgs_generate_messages_py.dir/build.make @@ -0,0 +1,62 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/lab1_5/ws/ws_linux/src + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/lab1_5/ws/ws_linux/build + +# Utility rule file for std_msgs_generate_messages_py. + +# Include the progress variables for this target. +include rosaria_msgs/CMakeFiles/std_msgs_generate_messages_py.dir/progress.make + +rosaria_msgs/CMakeFiles/std_msgs_generate_messages_py: + +std_msgs_generate_messages_py: rosaria_msgs/CMakeFiles/std_msgs_generate_messages_py +std_msgs_generate_messages_py: rosaria_msgs/CMakeFiles/std_msgs_generate_messages_py.dir/build.make +.PHONY : std_msgs_generate_messages_py + +# Rule to build all files generated by this target. +rosaria_msgs/CMakeFiles/std_msgs_generate_messages_py.dir/build: std_msgs_generate_messages_py +.PHONY : rosaria_msgs/CMakeFiles/std_msgs_generate_messages_py.dir/build + +rosaria_msgs/CMakeFiles/std_msgs_generate_messages_py.dir/clean: + cd /home/lab1_5/ws/ws_linux/build/rosaria_msgs && $(CMAKE_COMMAND) -P CMakeFiles/std_msgs_generate_messages_py.dir/cmake_clean.cmake +.PHONY : rosaria_msgs/CMakeFiles/std_msgs_generate_messages_py.dir/clean + +rosaria_msgs/CMakeFiles/std_msgs_generate_messages_py.dir/depend: + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/lab1_5/ws/ws_linux/src /home/lab1_5/ws/ws_linux/src/rosaria_msgs /home/lab1_5/ws/ws_linux/build /home/lab1_5/ws/ws_linux/build/rosaria_msgs /home/lab1_5/ws/ws_linux/build/rosaria_msgs/CMakeFiles/std_msgs_generate_messages_py.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : rosaria_msgs/CMakeFiles/std_msgs_generate_messages_py.dir/depend + diff --git a/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/std_msgs_generate_messages_py.dir/cmake_clean.cmake b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/std_msgs_generate_messages_py.dir/cmake_clean.cmake new file mode 100644 index 0000000..73217c0 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/std_msgs_generate_messages_py.dir/cmake_clean.cmake @@ -0,0 +1,8 @@ +FILE(REMOVE_RECURSE + "CMakeFiles/std_msgs_generate_messages_py" +) + +# Per-language clean rules from dependency scanning. +FOREACH(lang) + INCLUDE(CMakeFiles/std_msgs_generate_messages_py.dir/cmake_clean_${lang}.cmake OPTIONAL) +ENDFOREACH(lang) diff --git a/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/std_msgs_generate_messages_py.dir/depend.internal b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/std_msgs_generate_messages_py.dir/depend.internal new file mode 100644 index 0000000..38eae05 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/std_msgs_generate_messages_py.dir/depend.internal @@ -0,0 +1,3 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + diff --git a/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/std_msgs_generate_messages_py.dir/depend.make b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/std_msgs_generate_messages_py.dir/depend.make new file mode 100644 index 0000000..38eae05 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/std_msgs_generate_messages_py.dir/depend.make @@ -0,0 +1,3 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + diff --git a/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/std_msgs_generate_messages_py.dir/progress.make b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/std_msgs_generate_messages_py.dir/progress.make new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/CMakeFiles/std_msgs_generate_messages_py.dir/progress.make @@ -0,0 +1 @@ + diff --git a/Legacy/ws_linux/build/rosaria_msgs/CTestTestfile.cmake b/Legacy/ws_linux/build/rosaria_msgs/CTestTestfile.cmake new file mode 100644 index 0000000..8682ab6 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/CTestTestfile.cmake @@ -0,0 +1,6 @@ +# CMake generated Testfile for +# Source directory: /home/lab1_5/ws/ws_linux/src/rosaria_msgs +# Build directory: /home/lab1_5/ws/ws_linux/build/rosaria_msgs +# +# This file includes the relevent testing commands required for +# testing this directory and lists subdirectories to be tested as well. diff --git a/Legacy/ws_linux/build/rosaria_msgs/Makefile b/Legacy/ws_linux/build/rosaria_msgs/Makefile new file mode 100644 index 0000000..577627d --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/Makefile @@ -0,0 +1,370 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +# Default target executed when no arguments are given to make. +default_target: all +.PHONY : default_target + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/lab1_5/ws/ws_linux/src + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/lab1_5/ws/ws_linux/build + +#============================================================================= +# Targets provided globally by CMake. + +# Special rule for the target edit_cache +edit_cache: + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running interactive CMake command-line interface..." + /usr/bin/cmake -i . +.PHONY : edit_cache + +# Special rule for the target edit_cache +edit_cache/fast: edit_cache +.PHONY : edit_cache/fast + +# Special rule for the target install +install: preinstall + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Install the project..." + /usr/bin/cmake -P cmake_install.cmake +.PHONY : install + +# Special rule for the target install +install/fast: preinstall/fast + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Install the project..." + /usr/bin/cmake -P cmake_install.cmake +.PHONY : install/fast + +# Special rule for the target install/local +install/local: preinstall + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Installing only the local directory..." + /usr/bin/cmake -DCMAKE_INSTALL_LOCAL_ONLY=1 -P cmake_install.cmake +.PHONY : install/local + +# Special rule for the target install/local +install/local/fast: install/local +.PHONY : install/local/fast + +# Special rule for the target install/strip +install/strip: preinstall + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Installing the project stripped..." + /usr/bin/cmake -DCMAKE_INSTALL_DO_STRIP=1 -P cmake_install.cmake +.PHONY : install/strip + +# Special rule for the target install/strip +install/strip/fast: install/strip +.PHONY : install/strip/fast + +# Special rule for the target list_install_components +list_install_components: + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Available install components are: \"Unspecified\"" +.PHONY : list_install_components + +# Special rule for the target list_install_components +list_install_components/fast: list_install_components +.PHONY : list_install_components/fast + +# Special rule for the target rebuild_cache +rebuild_cache: + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running CMake to regenerate build system..." + /usr/bin/cmake -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) +.PHONY : rebuild_cache + +# Special rule for the target rebuild_cache +rebuild_cache/fast: rebuild_cache +.PHONY : rebuild_cache/fast + +# Special rule for the target test +test: + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running tests..." + /usr/bin/ctest --force-new-ctest-process $(ARGS) +.PHONY : test + +# Special rule for the target test +test/fast: test +.PHONY : test/fast + +# The main all target +all: cmake_check_build_system + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -E cmake_progress_start /home/lab1_5/ws/ws_linux/build/CMakeFiles /home/lab1_5/ws/ws_linux/build/rosaria_msgs/CMakeFiles/progress.marks + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 rosaria_msgs/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/lab1_5/ws/ws_linux/build/CMakeFiles 0 +.PHONY : all + +# The main clean target +clean: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 rosaria_msgs/clean +.PHONY : clean + +# The main clean target +clean/fast: clean +.PHONY : clean/fast + +# Prepare targets for installation. +preinstall: all + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 rosaria_msgs/preinstall +.PHONY : preinstall + +# Prepare targets for installation. +preinstall/fast: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 rosaria_msgs/preinstall +.PHONY : preinstall/fast + +# clear depends +depend: + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 1 +.PHONY : depend + +# Convenience name for target. +rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_cpp.dir/rule: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_cpp.dir/rule +.PHONY : rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_cpp.dir/rule + +# Convenience name for target. +geometry_msgs_generate_messages_cpp: rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_cpp.dir/rule +.PHONY : geometry_msgs_generate_messages_cpp + +# fast build rule for target. +geometry_msgs_generate_messages_cpp/fast: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_cpp.dir/build.make rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_cpp.dir/build +.PHONY : geometry_msgs_generate_messages_cpp/fast + +# Convenience name for target. +rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_lisp.dir/rule: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_lisp.dir/rule +.PHONY : rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_lisp.dir/rule + +# Convenience name for target. +geometry_msgs_generate_messages_lisp: rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_lisp.dir/rule +.PHONY : geometry_msgs_generate_messages_lisp + +# fast build rule for target. +geometry_msgs_generate_messages_lisp/fast: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_lisp.dir/build.make rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_lisp.dir/build +.PHONY : geometry_msgs_generate_messages_lisp/fast + +# Convenience name for target. +rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_py.dir/rule: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_py.dir/rule +.PHONY : rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_py.dir/rule + +# Convenience name for target. +geometry_msgs_generate_messages_py: rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_py.dir/rule +.PHONY : geometry_msgs_generate_messages_py + +# fast build rule for target. +geometry_msgs_generate_messages_py/fast: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_py.dir/build.make rosaria_msgs/CMakeFiles/geometry_msgs_generate_messages_py.dir/build +.PHONY : geometry_msgs_generate_messages_py/fast + +# Convenience name for target. +rosaria_msgs/CMakeFiles/rosaria_msgs_gencpp.dir/rule: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 rosaria_msgs/CMakeFiles/rosaria_msgs_gencpp.dir/rule +.PHONY : rosaria_msgs/CMakeFiles/rosaria_msgs_gencpp.dir/rule + +# Convenience name for target. +rosaria_msgs_gencpp: rosaria_msgs/CMakeFiles/rosaria_msgs_gencpp.dir/rule +.PHONY : rosaria_msgs_gencpp + +# fast build rule for target. +rosaria_msgs_gencpp/fast: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f rosaria_msgs/CMakeFiles/rosaria_msgs_gencpp.dir/build.make rosaria_msgs/CMakeFiles/rosaria_msgs_gencpp.dir/build +.PHONY : rosaria_msgs_gencpp/fast + +# Convenience name for target. +rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages.dir/rule: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages.dir/rule +.PHONY : rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages.dir/rule + +# Convenience name for target. +rosaria_msgs_generate_messages: rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages.dir/rule +.PHONY : rosaria_msgs_generate_messages + +# fast build rule for target. +rosaria_msgs_generate_messages/fast: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages.dir/build.make rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages.dir/build +.PHONY : rosaria_msgs_generate_messages/fast + +# Convenience name for target. +rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_cpp.dir/rule: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_cpp.dir/rule +.PHONY : rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_cpp.dir/rule + +# Convenience name for target. +rosaria_msgs_generate_messages_cpp: rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_cpp.dir/rule +.PHONY : rosaria_msgs_generate_messages_cpp + +# fast build rule for target. +rosaria_msgs_generate_messages_cpp/fast: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_cpp.dir/build.make rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_cpp.dir/build +.PHONY : rosaria_msgs_generate_messages_cpp/fast + +# Convenience name for target. +rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_lisp.dir/rule: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_lisp.dir/rule +.PHONY : rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_lisp.dir/rule + +# Convenience name for target. +rosaria_msgs_generate_messages_lisp: rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_lisp.dir/rule +.PHONY : rosaria_msgs_generate_messages_lisp + +# fast build rule for target. +rosaria_msgs_generate_messages_lisp/fast: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_lisp.dir/build.make rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_lisp.dir/build +.PHONY : rosaria_msgs_generate_messages_lisp/fast + +# Convenience name for target. +rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_py.dir/rule: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_py.dir/rule +.PHONY : rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_py.dir/rule + +# Convenience name for target. +rosaria_msgs_generate_messages_py: rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_py.dir/rule +.PHONY : rosaria_msgs_generate_messages_py + +# fast build rule for target. +rosaria_msgs_generate_messages_py/fast: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_py.dir/build.make rosaria_msgs/CMakeFiles/rosaria_msgs_generate_messages_py.dir/build +.PHONY : rosaria_msgs_generate_messages_py/fast + +# Convenience name for target. +rosaria_msgs/CMakeFiles/rosaria_msgs_genlisp.dir/rule: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 rosaria_msgs/CMakeFiles/rosaria_msgs_genlisp.dir/rule +.PHONY : rosaria_msgs/CMakeFiles/rosaria_msgs_genlisp.dir/rule + +# Convenience name for target. +rosaria_msgs_genlisp: rosaria_msgs/CMakeFiles/rosaria_msgs_genlisp.dir/rule +.PHONY : rosaria_msgs_genlisp + +# fast build rule for target. +rosaria_msgs_genlisp/fast: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f rosaria_msgs/CMakeFiles/rosaria_msgs_genlisp.dir/build.make rosaria_msgs/CMakeFiles/rosaria_msgs_genlisp.dir/build +.PHONY : rosaria_msgs_genlisp/fast + +# Convenience name for target. +rosaria_msgs/CMakeFiles/rosaria_msgs_genpy.dir/rule: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 rosaria_msgs/CMakeFiles/rosaria_msgs_genpy.dir/rule +.PHONY : rosaria_msgs/CMakeFiles/rosaria_msgs_genpy.dir/rule + +# Convenience name for target. +rosaria_msgs_genpy: rosaria_msgs/CMakeFiles/rosaria_msgs_genpy.dir/rule +.PHONY : rosaria_msgs_genpy + +# fast build rule for target. +rosaria_msgs_genpy/fast: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f rosaria_msgs/CMakeFiles/rosaria_msgs_genpy.dir/build.make rosaria_msgs/CMakeFiles/rosaria_msgs_genpy.dir/build +.PHONY : rosaria_msgs_genpy/fast + +# Convenience name for target. +rosaria_msgs/CMakeFiles/std_msgs_generate_messages_cpp.dir/rule: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 rosaria_msgs/CMakeFiles/std_msgs_generate_messages_cpp.dir/rule +.PHONY : rosaria_msgs/CMakeFiles/std_msgs_generate_messages_cpp.dir/rule + +# Convenience name for target. +std_msgs_generate_messages_cpp: rosaria_msgs/CMakeFiles/std_msgs_generate_messages_cpp.dir/rule +.PHONY : std_msgs_generate_messages_cpp + +# fast build rule for target. +std_msgs_generate_messages_cpp/fast: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f rosaria_msgs/CMakeFiles/std_msgs_generate_messages_cpp.dir/build.make rosaria_msgs/CMakeFiles/std_msgs_generate_messages_cpp.dir/build +.PHONY : std_msgs_generate_messages_cpp/fast + +# Convenience name for target. +rosaria_msgs/CMakeFiles/std_msgs_generate_messages_lisp.dir/rule: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 rosaria_msgs/CMakeFiles/std_msgs_generate_messages_lisp.dir/rule +.PHONY : rosaria_msgs/CMakeFiles/std_msgs_generate_messages_lisp.dir/rule + +# Convenience name for target. +std_msgs_generate_messages_lisp: rosaria_msgs/CMakeFiles/std_msgs_generate_messages_lisp.dir/rule +.PHONY : std_msgs_generate_messages_lisp + +# fast build rule for target. +std_msgs_generate_messages_lisp/fast: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f rosaria_msgs/CMakeFiles/std_msgs_generate_messages_lisp.dir/build.make rosaria_msgs/CMakeFiles/std_msgs_generate_messages_lisp.dir/build +.PHONY : std_msgs_generate_messages_lisp/fast + +# Convenience name for target. +rosaria_msgs/CMakeFiles/std_msgs_generate_messages_py.dir/rule: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 rosaria_msgs/CMakeFiles/std_msgs_generate_messages_py.dir/rule +.PHONY : rosaria_msgs/CMakeFiles/std_msgs_generate_messages_py.dir/rule + +# Convenience name for target. +std_msgs_generate_messages_py: rosaria_msgs/CMakeFiles/std_msgs_generate_messages_py.dir/rule +.PHONY : std_msgs_generate_messages_py + +# fast build rule for target. +std_msgs_generate_messages_py/fast: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f rosaria_msgs/CMakeFiles/std_msgs_generate_messages_py.dir/build.make rosaria_msgs/CMakeFiles/std_msgs_generate_messages_py.dir/build +.PHONY : std_msgs_generate_messages_py/fast + +# Help Target +help: + @echo "The following are some of the valid targets for this Makefile:" + @echo "... all (the default if no target is provided)" + @echo "... clean" + @echo "... depend" + @echo "... edit_cache" + @echo "... geometry_msgs_generate_messages_cpp" + @echo "... geometry_msgs_generate_messages_lisp" + @echo "... geometry_msgs_generate_messages_py" + @echo "... install" + @echo "... install/local" + @echo "... install/strip" + @echo "... list_install_components" + @echo "... rebuild_cache" + @echo "... rosaria_msgs_gencpp" + @echo "... rosaria_msgs_generate_messages" + @echo "... rosaria_msgs_generate_messages_cpp" + @echo "... rosaria_msgs_generate_messages_lisp" + @echo "... rosaria_msgs_generate_messages_py" + @echo "... rosaria_msgs_genlisp" + @echo "... rosaria_msgs_genpy" + @echo "... std_msgs_generate_messages_cpp" + @echo "... std_msgs_generate_messages_lisp" + @echo "... std_msgs_generate_messages_py" + @echo "... test" +.PHONY : help + + + +#============================================================================= +# Special targets to cleanup operation of make. + +# Special rule to run CMake to check the build system integrity. +# No rule that depends on this can have commands that come from listfiles +# because they might be regenerated. +cmake_check_build_system: + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 0 +.PHONY : cmake_check_build_system + diff --git a/Legacy/ws_linux/build/rosaria_msgs/catkin_generated/installspace/rosaria_msgs-msg-extras.cmake b/Legacy/ws_linux/build/rosaria_msgs/catkin_generated/installspace/rosaria_msgs-msg-extras.cmake new file mode 100644 index 0000000..7b087f9 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/catkin_generated/installspace/rosaria_msgs-msg-extras.cmake @@ -0,0 +1,2 @@ +set(rosaria_msgs_MESSAGE_FILES "msg/RestrictionsMsg.msg;msg/RobotInfoMsg.msg") +set(rosaria_msgs_SERVICE_FILES "") diff --git a/Legacy/ws_linux/build/rosaria_msgs/catkin_generated/installspace/rosaria_msgs-msg-paths-context.py b/Legacy/ws_linux/build/rosaria_msgs/catkin_generated/installspace/rosaria_msgs-msg-paths-context.py new file mode 100644 index 0000000..46fb66e --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/catkin_generated/installspace/rosaria_msgs-msg-paths-context.py @@ -0,0 +1,8 @@ +# generated from genmsg/cmake/pkg-msg-paths.context.in + +DEVELSPACE = 'FALSE' == 'TRUE' +INSTALLSPACE = 'TRUE' == 'TRUE' + +PROJECT_NAME = 'rosaria_msgs' +PKG_MSG_INCLUDE_DIRS = 'msg' +ARG_DEPENDENCIES = 'std_msgs;geometry_msgs' diff --git a/Legacy/ws_linux/build/rosaria_msgs/catkin_generated/installspace/rosaria_msgs-msg-paths.cmake b/Legacy/ws_linux/build/rosaria_msgs/catkin_generated/installspace/rosaria_msgs-msg-paths.cmake new file mode 100644 index 0000000..36ecc85 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/catkin_generated/installspace/rosaria_msgs-msg-paths.cmake @@ -0,0 +1,5 @@ +# generated from genmsg/cmake/pkg-msg-paths.cmake.em + +# message include dirs in installspace +_prepend_path("${rosaria_msgs_DIR}/.." "msg" rosaria_msgs_MSG_INCLUDE_DIRS UNIQUE) +set(rosaria_msgs_MSG_DEPENDENCIES std_msgs;geometry_msgs) diff --git a/Legacy/ws_linux/build/rosaria_msgs/catkin_generated/installspace/rosaria_msgs.pc b/Legacy/ws_linux/build/rosaria_msgs/catkin_generated/installspace/rosaria_msgs.pc new file mode 100644 index 0000000..a13e505 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/catkin_generated/installspace/rosaria_msgs.pc @@ -0,0 +1,8 @@ +prefix=/home/lab1_5/ws/ws_linux/install + +Name: rosaria_msgs +Description: Description of rosaria_msgs +Version: 0.0.0 +Cflags: -I/home/lab1_5/ws/ws_linux/install/include +Libs: -L/home/lab1_5/ws/ws_linux/install/lib +Requires: message_runtime diff --git a/Legacy/ws_linux/build/rosaria_msgs/catkin_generated/installspace/rosaria_msgsConfig-version.cmake b/Legacy/ws_linux/build/rosaria_msgs/catkin_generated/installspace/rosaria_msgsConfig-version.cmake new file mode 100644 index 0000000..7fd9f99 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/catkin_generated/installspace/rosaria_msgsConfig-version.cmake @@ -0,0 +1,14 @@ +# generated from catkin/cmake/template/pkgConfig-version.cmake.in +set(PACKAGE_VERSION "0.0.0") + +set(PACKAGE_VERSION_EXACT False) +set(PACKAGE_VERSION_COMPATIBLE False) + +if("${PACKAGE_FIND_VERSION}" VERSION_EQUAL "${PACKAGE_VERSION}") + set(PACKAGE_VERSION_EXACT True) + set(PACKAGE_VERSION_COMPATIBLE True) +endif() + +if("${PACKAGE_FIND_VERSION}" VERSION_LESS "${PACKAGE_VERSION}") + set(PACKAGE_VERSION_COMPATIBLE True) +endif() diff --git a/Legacy/ws_linux/build/rosaria_msgs/catkin_generated/installspace/rosaria_msgsConfig.cmake b/Legacy/ws_linux/build/rosaria_msgs/catkin_generated/installspace/rosaria_msgsConfig.cmake new file mode 100644 index 0000000..39010a8 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/catkin_generated/installspace/rosaria_msgsConfig.cmake @@ -0,0 +1,191 @@ +# generated from catkin/cmake/template/pkgConfig.cmake.in + +# append elements to a list and remove existing duplicates from the list +# copied from catkin/cmake/list_append_deduplicate.cmake to keep pkgConfig +# self contained +macro(_list_append_deduplicate listname) + if(NOT "${ARGN}" STREQUAL "") + if(${listname}) + list(REMOVE_ITEM ${listname} ${ARGN}) + endif() + list(APPEND ${listname} ${ARGN}) + endif() +endmacro() + +# append elements to a list if they are not already in the list +# copied from catkin/cmake/list_append_unique.cmake to keep pkgConfig +# self contained +macro(_list_append_unique listname) + foreach(_item ${ARGN}) + list(FIND ${listname} ${_item} _index) + if(_index EQUAL -1) + list(APPEND ${listname} ${_item}) + endif() + endforeach() +endmacro() + +# pack a list of libraries with optional build configuration keywords +# copied from catkin/cmake/catkin_libraries.cmake to keep pkgConfig +# self contained +macro(_pack_libraries_with_build_configuration VAR) + set(${VAR} "") + set(_argn ${ARGN}) + list(LENGTH _argn _count) + set(_index 0) + while(${_index} LESS ${_count}) + list(GET _argn ${_index} lib) + if("${lib}" MATCHES "^debug|optimized|general$") + math(EXPR _index "${_index} + 1") + if(${_index} EQUAL ${_count}) + message(FATAL_ERROR "_pack_libraries_with_build_configuration() the list of libraries '${ARGN}' ends with '${lib}' which is a build configuration keyword and must be followed by a library") + endif() + list(GET _argn ${_index} library) + list(APPEND ${VAR} "${lib}${CATKIN_BUILD_CONFIGURATION_KEYWORD_SEPARATOR}${library}") + else() + list(APPEND ${VAR} "${lib}") + endif() + math(EXPR _index "${_index} + 1") + endwhile() +endmacro() + +# unpack a list of libraries with optional build configuration keyword prefixes +# copied from catkin/cmake/catkin_libraries.cmake to keep pkgConfig +# self contained +macro(_unpack_libraries_with_build_configuration VAR) + set(${VAR} "") + foreach(lib ${ARGN}) + string(REGEX REPLACE "^(debug|optimized|general)${CATKIN_BUILD_CONFIGURATION_KEYWORD_SEPARATOR}(.+)$" "\\1;\\2" lib "${lib}") + list(APPEND ${VAR} "${lib}") + endforeach() +endmacro() + + +if(rosaria_msgs_CONFIG_INCLUDED) + return() +endif() +set(rosaria_msgs_CONFIG_INCLUDED TRUE) + +# set variables for source/devel/install prefixes +if("FALSE" STREQUAL "TRUE") + set(rosaria_msgs_SOURCE_PREFIX /home/lab1_5/ws/ws_linux/src/rosaria_msgs) + set(rosaria_msgs_DEVEL_PREFIX /home/lab1_5/ws/ws_linux/devel) + set(rosaria_msgs_INSTALL_PREFIX "") + set(rosaria_msgs_PREFIX ${rosaria_msgs_DEVEL_PREFIX}) +else() + set(rosaria_msgs_SOURCE_PREFIX "") + set(rosaria_msgs_DEVEL_PREFIX "") + set(rosaria_msgs_INSTALL_PREFIX /home/lab1_5/ws/ws_linux/install) + set(rosaria_msgs_PREFIX ${rosaria_msgs_INSTALL_PREFIX}) +endif() + +# warn when using a deprecated package +if(NOT "" STREQUAL "") + set(_msg "WARNING: package 'rosaria_msgs' is deprecated") + # append custom deprecation text if available + if(NOT "" STREQUAL "TRUE") + set(_msg "${_msg} ()") + endif() + message("${_msg}") +endif() + +# flag project as catkin-based to distinguish if a find_package()-ed project is a catkin project +set(rosaria_msgs_FOUND_CATKIN_PROJECT TRUE) + +if(NOT "include" STREQUAL "") + set(rosaria_msgs_INCLUDE_DIRS "") + set(_include_dirs "include") + foreach(idir ${_include_dirs}) + if(IS_ABSOLUTE ${idir} AND IS_DIRECTORY ${idir}) + set(include ${idir}) + elseif("${idir}" STREQUAL "include") + get_filename_component(include "${rosaria_msgs_DIR}/../../../include" ABSOLUTE) + if(NOT IS_DIRECTORY ${include}) + message(FATAL_ERROR "Project 'rosaria_msgs' specifies '${idir}' as an include dir, which is not found. It does not exist in '${include}'. Ask the maintainer 'Aleksander Bojda ' to fix it.") + endif() + else() + message(FATAL_ERROR "Project 'rosaria_msgs' specifies '${idir}' as an include dir, which is not found. It does neither exist as an absolute directory nor in '/home/lab1_5/ws/ws_linux/install/${idir}'. Ask the maintainer 'Aleksander Bojda ' to fix it.") + endif() + _list_append_unique(rosaria_msgs_INCLUDE_DIRS ${include}) + endforeach() +endif() + +set(libraries "") +foreach(library ${libraries}) + # keep build configuration keywords, target names and absolute libraries as-is + if("${library}" MATCHES "^debug|optimized|general$") + list(APPEND rosaria_msgs_LIBRARIES ${library}) + elseif(TARGET ${library}) + list(APPEND rosaria_msgs_LIBRARIES ${library}) + elseif(IS_ABSOLUTE ${library}) + list(APPEND rosaria_msgs_LIBRARIES ${library}) + else() + set(lib_path "") + set(lib "${library}-NOTFOUND") + # since the path where the library is found is returned we have to iterate over the paths manually + foreach(path /home/lab1_5/ws/ws_linux/install/lib;/home/lab1_5/ws/ws_linux/devel/lib;/home/lab1_5/ws/ws_xeno/devel/lib;/home/lab1_5/ws/ws_isolated/install_isolated/lib;/opt/ros/hydro/lib) + find_library(lib ${library} + PATHS ${path} + NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH) + if(lib) + set(lib_path ${path}) + break() + endif() + endforeach() + if(lib) + _list_append_unique(rosaria_msgs_LIBRARY_DIRS ${lib_path}) + list(APPEND rosaria_msgs_LIBRARIES ${lib}) + else() + # as a fall back for non-catkin libraries try to search globally + find_library(lib ${library}) + if(NOT lib) + message(FATAL_ERROR "Project '${PROJECT_NAME}' tried to find library '${library}'. The library is neither a target nor built/installed properly. Did you compile project 'rosaria_msgs'? Did you find_package() it before the subdirectory containing its code is included?") + endif() + list(APPEND rosaria_msgs_LIBRARIES ${lib}) + endif() + endif() +endforeach() + +set(rosaria_msgs_EXPORTED_TARGETS "rosaria_msgs_generate_messages_cpp;rosaria_msgs_generate_messages_lisp;rosaria_msgs_generate_messages_py") +# create dummy targets for exported code generation targets to make life of users easier +foreach(t ${rosaria_msgs_EXPORTED_TARGETS}) + if(NOT TARGET ${t}) + add_custom_target(${t}) + endif() +endforeach() + +set(depends "message_runtime") +foreach(depend ${depends}) + string(REPLACE " " ";" depend_list ${depend}) + # the package name of the dependency must be kept in a unique variable so that it is not overwritten in recursive calls + list(GET depend_list 0 rosaria_msgs_dep) + list(LENGTH depend_list count) + if(${count} EQUAL 1) + # simple dependencies must only be find_package()-ed once + if(NOT ${rosaria_msgs_dep}_FOUND) + find_package(${rosaria_msgs_dep} REQUIRED) + endif() + else() + # dependencies with components must be find_package()-ed again + list(REMOVE_AT depend_list 0) + find_package(${rosaria_msgs_dep} REQUIRED ${depend_list}) + endif() + _list_append_unique(rosaria_msgs_INCLUDE_DIRS ${${rosaria_msgs_dep}_INCLUDE_DIRS}) + + # merge build configuration keywords with library names to correctly deduplicate + _pack_libraries_with_build_configuration(rosaria_msgs_LIBRARIES ${rosaria_msgs_LIBRARIES}) + _pack_libraries_with_build_configuration(_libraries ${${rosaria_msgs_dep}_LIBRARIES}) + _list_append_deduplicate(rosaria_msgs_LIBRARIES ${_libraries}) + # undo build configuration keyword merging after deduplication + _unpack_libraries_with_build_configuration(rosaria_msgs_LIBRARIES ${rosaria_msgs_LIBRARIES}) + + _list_append_unique(rosaria_msgs_LIBRARY_DIRS ${${rosaria_msgs_dep}_LIBRARY_DIRS}) + list(APPEND rosaria_msgs_EXPORTED_TARGETS ${${rosaria_msgs_dep}_EXPORTED_TARGETS}) +endforeach() + +set(pkg_cfg_extras "rosaria_msgs-msg-extras.cmake") +foreach(extra ${pkg_cfg_extras}) + if(NOT IS_ABSOLUTE ${extra}) + set(extra ${rosaria_msgs_DIR}/${extra}) + endif() + include(${extra}) +endforeach() diff --git a/Legacy/ws_linux/build/rosaria_msgs/catkin_generated/ordered_paths.cmake b/Legacy/ws_linux/build/rosaria_msgs/catkin_generated/ordered_paths.cmake new file mode 100644 index 0000000..3b5d318 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/catkin_generated/ordered_paths.cmake @@ -0,0 +1 @@ +set(ORDERED_PATHS "/opt/ros/hydro/lib") \ No newline at end of file diff --git a/Legacy/ws_linux/build/rosaria_msgs/catkin_generated/package.cmake b/Legacy/ws_linux/build/rosaria_msgs/catkin_generated/package.cmake new file mode 100644 index 0000000..8239483 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/catkin_generated/package.cmake @@ -0,0 +1,7 @@ +set(_CATKIN_CURRENT_PACKAGE "rosaria_msgs") +set(rosaria_msgs_MAINTAINER "Aleksander Bojda ") +set(rosaria_msgs_DEPRECATED "") +set(rosaria_msgs_VERSION "0.0.0") +set(rosaria_msgs_BUILD_DEPENDS "std_msgs" "message_generation") +set(rosaria_msgs_RUN_DEPENDS "std_msgs" "message_runtime" "message_generation") +set(rosaria_msgs_BUILDTOOL_DEPENDS "catkin") \ No newline at end of file diff --git a/Legacy/ws_linux/build/rosaria_msgs/catkin_generated/pkg.develspace.context.pc.py b/Legacy/ws_linux/build/rosaria_msgs/catkin_generated/pkg.develspace.context.pc.py new file mode 100644 index 0000000..714539d --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/catkin_generated/pkg.develspace.context.pc.py @@ -0,0 +1,8 @@ +# generated from catkin/cmake/template/pkg.context.pc.in +CATKIN_PACKAGE_PREFIX = "" +PROJECT_PKG_CONFIG_INCLUDE_DIRS = "/home/lab1_5/ws/ws_linux/devel/include".split(';') if "/home/lab1_5/ws/ws_linux/devel/include" != "" else [] +PROJECT_CATKIN_DEPENDS = "message_runtime".replace(';', ' ') +PKG_CONFIG_LIBRARIES_WITH_PREFIX = "".split(';') if "" != "" else [] +PROJECT_NAME = "rosaria_msgs" +PROJECT_SPACE_DIR = "/home/lab1_5/ws/ws_linux/devel" +PROJECT_VERSION = "0.0.0" diff --git a/Legacy/ws_linux/build/rosaria_msgs/catkin_generated/pkg.installspace.context.pc.py b/Legacy/ws_linux/build/rosaria_msgs/catkin_generated/pkg.installspace.context.pc.py new file mode 100644 index 0000000..3fb7ef6 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/catkin_generated/pkg.installspace.context.pc.py @@ -0,0 +1,8 @@ +# generated from catkin/cmake/template/pkg.context.pc.in +CATKIN_PACKAGE_PREFIX = "" +PROJECT_PKG_CONFIG_INCLUDE_DIRS = "/home/lab1_5/ws/ws_linux/install/include".split(';') if "/home/lab1_5/ws/ws_linux/install/include" != "" else [] +PROJECT_CATKIN_DEPENDS = "message_runtime".replace(';', ' ') +PKG_CONFIG_LIBRARIES_WITH_PREFIX = "".split(';') if "" != "" else [] +PROJECT_NAME = "rosaria_msgs" +PROJECT_SPACE_DIR = "/home/lab1_5/ws/ws_linux/install" +PROJECT_VERSION = "0.0.0" diff --git a/Legacy/ws_linux/build/rosaria_msgs/catkin_generated/rosaria_msgs-msg-extras.cmake.develspace.in b/Legacy/ws_linux/build/rosaria_msgs/catkin_generated/rosaria_msgs-msg-extras.cmake.develspace.in new file mode 100644 index 0000000..e01c757 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/catkin_generated/rosaria_msgs-msg-extras.cmake.develspace.in @@ -0,0 +1,2 @@ +set(rosaria_msgs_MESSAGE_FILES "/home/lab1_5/ws/ws_linux/src/rosaria_msgs/msg/RestrictionsMsg.msg;/home/lab1_5/ws/ws_linux/src/rosaria_msgs/msg/RobotInfoMsg.msg") +set(rosaria_msgs_SERVICE_FILES "") diff --git a/Legacy/ws_linux/build/rosaria_msgs/catkin_generated/rosaria_msgs-msg-extras.cmake.installspace.in b/Legacy/ws_linux/build/rosaria_msgs/catkin_generated/rosaria_msgs-msg-extras.cmake.installspace.in new file mode 100644 index 0000000..7b087f9 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/catkin_generated/rosaria_msgs-msg-extras.cmake.installspace.in @@ -0,0 +1,2 @@ +set(rosaria_msgs_MESSAGE_FILES "msg/RestrictionsMsg.msg;msg/RobotInfoMsg.msg") +set(rosaria_msgs_SERVICE_FILES "") diff --git a/Legacy/ws_linux/build/rosaria_msgs/catkin_generated/rosaria_msgs-msg-paths-context.py b/Legacy/ws_linux/build/rosaria_msgs/catkin_generated/rosaria_msgs-msg-paths-context.py new file mode 100644 index 0000000..1678578 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/catkin_generated/rosaria_msgs-msg-paths-context.py @@ -0,0 +1,8 @@ +# generated from genmsg/cmake/pkg-msg-paths.context.in + +DEVELSPACE = 'TRUE' == 'TRUE' +INSTALLSPACE = 'FALSE' == 'TRUE' + +PROJECT_NAME = 'rosaria_msgs' +PKG_MSG_INCLUDE_DIRS = '/home/lab1_5/ws/ws_linux/src/rosaria_msgs/msg' +ARG_DEPENDENCIES = 'std_msgs;geometry_msgs' diff --git a/Legacy/ws_linux/build/rosaria_msgs/catkin_generated/stamps/rosaria_msgs/package.xml.stamp b/Legacy/ws_linux/build/rosaria_msgs/catkin_generated/stamps/rosaria_msgs/package.xml.stamp new file mode 100644 index 0000000..81a1a54 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/catkin_generated/stamps/rosaria_msgs/package.xml.stamp @@ -0,0 +1,21 @@ + + + rosaria_msgs + 0.0.0 + The rosaria_msgs package + + Aleksander Bojda + + MIT + + catkin + std_msgs + message_generation + + std_msgs + message_generation + + std_msgs + message_runtime + + diff --git a/Legacy/ws_linux/build/rosaria_msgs/catkin_generated/stamps/rosaria_msgs/pkg-genmsg.cmake.em.stamp b/Legacy/ws_linux/build/rosaria_msgs/catkin_generated/stamps/rosaria_msgs/pkg-genmsg.cmake.em.stamp new file mode 100644 index 0000000..5182859 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/catkin_generated/stamps/rosaria_msgs/pkg-genmsg.cmake.em.stamp @@ -0,0 +1,141 @@ +# generated from genmsg/cmake/pkg-genmsg.cmake.em + +@{ +import os +import sys + +import genmsg +import genmsg.base +genmsg.base.log_verbose('GENMSG_VERBOSE' in os.environ) +import genmsg.deps +import genmsg.gentools + +# split incoming variables +messages = messages_str.split(';') if messages_str != '' else [] +services = services_str.split(';') if services_str != '' else [] +dependencies = dependencies_str.split(';') if dependencies_str != '' else [] +dep_search_paths = dep_include_paths_str.split(';') if dep_include_paths_str != '' else [] + +dep_search_paths_dict = {} +dep_search_paths_tuple_list = [] +is_even = True +for val in dep_search_paths: + if is_even: + dep_search_paths_dict.setdefault(val, []) + val_prev = val + is_even = False + else: + dep_search_paths_dict[val_prev].append(val) + dep_search_paths_tuple_list.append((val_prev, val)) + is_even = True +dep_search_paths = dep_search_paths_dict + +if not messages and not services: + print('message(WARNING "Invoking generate_messages() without having added any message or service file before.\nYou should either add add_message_files() and/or add_service_files() calls or remove the invocation of generate_messages().")') + +msg_deps = {} +for m in messages: + try: + msg_deps[m] = genmsg.deps.find_msg_dependencies(pkg_name, m, dep_search_paths) + except genmsg.MsgNotFound as e: + print('message(FATAL_ERROR "Could not find messages which \'%s\' depends on. Did you forget to specify generate_messages(DEPENDENCIES ...)?\n%s")' % (m, str(e))) + +srv_deps = {} +for s in services: + try: + srv_deps[s] = genmsg.deps.find_srv_dependencies(pkg_name, s, dep_search_paths) + except genmsg.MsgNotFound as e: + print('message(FATAL_ERROR "Could not find messages which \'%s\' depends on. Did you forget to specify generate_messages(DEPENDENCIES ...)?\n%s")' % (s, str(e))) + +}@ +message(STATUS "@(pkg_name): @(len(messages)) messages, @(len(services)) services") + +set(MSG_I_FLAGS "@(';'.join(["-I%s:%s" % (dep, dir) for dep, dir in dep_search_paths_tuple_list]))") + +# Find all generators +@[if langs]@ +@[for l in langs.split(';')]@ +find_package(@l REQUIRED) +@[end for]@ +@[end if]@ + +add_custom_target(@(pkg_name)_generate_messages ALL) + +# +# langs = @langs +# + +@[if langs]@ +@[for l in langs.split(';')]@ +### Section generating for lang: @l +### Generating Messages +@[for m in msg_deps.keys()]@ +_generate_msg_@(l[3:])(@pkg_name + "@m" + "${MSG_I_FLAGS}" + "@(';'.join(msg_deps[m]).replace("\\","/"))" + ${CATKIN_DEVEL_PREFIX}/${@(l)_INSTALL_DIR}/@pkg_name +) +@[end for]@# messages + +### Generating Services +@[for s in srv_deps.keys()]@ +_generate_srv_@(l[3:])(@pkg_name + "@s" + "${MSG_I_FLAGS}" + "@(';'.join(srv_deps[s]).replace("\\","/"))" + ${CATKIN_DEVEL_PREFIX}/${@(l)_INSTALL_DIR}/@pkg_name +) +@[end for]@# services + +### Generating Module File +_generate_module_@(l[3:])(@pkg_name + ${CATKIN_DEVEL_PREFIX}/${@(l)_INSTALL_DIR}/@pkg_name + "${ALL_GEN_OUTPUT_FILES_@(l[3:])}" +) + +add_custom_target(@(pkg_name)_generate_messages_@(l[3:]) + DEPENDS ${ALL_GEN_OUTPUT_FILES_@(l[3:])} +) +add_dependencies(@(pkg_name)_generate_messages @(pkg_name)_generate_messages_@(l[3:])) + +# target for backward compatibility +add_custom_target(@(pkg_name)_@(l)) +add_dependencies(@(pkg_name)_@(l) @(pkg_name)_generate_messages_@(l[3:])) + +# register target for catkin_package(EXPORTED_TARGETS) +list(APPEND ${PROJECT_NAME}_EXPORTED_TARGETS @(pkg_name)_generate_messages_@(l[3:])) + +@[end for]@# langs +@[end if]@ + +@[if langs]@ +@[for l in langs.split(';')]@ + +if(@(l)_INSTALL_DIR AND EXISTS ${CATKIN_DEVEL_PREFIX}/${@(l)_INSTALL_DIR}/@pkg_name) +@[if l == 'genpy']@ + install(CODE "execute_process(COMMAND \"@(PYTHON_EXECUTABLE)\" -m compileall \"${CATKIN_DEVEL_PREFIX}/${@(l)_INSTALL_DIR}/@pkg_name\")") +@[end if]@ + # install generated code + install( + DIRECTORY ${CATKIN_DEVEL_PREFIX}/${@(l)_INSTALL_DIR}/@pkg_name + DESTINATION ${@(l)_INSTALL_DIR} +@[if l == 'genpy' and package_has_static_sources]@ + # skip all init files + PATTERN "__init__.py" EXCLUDE + PATTERN "__init__.pyc" EXCLUDE + ) + # install init files which are not in the root folder of the generated code + install( + DIRECTORY ${CATKIN_DEVEL_PREFIX}/${@(l)_INSTALL_DIR}/@pkg_name + DESTINATION ${@(l)_INSTALL_DIR} + FILES_MATCHING + REGEX "${CATKIN_DEVEL_PREFIX}/${@(l)_INSTALL_DIR}/@(pkg_name)/.+/__init__.pyc?$" +@[end if]@ + ) +endif() +@[for d in dependencies]@ +add_dependencies(@(pkg_name)_generate_messages_@(l[3:]) @(d)_generate_messages_@(l[3:])) +@[end for]@# dependencies +@[end for]@# langs +@[end if]@ diff --git a/Legacy/ws_linux/build/rosaria_msgs/catkin_generated/stamps/rosaria_msgs/pkg-msg-paths.cmake.em.stamp b/Legacy/ws_linux/build/rosaria_msgs/catkin_generated/stamps/rosaria_msgs/pkg-msg-paths.cmake.em.stamp new file mode 100644 index 0000000..eb6f88a --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/catkin_generated/stamps/rosaria_msgs/pkg-msg-paths.cmake.em.stamp @@ -0,0 +1,10 @@ +# generated from genmsg/cmake/pkg-msg-paths.cmake.em + +@[if DEVELSPACE]@ +# message include dirs in develspace +set(@(PROJECT_NAME)_MSG_INCLUDE_DIRS "@(PKG_MSG_INCLUDE_DIRS)") +@[else]@ +# message include dirs in installspace +_prepend_path("${@(PROJECT_NAME)_DIR}/.." "@(PKG_MSG_INCLUDE_DIRS)" @(PROJECT_NAME)_MSG_INCLUDE_DIRS UNIQUE) +@[end if]@ +set(@(PROJECT_NAME)_MSG_DEPENDENCIES @(ARG_DEPENDENCIES)) diff --git a/Legacy/ws_linux/build/rosaria_msgs/catkin_generated/stamps/rosaria_msgs/pkg.pc.em.stamp b/Legacy/ws_linux/build/rosaria_msgs/catkin_generated/stamps/rosaria_msgs/pkg.pc.em.stamp new file mode 100644 index 0000000..a4f7257 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/catkin_generated/stamps/rosaria_msgs/pkg.pc.em.stamp @@ -0,0 +1,8 @@ +prefix=@PROJECT_SPACE_DIR + +Name: @(CATKIN_PACKAGE_PREFIX + PROJECT_NAME) +Description: Description of @PROJECT_NAME +Version: @PROJECT_VERSION +Cflags: @(' '.join(['-I%s' % include for include in PROJECT_PKG_CONFIG_INCLUDE_DIRS])) +Libs: -L@PROJECT_SPACE_DIR/lib @(' '.join(PKG_CONFIG_LIBRARIES_WITH_PREFIX)) +Requires: @(PROJECT_CATKIN_DEPENDS) diff --git a/Legacy/ws_linux/build/rosaria_msgs/cmake/rosaria_msgs-genmsg-context.py b/Legacy/ws_linux/build/rosaria_msgs/cmake/rosaria_msgs-genmsg-context.py new file mode 100644 index 0000000..52a887b --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/cmake/rosaria_msgs-genmsg-context.py @@ -0,0 +1,10 @@ +# generated from genmsg/cmake/pkg-genmsg.context.in + +messages_str = "/home/lab1_5/ws/ws_linux/src/rosaria_msgs/msg/RestrictionsMsg.msg;/home/lab1_5/ws/ws_linux/src/rosaria_msgs/msg/RobotInfoMsg.msg" +services_str = "" +pkg_name = "rosaria_msgs" +dependencies_str = "std_msgs;geometry_msgs" +langs = "gencpp;genlisp;genpy" +dep_include_paths_str = "rosaria_msgs;/home/lab1_5/ws/ws_linux/src/rosaria_msgs/msg;std_msgs;/opt/ros/hydro/share/std_msgs/cmake/../msg;geometry_msgs;/opt/ros/hydro/share/geometry_msgs/cmake/../msg" +PYTHON_EXECUTABLE = "/usr/bin/python" +package_has_static_sources = '' == 'TRUE' diff --git a/Legacy/ws_linux/build/rosaria_msgs/cmake/rosaria_msgs-genmsg.cmake b/Legacy/ws_linux/build/rosaria_msgs/cmake/rosaria_msgs-genmsg.cmake new file mode 100644 index 0000000..3bb79d2 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/cmake/rosaria_msgs-genmsg.cmake @@ -0,0 +1,154 @@ +# generated from genmsg/cmake/pkg-genmsg.cmake.em + +message(STATUS "rosaria_msgs: 2 messages, 0 services") + +set(MSG_I_FLAGS "-Irosaria_msgs:/home/lab1_5/ws/ws_linux/src/rosaria_msgs/msg;-Istd_msgs:/opt/ros/hydro/share/std_msgs/cmake/../msg;-Igeometry_msgs:/opt/ros/hydro/share/geometry_msgs/cmake/../msg") + +# Find all generators +find_package(gencpp REQUIRED) +find_package(genlisp REQUIRED) +find_package(genpy REQUIRED) + +add_custom_target(rosaria_msgs_generate_messages ALL) + +# +# langs = gencpp;genlisp;genpy +# + +### Section generating for lang: gencpp +### Generating Messages +_generate_msg_cpp(rosaria_msgs + "/home/lab1_5/ws/ws_linux/src/rosaria_msgs/msg/RobotInfoMsg.msg" + "${MSG_I_FLAGS}" + "/opt/ros/hydro/share/geometry_msgs/cmake/../msg/Twist.msg;/opt/ros/hydro/share/std_msgs/cmake/../msg/Float64.msg;/opt/ros/hydro/share/std_msgs/cmake/../msg/UInt8.msg;/opt/ros/hydro/share/geometry_msgs/cmake/../msg/Vector3.msg;/opt/ros/hydro/share/std_msgs/cmake/../msg/Bool.msg" + ${CATKIN_DEVEL_PREFIX}/${gencpp_INSTALL_DIR}/rosaria_msgs +) +_generate_msg_cpp(rosaria_msgs + "/home/lab1_5/ws/ws_linux/src/rosaria_msgs/msg/RestrictionsMsg.msg" + "${MSG_I_FLAGS}" + "/opt/ros/hydro/share/std_msgs/cmake/../msg/Float64.msg" + ${CATKIN_DEVEL_PREFIX}/${gencpp_INSTALL_DIR}/rosaria_msgs +) + +### Generating Services + +### Generating Module File +_generate_module_cpp(rosaria_msgs + ${CATKIN_DEVEL_PREFIX}/${gencpp_INSTALL_DIR}/rosaria_msgs + "${ALL_GEN_OUTPUT_FILES_cpp}" +) + +add_custom_target(rosaria_msgs_generate_messages_cpp + DEPENDS ${ALL_GEN_OUTPUT_FILES_cpp} +) +add_dependencies(rosaria_msgs_generate_messages rosaria_msgs_generate_messages_cpp) + +# target for backward compatibility +add_custom_target(rosaria_msgs_gencpp) +add_dependencies(rosaria_msgs_gencpp rosaria_msgs_generate_messages_cpp) + +# register target for catkin_package(EXPORTED_TARGETS) +list(APPEND ${PROJECT_NAME}_EXPORTED_TARGETS rosaria_msgs_generate_messages_cpp) + +### Section generating for lang: genlisp +### Generating Messages +_generate_msg_lisp(rosaria_msgs + "/home/lab1_5/ws/ws_linux/src/rosaria_msgs/msg/RobotInfoMsg.msg" + "${MSG_I_FLAGS}" + "/opt/ros/hydro/share/geometry_msgs/cmake/../msg/Twist.msg;/opt/ros/hydro/share/std_msgs/cmake/../msg/Float64.msg;/opt/ros/hydro/share/std_msgs/cmake/../msg/UInt8.msg;/opt/ros/hydro/share/geometry_msgs/cmake/../msg/Vector3.msg;/opt/ros/hydro/share/std_msgs/cmake/../msg/Bool.msg" + ${CATKIN_DEVEL_PREFIX}/${genlisp_INSTALL_DIR}/rosaria_msgs +) +_generate_msg_lisp(rosaria_msgs + "/home/lab1_5/ws/ws_linux/src/rosaria_msgs/msg/RestrictionsMsg.msg" + "${MSG_I_FLAGS}" + "/opt/ros/hydro/share/std_msgs/cmake/../msg/Float64.msg" + ${CATKIN_DEVEL_PREFIX}/${genlisp_INSTALL_DIR}/rosaria_msgs +) + +### Generating Services + +### Generating Module File +_generate_module_lisp(rosaria_msgs + ${CATKIN_DEVEL_PREFIX}/${genlisp_INSTALL_DIR}/rosaria_msgs + "${ALL_GEN_OUTPUT_FILES_lisp}" +) + +add_custom_target(rosaria_msgs_generate_messages_lisp + DEPENDS ${ALL_GEN_OUTPUT_FILES_lisp} +) +add_dependencies(rosaria_msgs_generate_messages rosaria_msgs_generate_messages_lisp) + +# target for backward compatibility +add_custom_target(rosaria_msgs_genlisp) +add_dependencies(rosaria_msgs_genlisp rosaria_msgs_generate_messages_lisp) + +# register target for catkin_package(EXPORTED_TARGETS) +list(APPEND ${PROJECT_NAME}_EXPORTED_TARGETS rosaria_msgs_generate_messages_lisp) + +### Section generating for lang: genpy +### Generating Messages +_generate_msg_py(rosaria_msgs + "/home/lab1_5/ws/ws_linux/src/rosaria_msgs/msg/RobotInfoMsg.msg" + "${MSG_I_FLAGS}" + "/opt/ros/hydro/share/geometry_msgs/cmake/../msg/Twist.msg;/opt/ros/hydro/share/std_msgs/cmake/../msg/Float64.msg;/opt/ros/hydro/share/std_msgs/cmake/../msg/UInt8.msg;/opt/ros/hydro/share/geometry_msgs/cmake/../msg/Vector3.msg;/opt/ros/hydro/share/std_msgs/cmake/../msg/Bool.msg" + ${CATKIN_DEVEL_PREFIX}/${genpy_INSTALL_DIR}/rosaria_msgs +) +_generate_msg_py(rosaria_msgs + "/home/lab1_5/ws/ws_linux/src/rosaria_msgs/msg/RestrictionsMsg.msg" + "${MSG_I_FLAGS}" + "/opt/ros/hydro/share/std_msgs/cmake/../msg/Float64.msg" + ${CATKIN_DEVEL_PREFIX}/${genpy_INSTALL_DIR}/rosaria_msgs +) + +### Generating Services + +### Generating Module File +_generate_module_py(rosaria_msgs + ${CATKIN_DEVEL_PREFIX}/${genpy_INSTALL_DIR}/rosaria_msgs + "${ALL_GEN_OUTPUT_FILES_py}" +) + +add_custom_target(rosaria_msgs_generate_messages_py + DEPENDS ${ALL_GEN_OUTPUT_FILES_py} +) +add_dependencies(rosaria_msgs_generate_messages rosaria_msgs_generate_messages_py) + +# target for backward compatibility +add_custom_target(rosaria_msgs_genpy) +add_dependencies(rosaria_msgs_genpy rosaria_msgs_generate_messages_py) + +# register target for catkin_package(EXPORTED_TARGETS) +list(APPEND ${PROJECT_NAME}_EXPORTED_TARGETS rosaria_msgs_generate_messages_py) + + + +if(gencpp_INSTALL_DIR AND EXISTS ${CATKIN_DEVEL_PREFIX}/${gencpp_INSTALL_DIR}/rosaria_msgs) + # install generated code + install( + DIRECTORY ${CATKIN_DEVEL_PREFIX}/${gencpp_INSTALL_DIR}/rosaria_msgs + DESTINATION ${gencpp_INSTALL_DIR} + ) +endif() +add_dependencies(rosaria_msgs_generate_messages_cpp std_msgs_generate_messages_cpp) +add_dependencies(rosaria_msgs_generate_messages_cpp geometry_msgs_generate_messages_cpp) + +if(genlisp_INSTALL_DIR AND EXISTS ${CATKIN_DEVEL_PREFIX}/${genlisp_INSTALL_DIR}/rosaria_msgs) + # install generated code + install( + DIRECTORY ${CATKIN_DEVEL_PREFIX}/${genlisp_INSTALL_DIR}/rosaria_msgs + DESTINATION ${genlisp_INSTALL_DIR} + ) +endif() +add_dependencies(rosaria_msgs_generate_messages_lisp std_msgs_generate_messages_lisp) +add_dependencies(rosaria_msgs_generate_messages_lisp geometry_msgs_generate_messages_lisp) + +if(genpy_INSTALL_DIR AND EXISTS ${CATKIN_DEVEL_PREFIX}/${genpy_INSTALL_DIR}/rosaria_msgs) + install(CODE "execute_process(COMMAND \"/usr/bin/python\" -m compileall \"${CATKIN_DEVEL_PREFIX}/${genpy_INSTALL_DIR}/rosaria_msgs\")") + # install generated code + install( + DIRECTORY ${CATKIN_DEVEL_PREFIX}/${genpy_INSTALL_DIR}/rosaria_msgs + DESTINATION ${genpy_INSTALL_DIR} + ) +endif() +add_dependencies(rosaria_msgs_generate_messages_py std_msgs_generate_messages_py) +add_dependencies(rosaria_msgs_generate_messages_py geometry_msgs_generate_messages_py) diff --git a/Legacy/ws_linux/build/rosaria_msgs/cmake_install.cmake b/Legacy/ws_linux/build/rosaria_msgs/cmake_install.cmake new file mode 100644 index 0000000..7025c47 --- /dev/null +++ b/Legacy/ws_linux/build/rosaria_msgs/cmake_install.cmake @@ -0,0 +1,80 @@ +# Install script for directory: /home/lab1_5/ws/ws_linux/src/rosaria_msgs + +# Set the install prefix +IF(NOT DEFINED CMAKE_INSTALL_PREFIX) + SET(CMAKE_INSTALL_PREFIX "/home/lab1_5/ws/ws_linux/install") +ENDIF(NOT DEFINED CMAKE_INSTALL_PREFIX) +STRING(REGEX REPLACE "/$" "" CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}") + +# Set the install configuration name. +IF(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME) + IF(BUILD_TYPE) + STRING(REGEX REPLACE "^[^A-Za-z0-9_]+" "" + CMAKE_INSTALL_CONFIG_NAME "${BUILD_TYPE}") + ELSE(BUILD_TYPE) + SET(CMAKE_INSTALL_CONFIG_NAME "") + ENDIF(BUILD_TYPE) + MESSAGE(STATUS "Install configuration: \"${CMAKE_INSTALL_CONFIG_NAME}\"") +ENDIF(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME) + +# Set the component getting installed. +IF(NOT CMAKE_INSTALL_COMPONENT) + IF(COMPONENT) + MESSAGE(STATUS "Install component: \"${COMPONENT}\"") + SET(CMAKE_INSTALL_COMPONENT "${COMPONENT}") + ELSE(COMPONENT) + SET(CMAKE_INSTALL_COMPONENT) + ENDIF(COMPONENT) +ENDIF(NOT CMAKE_INSTALL_COMPONENT) + +# Install shared libraries without execute permission? +IF(NOT DEFINED CMAKE_INSTALL_SO_NO_EXE) + SET(CMAKE_INSTALL_SO_NO_EXE "1") +ENDIF(NOT DEFINED CMAKE_INSTALL_SO_NO_EXE) + +IF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + FILE(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/share/rosaria_msgs/msg" TYPE FILE FILES + "/home/lab1_5/ws/ws_linux/src/rosaria_msgs/msg/RestrictionsMsg.msg" + "/home/lab1_5/ws/ws_linux/src/rosaria_msgs/msg/RobotInfoMsg.msg" + ) +ENDIF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + +IF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + FILE(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/share/rosaria_msgs/cmake" TYPE FILE FILES "/home/lab1_5/ws/ws_linux/build/rosaria_msgs/catkin_generated/installspace/rosaria_msgs-msg-paths.cmake") +ENDIF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + +IF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + FILE(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/include" TYPE DIRECTORY FILES "/home/lab1_5/ws/ws_linux/devel/include/rosaria_msgs") +ENDIF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + +IF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + FILE(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/share/common-lisp/ros" TYPE DIRECTORY FILES "/home/lab1_5/ws/ws_linux/devel/share/common-lisp/ros/rosaria_msgs") +ENDIF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + +IF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + execute_process(COMMAND "/usr/bin/python" -m compileall "/home/lab1_5/ws/ws_linux/devel/lib/python2.7/dist-packages/rosaria_msgs") +ENDIF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + +IF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + FILE(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/lib/python2.7/dist-packages" TYPE DIRECTORY FILES "/home/lab1_5/ws/ws_linux/devel/lib/python2.7/dist-packages/rosaria_msgs") +ENDIF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + +IF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + FILE(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/lib/pkgconfig" TYPE FILE FILES "/home/lab1_5/ws/ws_linux/build/rosaria_msgs/catkin_generated/installspace/rosaria_msgs.pc") +ENDIF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + +IF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + FILE(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/share/rosaria_msgs/cmake" TYPE FILE FILES "/home/lab1_5/ws/ws_linux/build/rosaria_msgs/catkin_generated/installspace/rosaria_msgs-msg-extras.cmake") +ENDIF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + +IF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + FILE(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/share/rosaria_msgs/cmake" TYPE FILE FILES + "/home/lab1_5/ws/ws_linux/build/rosaria_msgs/catkin_generated/installspace/rosaria_msgsConfig.cmake" + "/home/lab1_5/ws/ws_linux/build/rosaria_msgs/catkin_generated/installspace/rosaria_msgsConfig-version.cmake" + ) +ENDIF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + +IF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + FILE(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/share/rosaria_msgs" TYPE FILE FILES "/home/lab1_5/ws/ws_linux/src/rosaria_msgs/package.xml") +ENDIF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + diff --git a/Legacy/ws_linux/build/safety/CMakeFiles/CMakeDirectoryInformation.cmake b/Legacy/ws_linux/build/safety/CMakeFiles/CMakeDirectoryInformation.cmake new file mode 100644 index 0000000..b89c852 --- /dev/null +++ b/Legacy/ws_linux/build/safety/CMakeFiles/CMakeDirectoryInformation.cmake @@ -0,0 +1,25 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +# Relative path conversion top directories. +SET(CMAKE_RELATIVE_PATH_TOP_SOURCE "/home/lab1_5/ws/ws_linux/src") +SET(CMAKE_RELATIVE_PATH_TOP_BINARY "/home/lab1_5/ws/ws_linux/build") + +# Force unix paths in dependencies. +SET(CMAKE_FORCE_UNIX_PATHS 1) + +# The C and CXX include file search paths: +SET(CMAKE_C_INCLUDE_PATH + "/home/lab1_5/ws/ws_linux/src/safety/include" + "/home/lab1_5/ws/ws_linux/devel/include" + "/opt/ros/hydro/include" + ) +SET(CMAKE_CXX_INCLUDE_PATH ${CMAKE_C_INCLUDE_PATH}) +SET(CMAKE_Fortran_INCLUDE_PATH ${CMAKE_C_INCLUDE_PATH}) +SET(CMAKE_ASM_INCLUDE_PATH ${CMAKE_C_INCLUDE_PATH}) + +# The C and CXX include file regular expressions for this directory. +SET(CMAKE_C_INCLUDE_REGEX_SCAN "^.*$") +SET(CMAKE_C_INCLUDE_REGEX_COMPLAIN "^$") +SET(CMAKE_CXX_INCLUDE_REGEX_SCAN ${CMAKE_C_INCLUDE_REGEX_SCAN}) +SET(CMAKE_CXX_INCLUDE_REGEX_COMPLAIN ${CMAKE_C_INCLUDE_REGEX_COMPLAIN}) diff --git a/Legacy/ws_linux/build/safety/CMakeFiles/cloud_reader.dir/CXX.includecache b/Legacy/ws_linux/build/safety/CMakeFiles/cloud_reader.dir/CXX.includecache new file mode 100644 index 0000000..a44274e --- /dev/null +++ b/Legacy/ws_linux/build/safety/CMakeFiles/cloud_reader.dir/CXX.includecache @@ -0,0 +1,1026 @@ +#IncludeRegexLine: ^[ ]*#[ ]*(include|import)[ ]*[<"]([^">]+)([">]) + +#IncludeRegexScan: ^.*$ + +#IncludeRegexComplain: ^$ + +#IncludeRegexTransform: + +/home/lab1_5/ws/ws_linux/devel/include/rosaria/RosAriaConfig.h +dynamic_reconfigure/config_tools.h +- +limits +- +ros/node_handle.h +- +dynamic_reconfigure/ConfigDescription.h +- +dynamic_reconfigure/ParamDescription.h +- +dynamic_reconfigure/Group.h +- +dynamic_reconfigure/config_init_mutex.h +- +boost/any.hpp +- + +/home/lab1_5/ws/ws_linux/src/safety/src/cloud_reader.cpp +ros/ros.h +/home/lab1_5/ws/ws_linux/src/safety/src/ros/ros.h +sensor_msgs/PointCloud.h +/home/lab1_5/ws/ws_linux/src/safety/src/sensor_msgs/PointCloud.h +rosaria/RosAriaConfig.h +- +std_srvs/Empty.h +- +std_msgs/Float32.h +- +geometry_msgs/Twist.h +- +geometry_msgs/Vector3.h +- +cmath +- +sstream +- + +/opt/ros/hydro/include/XmlRpcDecl.h +ros/macros.h +- + +/opt/ros/hydro/include/XmlRpcValue.h +XmlRpcDecl.h +/opt/ros/hydro/include/XmlRpcDecl.h +map +- +string +- +vector +- +time.h +- + +/opt/ros/hydro/include/dynamic_reconfigure/BoolParameter.h +string +- +vector +- +map +- +ros/types.h +- +ros/serialization.h +- +ros/builtin_message_traits.h +- +ros/message_operations.h +- + +/opt/ros/hydro/include/dynamic_reconfigure/Config.h +string +- +vector +- +map +- +ros/types.h +- +ros/serialization.h +- +ros/builtin_message_traits.h +- +ros/message_operations.h +- +dynamic_reconfigure/BoolParameter.h +- +dynamic_reconfigure/IntParameter.h +- +dynamic_reconfigure/StrParameter.h +- +dynamic_reconfigure/DoubleParameter.h +- +dynamic_reconfigure/GroupState.h +- + +/opt/ros/hydro/include/dynamic_reconfigure/ConfigDescription.h +string +- +vector +- +map +- +ros/types.h +- +ros/serialization.h +- +ros/builtin_message_traits.h +- +ros/message_operations.h +- +dynamic_reconfigure/Group.h +- +dynamic_reconfigure/Config.h +- +dynamic_reconfigure/Config.h +- +dynamic_reconfigure/Config.h +- + +/opt/ros/hydro/include/dynamic_reconfigure/DoubleParameter.h +string +- +vector +- +map +- +ros/types.h +- +ros/serialization.h +- +ros/builtin_message_traits.h +- +ros/message_operations.h +- + +/opt/ros/hydro/include/dynamic_reconfigure/Group.h +string +- +vector +- +map +- +ros/types.h +- +ros/serialization.h +- +ros/builtin_message_traits.h +- +ros/message_operations.h +- +dynamic_reconfigure/ParamDescription.h +- + +/opt/ros/hydro/include/dynamic_reconfigure/GroupState.h +string +- +vector +- +map +- +ros/types.h +- +ros/serialization.h +- +ros/builtin_message_traits.h +- +ros/message_operations.h +- + +/opt/ros/hydro/include/dynamic_reconfigure/IntParameter.h +string +- +vector +- +map +- +ros/types.h +- +ros/serialization.h +- +ros/builtin_message_traits.h +- +ros/message_operations.h +- + +/opt/ros/hydro/include/dynamic_reconfigure/ParamDescription.h +string +- +vector +- +map +- +ros/types.h +- +ros/serialization.h +- +ros/builtin_message_traits.h +- +ros/message_operations.h +- + +/opt/ros/hydro/include/dynamic_reconfigure/StrParameter.h +string +- +vector +- +map +- +ros/types.h +- +ros/serialization.h +- +ros/builtin_message_traits.h +- +ros/message_operations.h +- + +/opt/ros/hydro/include/dynamic_reconfigure/config_init_mutex.h +boost/thread/mutex.hpp +- + +/opt/ros/hydro/include/dynamic_reconfigure/config_tools.h +string +- +vector +- +dynamic_reconfigure/Config.h +- +dynamic_reconfigure/Group.h +- + +/opt/ros/hydro/include/geometry_msgs/Point32.h +string +- +vector +- +map +- +ros/types.h +- +ros/serialization.h +- +ros/builtin_message_traits.h +- +ros/message_operations.h +- + +/opt/ros/hydro/include/geometry_msgs/Twist.h +string +- +vector +- +map +- +ros/types.h +- +ros/serialization.h +- +ros/builtin_message_traits.h +- +ros/message_operations.h +- +geometry_msgs/Vector3.h +- +geometry_msgs/Vector3.h +- + +/opt/ros/hydro/include/geometry_msgs/Vector3.h +string +- +vector +- +map +- +ros/types.h +- +ros/serialization.h +- +ros/builtin_message_traits.h +- +ros/message_operations.h +- + +/opt/ros/hydro/include/ros/advertise_options.h +ros/forwards.h +/opt/ros/hydro/include/ros/ros/forwards.h +ros/message_traits.h +/opt/ros/hydro/include/ros/ros/message_traits.h +common.h +/opt/ros/hydro/include/ros/common.h + +/opt/ros/hydro/include/ros/advertise_service_options.h +ros/forwards.h +/opt/ros/hydro/include/ros/ros/forwards.h +ros/service_callback_helper.h +/opt/ros/hydro/include/ros/ros/service_callback_helper.h +ros/service_traits.h +/opt/ros/hydro/include/ros/ros/service_traits.h +ros/message_traits.h +/opt/ros/hydro/include/ros/ros/message_traits.h +common.h +/opt/ros/hydro/include/ros/common.h + +/opt/ros/hydro/include/ros/assert.h +ros/console.h +/opt/ros/hydro/include/ros/ros/console.h +ros/static_assert.h +/opt/ros/hydro/include/ros/ros/static_assert.h +ros/platform.h +- +stdlib.h +- + +/opt/ros/hydro/include/ros/builtin_message_traits.h +message_traits.h +/opt/ros/hydro/include/ros/message_traits.h +ros/time.h +/opt/ros/hydro/include/ros/ros/time.h + +/opt/ros/hydro/include/ros/common.h +stdint.h +- +assert.h +- +stddef.h +- +string +- +ros/assert.h +/opt/ros/hydro/include/ros/ros/assert.h +ros/forwards.h +/opt/ros/hydro/include/ros/ros/forwards.h +ros/serialized_message.h +/opt/ros/hydro/include/ros/ros/serialized_message.h +boost/shared_array.hpp +- +ros/macros.h +- + +/opt/ros/hydro/include/ros/console.h +console_backend.h +/opt/ros/hydro/include/ros/console_backend.h +cstdio +- +sstream +- +ros/time.h +- +cstdarg +- +ros/macros.h +- +map +- +log4cxx/level.h +/opt/ros/hydro/include/ros/log4cxx/level.h +rosconsole/macros_generated.h +/opt/ros/hydro/include/ros/rosconsole/macros_generated.h + +/opt/ros/hydro/include/ros/console_backend.h + +/opt/ros/hydro/include/ros/datatypes.h +string +- +vector +- +map +- +set +- +list +- +boost/shared_ptr.hpp +- + +/opt/ros/hydro/include/ros/duration.h +iostream +- +math.h +- +stdexcept +- +climits +- +stdint.h +- +rostime_decl.h +/opt/ros/hydro/include/ros/rostime_decl.h + +/opt/ros/hydro/include/ros/exception.h +stdexcept +- + +/opt/ros/hydro/include/ros/exceptions.h +ros/exception.h +- + +/opt/ros/hydro/include/ros/forwards.h +string +- +vector +- +map +- +set +- +list +- +boost/shared_ptr.hpp +- +boost/weak_ptr.hpp +- +boost/function.hpp +- +ros/time.h +- +ros/macros.h +- +exceptions.h +/opt/ros/hydro/include/ros/exceptions.h +ros/datatypes.h +/opt/ros/hydro/include/ros/ros/datatypes.h + +/opt/ros/hydro/include/ros/init.h +ros/forwards.h +/opt/ros/hydro/include/ros/ros/forwards.h +ros/spinner.h +/opt/ros/hydro/include/ros/ros/spinner.h +common.h +/opt/ros/hydro/include/ros/common.h + +/opt/ros/hydro/include/ros/macros.h + +/opt/ros/hydro/include/ros/master.h +forwards.h +/opt/ros/hydro/include/ros/forwards.h +XmlRpcValue.h +/opt/ros/hydro/include/ros/XmlRpcValue.h +common.h +/opt/ros/hydro/include/ros/common.h + +/opt/ros/hydro/include/ros/message.h +ros/macros.h +/opt/ros/hydro/include/ros/ros/macros.h +ros/assert.h +/opt/ros/hydro/include/ros/ros/assert.h +string +- +string.h +- +boost/shared_ptr.hpp +- +boost/array.hpp +- +stdint.h +- + +/opt/ros/hydro/include/ros/message_event.h +ros/time.h +/opt/ros/hydro/include/ros/ros/time.h +ros/datatypes.h +- +ros/message_traits.h +- +boost/type_traits/is_void.hpp +- +boost/type_traits/is_base_of.hpp +- +boost/type_traits/is_const.hpp +- +boost/type_traits/add_const.hpp +- +boost/type_traits/remove_const.hpp +- +boost/utility/enable_if.hpp +- +boost/function.hpp +- +boost/make_shared.hpp +- + +/opt/ros/hydro/include/ros/message_forward.h +memory +- + +/opt/ros/hydro/include/ros/message_operations.h +ostream +- + +/opt/ros/hydro/include/ros/message_traits.h +message_forward.h +/opt/ros/hydro/include/ros/message_forward.h +ros/time.h +- +string +- +boost/utility/enable_if.hpp +- +boost/type_traits/remove_const.hpp +- +boost/type_traits/remove_reference.hpp +- + +/opt/ros/hydro/include/ros/names.h +forwards.h +/opt/ros/hydro/include/ros/forwards.h +common.h +/opt/ros/hydro/include/ros/common.h + +/opt/ros/hydro/include/ros/node_handle.h +ros/forwards.h +/opt/ros/hydro/include/ros/ros/forwards.h +ros/publisher.h +/opt/ros/hydro/include/ros/ros/publisher.h +ros/subscriber.h +/opt/ros/hydro/include/ros/ros/subscriber.h +ros/service_server.h +/opt/ros/hydro/include/ros/ros/service_server.h +ros/service_client.h +/opt/ros/hydro/include/ros/ros/service_client.h +ros/timer.h +/opt/ros/hydro/include/ros/ros/timer.h +ros/rate.h +/opt/ros/hydro/include/ros/ros/rate.h +ros/wall_timer.h +/opt/ros/hydro/include/ros/ros/wall_timer.h +ros/advertise_options.h +/opt/ros/hydro/include/ros/ros/advertise_options.h +ros/advertise_service_options.h +/opt/ros/hydro/include/ros/ros/advertise_service_options.h +ros/subscribe_options.h +/opt/ros/hydro/include/ros/ros/subscribe_options.h +ros/service_client_options.h +/opt/ros/hydro/include/ros/ros/service_client_options.h +ros/timer_options.h +/opt/ros/hydro/include/ros/ros/timer_options.h +ros/wall_timer_options.h +/opt/ros/hydro/include/ros/ros/wall_timer_options.h +ros/spinner.h +/opt/ros/hydro/include/ros/ros/spinner.h +ros/init.h +/opt/ros/hydro/include/ros/ros/init.h +common.h +/opt/ros/hydro/include/ros/common.h +boost/bind.hpp +- +XmlRpcValue.h +- + +/opt/ros/hydro/include/ros/param.h +forwards.h +/opt/ros/hydro/include/ros/forwards.h +common.h +/opt/ros/hydro/include/ros/common.h +XmlRpcValue.h +/opt/ros/hydro/include/ros/XmlRpcValue.h +vector +- +map +- + +/opt/ros/hydro/include/ros/parameter_adapter.h +ros/forwards.h +/opt/ros/hydro/include/ros/ros/forwards.h +ros/message_event.h +/opt/ros/hydro/include/ros/ros/message_event.h +ros/static_assert.h +- +boost/type_traits/add_const.hpp +- +boost/type_traits/remove_const.hpp +- +boost/type_traits/remove_reference.hpp +- + +/opt/ros/hydro/include/ros/platform.h +windows.h +- +stdlib.h +- +string +- + +/opt/ros/hydro/include/ros/publisher.h +ros/forwards.h +/opt/ros/hydro/include/ros/ros/forwards.h +ros/common.h +/opt/ros/hydro/include/ros/ros/common.h +ros/message.h +/opt/ros/hydro/include/ros/ros/message.h +ros/serialization.h +/opt/ros/hydro/include/ros/ros/serialization.h +boost/bind.hpp +- + +/opt/ros/hydro/include/ros/rate.h +ros/time.h +/opt/ros/hydro/include/ros/ros/time.h +rostime_decl.h +/opt/ros/hydro/include/ros/rostime_decl.h + +/opt/ros/hydro/include/ros/ros.h +ros/time.h +/opt/ros/hydro/include/ros/ros/time.h +ros/rate.h +/opt/ros/hydro/include/ros/ros/rate.h +ros/console.h +/opt/ros/hydro/include/ros/ros/console.h +ros/assert.h +/opt/ros/hydro/include/ros/ros/assert.h +ros/common.h +/opt/ros/hydro/include/ros/ros/common.h +ros/types.h +/opt/ros/hydro/include/ros/ros/types.h +ros/node_handle.h +/opt/ros/hydro/include/ros/ros/node_handle.h +ros/publisher.h +/opt/ros/hydro/include/ros/ros/publisher.h +ros/single_subscriber_publisher.h +/opt/ros/hydro/include/ros/ros/single_subscriber_publisher.h +ros/service_server.h +/opt/ros/hydro/include/ros/ros/service_server.h +ros/subscriber.h +/opt/ros/hydro/include/ros/ros/subscriber.h +ros/service.h +/opt/ros/hydro/include/ros/ros/service.h +ros/init.h +/opt/ros/hydro/include/ros/ros/init.h +ros/master.h +/opt/ros/hydro/include/ros/ros/master.h +ros/this_node.h +/opt/ros/hydro/include/ros/ros/this_node.h +ros/param.h +/opt/ros/hydro/include/ros/ros/param.h +ros/topic.h +/opt/ros/hydro/include/ros/ros/topic.h +ros/names.h +/opt/ros/hydro/include/ros/ros/names.h + +/opt/ros/hydro/include/ros/roscpp_serialization_macros.h +ros/macros.h +- + +/opt/ros/hydro/include/ros/rostime_decl.h +ros/macros.h +- + +/opt/ros/hydro/include/ros/serialization.h +roscpp_serialization_macros.h +/opt/ros/hydro/include/ros/roscpp_serialization_macros.h +ros/types.h +- +ros/time.h +- +serialized_message.h +/opt/ros/hydro/include/ros/serialized_message.h +ros/message_traits.h +/opt/ros/hydro/include/ros/ros/message_traits.h +ros/builtin_message_traits.h +/opt/ros/hydro/include/ros/ros/builtin_message_traits.h +ros/exception.h +/opt/ros/hydro/include/ros/ros/exception.h +ros/datatypes.h +/opt/ros/hydro/include/ros/ros/datatypes.h +vector +- +map +- +boost/array.hpp +- +boost/call_traits.hpp +- +boost/utility/enable_if.hpp +- +boost/mpl/and.hpp +- +boost/mpl/or.hpp +- +boost/mpl/not.hpp +- +cstring +- + +/opt/ros/hydro/include/ros/serialized_message.h +roscpp_serialization_macros.h +/opt/ros/hydro/include/ros/roscpp_serialization_macros.h +boost/shared_array.hpp +- +boost/shared_ptr.hpp +- + +/opt/ros/hydro/include/ros/service.h +string +- +ros/common.h +/opt/ros/hydro/include/ros/ros/common.h +ros/message.h +/opt/ros/hydro/include/ros/ros/message.h +ros/forwards.h +/opt/ros/hydro/include/ros/ros/forwards.h +ros/node_handle.h +/opt/ros/hydro/include/ros/ros/node_handle.h +ros/service_traits.h +/opt/ros/hydro/include/ros/ros/service_traits.h +ros/names.h +/opt/ros/hydro/include/ros/ros/names.h +boost/shared_ptr.hpp +- + +/opt/ros/hydro/include/ros/service_callback_helper.h +ros/forwards.h +/opt/ros/hydro/include/ros/ros/forwards.h +ros/common.h +/opt/ros/hydro/include/ros/ros/common.h +ros/message.h +/opt/ros/hydro/include/ros/ros/message.h +ros/message_traits.h +/opt/ros/hydro/include/ros/ros/message_traits.h +ros/service_traits.h +/opt/ros/hydro/include/ros/ros/service_traits.h +ros/serialization.h +/opt/ros/hydro/include/ros/ros/serialization.h +boost/type_traits/is_base_of.hpp +- +boost/utility/enable_if.hpp +- + +/opt/ros/hydro/include/ros/service_client.h +ros/forwards.h +/opt/ros/hydro/include/ros/ros/forwards.h +ros/common.h +/opt/ros/hydro/include/ros/ros/common.h +ros/service_traits.h +/opt/ros/hydro/include/ros/ros/service_traits.h +ros/serialization.h +/opt/ros/hydro/include/ros/ros/serialization.h + +/opt/ros/hydro/include/ros/service_client_options.h +ros/forwards.h +/opt/ros/hydro/include/ros/ros/forwards.h +common.h +/opt/ros/hydro/include/ros/common.h +ros/service_traits.h +/opt/ros/hydro/include/ros/ros/service_traits.h + +/opt/ros/hydro/include/ros/service_server.h +ros/forwards.h +/opt/ros/hydro/include/ros/ros/forwards.h +common.h +/opt/ros/hydro/include/ros/common.h + +/opt/ros/hydro/include/ros/service_traits.h +boost/type_traits/remove_reference.hpp +- +boost/type_traits/remove_const.hpp +- + +/opt/ros/hydro/include/ros/single_subscriber_publisher.h +ros/forwards.h +/opt/ros/hydro/include/ros/ros/forwards.h +ros/serialization.h +/opt/ros/hydro/include/ros/ros/serialization.h +common.h +/opt/ros/hydro/include/ros/common.h +boost/utility.hpp +- + +/opt/ros/hydro/include/ros/spinner.h +ros/types.h +/opt/ros/hydro/include/ros/ros/types.h +common.h +/opt/ros/hydro/include/ros/common.h +boost/shared_ptr.hpp +- + +/opt/ros/hydro/include/ros/static_assert.h +boost/static_assert.hpp +- + +/opt/ros/hydro/include/ros/subscribe_options.h +ros/forwards.h +/opt/ros/hydro/include/ros/ros/forwards.h +common.h +/opt/ros/hydro/include/ros/common.h +ros/transport_hints.h +/opt/ros/hydro/include/ros/ros/transport_hints.h +ros/message_traits.h +/opt/ros/hydro/include/ros/ros/message_traits.h +subscription_callback_helper.h +/opt/ros/hydro/include/ros/subscription_callback_helper.h + +/opt/ros/hydro/include/ros/subscriber.h +common.h +/opt/ros/hydro/include/ros/common.h +ros/forwards.h +/opt/ros/hydro/include/ros/ros/forwards.h +ros/subscription_callback_helper.h +/opt/ros/hydro/include/ros/ros/subscription_callback_helper.h + +/opt/ros/hydro/include/ros/subscription_callback_helper.h +typeinfo +- +common.h +/opt/ros/hydro/include/ros/common.h +ros/forwards.h +/opt/ros/hydro/include/ros/ros/forwards.h +ros/parameter_adapter.h +/opt/ros/hydro/include/ros/ros/parameter_adapter.h +ros/message_traits.h +/opt/ros/hydro/include/ros/ros/message_traits.h +ros/builtin_message_traits.h +/opt/ros/hydro/include/ros/ros/builtin_message_traits.h +ros/serialization.h +/opt/ros/hydro/include/ros/ros/serialization.h +ros/message_event.h +/opt/ros/hydro/include/ros/ros/message_event.h +ros/static_assert.h +- +boost/type_traits/add_const.hpp +- +boost/type_traits/remove_const.hpp +- +boost/type_traits/remove_reference.hpp +- +boost/type_traits/is_base_of.hpp +- +boost/utility/enable_if.hpp +- +boost/make_shared.hpp +- + +/opt/ros/hydro/include/ros/this_node.h +common.h +/opt/ros/hydro/include/ros/common.h +forwards.h +/opt/ros/hydro/include/ros/forwards.h + +/opt/ros/hydro/include/ros/time.h +ros/platform.h +- +iostream +- +cmath +- +ros/exception.h +- +duration.h +/opt/ros/hydro/include/ros/duration.h +boost/math/special_functions/round.hpp +- +rostime_decl.h +/opt/ros/hydro/include/ros/rostime_decl.h +sys/timeb.h +- +sys/time.h +- + +/opt/ros/hydro/include/ros/timer.h +common.h +/opt/ros/hydro/include/ros/common.h +forwards.h +/opt/ros/hydro/include/ros/forwards.h +timer_options.h +/opt/ros/hydro/include/ros/timer_options.h + +/opt/ros/hydro/include/ros/timer_options.h +common.h +/opt/ros/hydro/include/ros/common.h +ros/forwards.h +/opt/ros/hydro/include/ros/ros/forwards.h + +/opt/ros/hydro/include/ros/topic.h +common.h +/opt/ros/hydro/include/ros/common.h +node_handle.h +/opt/ros/hydro/include/ros/node_handle.h +boost/shared_ptr.hpp +- + +/opt/ros/hydro/include/ros/transport_hints.h +common.h +/opt/ros/hydro/include/ros/common.h +ros/forwards.h +/opt/ros/hydro/include/ros/ros/forwards.h +boost/lexical_cast.hpp +- + +/opt/ros/hydro/include/ros/types.h +stdint.h +- + +/opt/ros/hydro/include/ros/wall_timer.h +common.h +/opt/ros/hydro/include/ros/common.h +forwards.h +/opt/ros/hydro/include/ros/forwards.h +wall_timer_options.h +/opt/ros/hydro/include/ros/wall_timer_options.h + +/opt/ros/hydro/include/ros/wall_timer_options.h +common.h +/opt/ros/hydro/include/ros/common.h +ros/forwards.h +/opt/ros/hydro/include/ros/ros/forwards.h + +/opt/ros/hydro/include/rosconsole/macros_generated.h + +/opt/ros/hydro/include/sensor_msgs/ChannelFloat32.h +string +- +vector +- +map +- +ros/types.h +- +ros/serialization.h +- +ros/builtin_message_traits.h +- +ros/message_operations.h +- + +/opt/ros/hydro/include/sensor_msgs/PointCloud.h +string +- +vector +- +map +- +ros/types.h +- +ros/serialization.h +- +ros/builtin_message_traits.h +- +ros/message_operations.h +- +std_msgs/Header.h +- +geometry_msgs/Point32.h +- +sensor_msgs/ChannelFloat32.h +- + +/opt/ros/hydro/include/std_msgs/Float32.h +string +- +vector +- +map +- +ros/types.h +- +ros/serialization.h +- +ros/builtin_message_traits.h +- +ros/message_operations.h +- + +/opt/ros/hydro/include/std_msgs/Header.h +string +- +vector +- +map +- +ros/types.h +- +ros/serialization.h +- +ros/builtin_message_traits.h +- +ros/message_operations.h +- + +/opt/ros/hydro/include/std_srvs/Empty.h +ros/service_traits.h +- +std_srvs/EmptyRequest.h +- +std_srvs/EmptyResponse.h +- + +/opt/ros/hydro/include/std_srvs/EmptyRequest.h +string +- +vector +- +map +- +ros/types.h +- +ros/serialization.h +- +ros/builtin_message_traits.h +- +ros/message_operations.h +- + +/opt/ros/hydro/include/std_srvs/EmptyResponse.h +string +- +vector +- +map +- +ros/types.h +- +ros/serialization.h +- +ros/builtin_message_traits.h +- +ros/message_operations.h +- + diff --git a/Legacy/ws_linux/build/safety/CMakeFiles/cloud_reader.dir/DependInfo.cmake b/Legacy/ws_linux/build/safety/CMakeFiles/cloud_reader.dir/DependInfo.cmake new file mode 100644 index 0000000..0829414 --- /dev/null +++ b/Legacy/ws_linux/build/safety/CMakeFiles/cloud_reader.dir/DependInfo.cmake @@ -0,0 +1,20 @@ +# The set of languages for which implicit dependencies are needed: +SET(CMAKE_DEPENDS_LANGUAGES + "CXX" + ) +# The set of files for implicit dependencies of each language: +SET(CMAKE_DEPENDS_CHECK_CXX + "/home/lab1_5/ws/ws_linux/src/safety/src/cloud_reader.cpp" "/home/lab1_5/ws/ws_linux/build/safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o" + ) +SET(CMAKE_CXX_COMPILER_ID "GNU") + +# Preprocessor definitions for this target. +SET(CMAKE_TARGET_DEFINITIONS + "ROS_BUILD_SHARED_LIBS=1" + "ROS_PACKAGE_NAME=\"safety\"" + "ROSCONSOLE_BACKEND_LOG4CXX" + ) + +# Targets to which this target links. +SET(CMAKE_TARGET_LINKED_INFO_FILES + ) diff --git a/Legacy/ws_linux/build/safety/CMakeFiles/cloud_reader.dir/build.make b/Legacy/ws_linux/build/safety/CMakeFiles/cloud_reader.dir/build.make new file mode 100644 index 0000000..668abd2 --- /dev/null +++ b/Legacy/ws_linux/build/safety/CMakeFiles/cloud_reader.dir/build.make @@ -0,0 +1,121 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/lab1_5/ws/ws_linux/src + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/lab1_5/ws/ws_linux/build + +# Include any dependencies generated for this target. +include safety/CMakeFiles/cloud_reader.dir/depend.make + +# Include the progress variables for this target. +include safety/CMakeFiles/cloud_reader.dir/progress.make + +# Include the compile flags for this target's objects. +include safety/CMakeFiles/cloud_reader.dir/flags.make + +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o: safety/CMakeFiles/cloud_reader.dir/flags.make +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o: /home/lab1_5/ws/ws_linux/src/safety/src/cloud_reader.cpp + $(CMAKE_COMMAND) -E cmake_progress_report /home/lab1_5/ws/ws_linux/build/CMakeFiles $(CMAKE_PROGRESS_1) + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Building CXX object safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o" + cd /home/lab1_5/ws/ws_linux/build/safety && /usr/bin/c++ $(CXX_DEFINES) $(CXX_FLAGS) -o CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o -c /home/lab1_5/ws/ws_linux/src/safety/src/cloud_reader.cpp + +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing CXX source to CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.i" + cd /home/lab1_5/ws/ws_linux/build/safety && /usr/bin/c++ $(CXX_DEFINES) $(CXX_FLAGS) -E /home/lab1_5/ws/ws_linux/src/safety/src/cloud_reader.cpp > CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.i + +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling CXX source to assembly CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.s" + cd /home/lab1_5/ws/ws_linux/build/safety && /usr/bin/c++ $(CXX_DEFINES) $(CXX_FLAGS) -S /home/lab1_5/ws/ws_linux/src/safety/src/cloud_reader.cpp -o CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.s + +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o.requires: +.PHONY : safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o.requires + +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o.provides: safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o.requires + $(MAKE) -f safety/CMakeFiles/cloud_reader.dir/build.make safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o.provides.build +.PHONY : safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o.provides + +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o.provides.build: safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o + +# Object files for target cloud_reader +cloud_reader_OBJECTS = \ +"CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o" + +# External object files for target cloud_reader +cloud_reader_EXTERNAL_OBJECTS = + +/home/lab1_5/ws/ws_linux/devel/lib/safety/cloud_reader: safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o +/home/lab1_5/ws/ws_linux/devel/lib/safety/cloud_reader: /opt/ros/hydro/lib/libtf.so +/home/lab1_5/ws/ws_linux/devel/lib/safety/cloud_reader: /opt/ros/hydro/lib/libtf2_ros.so +/home/lab1_5/ws/ws_linux/devel/lib/safety/cloud_reader: /opt/ros/hydro/lib/libactionlib.so +/home/lab1_5/ws/ws_linux/devel/lib/safety/cloud_reader: /opt/ros/hydro/lib/libmessage_filters.so +/home/lab1_5/ws/ws_linux/devel/lib/safety/cloud_reader: /opt/ros/hydro/lib/libroscpp.so +/home/lab1_5/ws/ws_linux/devel/lib/safety/cloud_reader: /usr/lib/libboost_signals-mt.so +/home/lab1_5/ws/ws_linux/devel/lib/safety/cloud_reader: /usr/lib/libboost_filesystem-mt.so +/home/lab1_5/ws/ws_linux/devel/lib/safety/cloud_reader: /opt/ros/hydro/lib/libxmlrpcpp.so +/home/lab1_5/ws/ws_linux/devel/lib/safety/cloud_reader: /opt/ros/hydro/lib/libtf2.so +/home/lab1_5/ws/ws_linux/devel/lib/safety/cloud_reader: /opt/ros/hydro/lib/libroscpp_serialization.so +/home/lab1_5/ws/ws_linux/devel/lib/safety/cloud_reader: /opt/ros/hydro/lib/librosconsole.so +/home/lab1_5/ws/ws_linux/devel/lib/safety/cloud_reader: /opt/ros/hydro/lib/librosconsole_log4cxx.so +/home/lab1_5/ws/ws_linux/devel/lib/safety/cloud_reader: /opt/ros/hydro/lib/librosconsole_backend_interface.so +/home/lab1_5/ws/ws_linux/devel/lib/safety/cloud_reader: /usr/lib/liblog4cxx.so +/home/lab1_5/ws/ws_linux/devel/lib/safety/cloud_reader: /usr/lib/libboost_regex-mt.so +/home/lab1_5/ws/ws_linux/devel/lib/safety/cloud_reader: /opt/ros/hydro/lib/librostime.so +/home/lab1_5/ws/ws_linux/devel/lib/safety/cloud_reader: /usr/lib/libboost_date_time-mt.so +/home/lab1_5/ws/ws_linux/devel/lib/safety/cloud_reader: /usr/lib/libboost_system-mt.so +/home/lab1_5/ws/ws_linux/devel/lib/safety/cloud_reader: /usr/lib/libboost_thread-mt.so +/home/lab1_5/ws/ws_linux/devel/lib/safety/cloud_reader: /usr/lib/x86_64-linux-gnu/libpthread.so +/home/lab1_5/ws/ws_linux/devel/lib/safety/cloud_reader: /opt/ros/hydro/lib/libcpp_common.so +/home/lab1_5/ws/ws_linux/devel/lib/safety/cloud_reader: /opt/ros/hydro/lib/libconsole_bridge.so +/home/lab1_5/ws/ws_linux/devel/lib/safety/cloud_reader: safety/CMakeFiles/cloud_reader.dir/build.make +/home/lab1_5/ws/ws_linux/devel/lib/safety/cloud_reader: safety/CMakeFiles/cloud_reader.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --red --bold "Linking CXX executable /home/lab1_5/ws/ws_linux/devel/lib/safety/cloud_reader" + cd /home/lab1_5/ws/ws_linux/build/safety && $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/cloud_reader.dir/link.txt --verbose=$(VERBOSE) + +# Rule to build all files generated by this target. +safety/CMakeFiles/cloud_reader.dir/build: /home/lab1_5/ws/ws_linux/devel/lib/safety/cloud_reader +.PHONY : safety/CMakeFiles/cloud_reader.dir/build + +safety/CMakeFiles/cloud_reader.dir/requires: safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o.requires +.PHONY : safety/CMakeFiles/cloud_reader.dir/requires + +safety/CMakeFiles/cloud_reader.dir/clean: + cd /home/lab1_5/ws/ws_linux/build/safety && $(CMAKE_COMMAND) -P CMakeFiles/cloud_reader.dir/cmake_clean.cmake +.PHONY : safety/CMakeFiles/cloud_reader.dir/clean + +safety/CMakeFiles/cloud_reader.dir/depend: + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/lab1_5/ws/ws_linux/src /home/lab1_5/ws/ws_linux/src/safety /home/lab1_5/ws/ws_linux/build /home/lab1_5/ws/ws_linux/build/safety /home/lab1_5/ws/ws_linux/build/safety/CMakeFiles/cloud_reader.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : safety/CMakeFiles/cloud_reader.dir/depend + diff --git a/Legacy/ws_linux/build/safety/CMakeFiles/cloud_reader.dir/cmake_clean.cmake b/Legacy/ws_linux/build/safety/CMakeFiles/cloud_reader.dir/cmake_clean.cmake new file mode 100644 index 0000000..90229e7 --- /dev/null +++ b/Legacy/ws_linux/build/safety/CMakeFiles/cloud_reader.dir/cmake_clean.cmake @@ -0,0 +1,10 @@ +FILE(REMOVE_RECURSE + "CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o" + "/home/lab1_5/ws/ws_linux/devel/lib/safety/cloud_reader.pdb" + "/home/lab1_5/ws/ws_linux/devel/lib/safety/cloud_reader" +) + +# Per-language clean rules from dependency scanning. +FOREACH(lang CXX) + INCLUDE(CMakeFiles/cloud_reader.dir/cmake_clean_${lang}.cmake OPTIONAL) +ENDFOREACH(lang) diff --git a/Legacy/ws_linux/build/safety/CMakeFiles/cloud_reader.dir/depend.internal b/Legacy/ws_linux/build/safety/CMakeFiles/cloud_reader.dir/depend.internal new file mode 100644 index 0000000..a0dce07 --- /dev/null +++ b/Legacy/ws_linux/build/safety/CMakeFiles/cloud_reader.dir/depend.internal @@ -0,0 +1,83 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o + /home/lab1_5/ws/ws_linux/devel/include/rosaria/RosAriaConfig.h + /home/lab1_5/ws/ws_linux/src/safety/src/cloud_reader.cpp + /opt/ros/hydro/include/XmlRpcDecl.h + /opt/ros/hydro/include/XmlRpcValue.h + /opt/ros/hydro/include/dynamic_reconfigure/BoolParameter.h + /opt/ros/hydro/include/dynamic_reconfigure/Config.h + /opt/ros/hydro/include/dynamic_reconfigure/ConfigDescription.h + /opt/ros/hydro/include/dynamic_reconfigure/DoubleParameter.h + /opt/ros/hydro/include/dynamic_reconfigure/Group.h + /opt/ros/hydro/include/dynamic_reconfigure/GroupState.h + /opt/ros/hydro/include/dynamic_reconfigure/IntParameter.h + /opt/ros/hydro/include/dynamic_reconfigure/ParamDescription.h + /opt/ros/hydro/include/dynamic_reconfigure/StrParameter.h + /opt/ros/hydro/include/dynamic_reconfigure/config_init_mutex.h + /opt/ros/hydro/include/dynamic_reconfigure/config_tools.h + /opt/ros/hydro/include/geometry_msgs/Point32.h + /opt/ros/hydro/include/geometry_msgs/Twist.h + /opt/ros/hydro/include/geometry_msgs/Vector3.h + /opt/ros/hydro/include/ros/advertise_options.h + /opt/ros/hydro/include/ros/advertise_service_options.h + /opt/ros/hydro/include/ros/assert.h + /opt/ros/hydro/include/ros/builtin_message_traits.h + /opt/ros/hydro/include/ros/common.h + /opt/ros/hydro/include/ros/console.h + /opt/ros/hydro/include/ros/console_backend.h + /opt/ros/hydro/include/ros/datatypes.h + /opt/ros/hydro/include/ros/duration.h + /opt/ros/hydro/include/ros/exception.h + /opt/ros/hydro/include/ros/exceptions.h + /opt/ros/hydro/include/ros/forwards.h + /opt/ros/hydro/include/ros/init.h + /opt/ros/hydro/include/ros/macros.h + /opt/ros/hydro/include/ros/master.h + /opt/ros/hydro/include/ros/message.h + /opt/ros/hydro/include/ros/message_event.h + /opt/ros/hydro/include/ros/message_forward.h + /opt/ros/hydro/include/ros/message_operations.h + /opt/ros/hydro/include/ros/message_traits.h + /opt/ros/hydro/include/ros/names.h + /opt/ros/hydro/include/ros/node_handle.h + /opt/ros/hydro/include/ros/param.h + /opt/ros/hydro/include/ros/parameter_adapter.h + /opt/ros/hydro/include/ros/platform.h + /opt/ros/hydro/include/ros/publisher.h + /opt/ros/hydro/include/ros/rate.h + /opt/ros/hydro/include/ros/ros.h + /opt/ros/hydro/include/ros/roscpp_serialization_macros.h + /opt/ros/hydro/include/ros/rostime_decl.h + /opt/ros/hydro/include/ros/serialization.h + /opt/ros/hydro/include/ros/serialized_message.h + /opt/ros/hydro/include/ros/service.h + /opt/ros/hydro/include/ros/service_callback_helper.h + /opt/ros/hydro/include/ros/service_client.h + /opt/ros/hydro/include/ros/service_client_options.h + /opt/ros/hydro/include/ros/service_server.h + /opt/ros/hydro/include/ros/service_traits.h + /opt/ros/hydro/include/ros/single_subscriber_publisher.h + /opt/ros/hydro/include/ros/spinner.h + /opt/ros/hydro/include/ros/static_assert.h + /opt/ros/hydro/include/ros/subscribe_options.h + /opt/ros/hydro/include/ros/subscriber.h + /opt/ros/hydro/include/ros/subscription_callback_helper.h + /opt/ros/hydro/include/ros/this_node.h + /opt/ros/hydro/include/ros/time.h + /opt/ros/hydro/include/ros/timer.h + /opt/ros/hydro/include/ros/timer_options.h + /opt/ros/hydro/include/ros/topic.h + /opt/ros/hydro/include/ros/transport_hints.h + /opt/ros/hydro/include/ros/types.h + /opt/ros/hydro/include/ros/wall_timer.h + /opt/ros/hydro/include/ros/wall_timer_options.h + /opt/ros/hydro/include/rosconsole/macros_generated.h + /opt/ros/hydro/include/sensor_msgs/ChannelFloat32.h + /opt/ros/hydro/include/sensor_msgs/PointCloud.h + /opt/ros/hydro/include/std_msgs/Float32.h + /opt/ros/hydro/include/std_msgs/Header.h + /opt/ros/hydro/include/std_srvs/Empty.h + /opt/ros/hydro/include/std_srvs/EmptyRequest.h + /opt/ros/hydro/include/std_srvs/EmptyResponse.h diff --git a/Legacy/ws_linux/build/safety/CMakeFiles/cloud_reader.dir/depend.make b/Legacy/ws_linux/build/safety/CMakeFiles/cloud_reader.dir/depend.make new file mode 100644 index 0000000..11e0b1f --- /dev/null +++ b/Legacy/ws_linux/build/safety/CMakeFiles/cloud_reader.dir/depend.make @@ -0,0 +1,83 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o: /home/lab1_5/ws/ws_linux/devel/include/rosaria/RosAriaConfig.h +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o: /home/lab1_5/ws/ws_linux/src/safety/src/cloud_reader.cpp +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o: /opt/ros/hydro/include/XmlRpcDecl.h +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o: /opt/ros/hydro/include/XmlRpcValue.h +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o: /opt/ros/hydro/include/dynamic_reconfigure/BoolParameter.h +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o: /opt/ros/hydro/include/dynamic_reconfigure/Config.h +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o: /opt/ros/hydro/include/dynamic_reconfigure/ConfigDescription.h +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o: /opt/ros/hydro/include/dynamic_reconfigure/DoubleParameter.h +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o: /opt/ros/hydro/include/dynamic_reconfigure/Group.h +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o: /opt/ros/hydro/include/dynamic_reconfigure/GroupState.h +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o: /opt/ros/hydro/include/dynamic_reconfigure/IntParameter.h +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o: /opt/ros/hydro/include/dynamic_reconfigure/ParamDescription.h +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o: /opt/ros/hydro/include/dynamic_reconfigure/StrParameter.h +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o: /opt/ros/hydro/include/dynamic_reconfigure/config_init_mutex.h +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o: /opt/ros/hydro/include/dynamic_reconfigure/config_tools.h +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o: /opt/ros/hydro/include/geometry_msgs/Point32.h +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o: /opt/ros/hydro/include/geometry_msgs/Twist.h +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o: /opt/ros/hydro/include/geometry_msgs/Vector3.h +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o: /opt/ros/hydro/include/ros/advertise_options.h +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o: /opt/ros/hydro/include/ros/advertise_service_options.h +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o: /opt/ros/hydro/include/ros/assert.h +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o: /opt/ros/hydro/include/ros/builtin_message_traits.h +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o: /opt/ros/hydro/include/ros/common.h +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o: /opt/ros/hydro/include/ros/console.h +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o: /opt/ros/hydro/include/ros/console_backend.h +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o: /opt/ros/hydro/include/ros/datatypes.h +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o: /opt/ros/hydro/include/ros/duration.h +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o: /opt/ros/hydro/include/ros/exception.h +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o: /opt/ros/hydro/include/ros/exceptions.h +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o: /opt/ros/hydro/include/ros/forwards.h +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o: /opt/ros/hydro/include/ros/init.h +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o: /opt/ros/hydro/include/ros/macros.h +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o: /opt/ros/hydro/include/ros/master.h +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o: /opt/ros/hydro/include/ros/message.h +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o: /opt/ros/hydro/include/ros/message_event.h +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o: /opt/ros/hydro/include/ros/message_forward.h +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o: /opt/ros/hydro/include/ros/message_operations.h +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o: /opt/ros/hydro/include/ros/message_traits.h +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o: /opt/ros/hydro/include/ros/names.h +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o: /opt/ros/hydro/include/ros/node_handle.h +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o: /opt/ros/hydro/include/ros/param.h +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o: /opt/ros/hydro/include/ros/parameter_adapter.h +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o: /opt/ros/hydro/include/ros/platform.h +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o: /opt/ros/hydro/include/ros/publisher.h +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o: /opt/ros/hydro/include/ros/rate.h +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o: /opt/ros/hydro/include/ros/ros.h +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o: /opt/ros/hydro/include/ros/roscpp_serialization_macros.h +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o: /opt/ros/hydro/include/ros/rostime_decl.h +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o: /opt/ros/hydro/include/ros/serialization.h +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o: /opt/ros/hydro/include/ros/serialized_message.h +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o: /opt/ros/hydro/include/ros/service.h +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o: /opt/ros/hydro/include/ros/service_callback_helper.h +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o: /opt/ros/hydro/include/ros/service_client.h +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o: /opt/ros/hydro/include/ros/service_client_options.h +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o: /opt/ros/hydro/include/ros/service_server.h +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o: /opt/ros/hydro/include/ros/service_traits.h +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o: /opt/ros/hydro/include/ros/single_subscriber_publisher.h +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o: /opt/ros/hydro/include/ros/spinner.h +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o: /opt/ros/hydro/include/ros/static_assert.h +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o: /opt/ros/hydro/include/ros/subscribe_options.h +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o: /opt/ros/hydro/include/ros/subscriber.h +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o: /opt/ros/hydro/include/ros/subscription_callback_helper.h +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o: /opt/ros/hydro/include/ros/this_node.h +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o: /opt/ros/hydro/include/ros/time.h +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o: /opt/ros/hydro/include/ros/timer.h +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o: /opt/ros/hydro/include/ros/timer_options.h +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o: /opt/ros/hydro/include/ros/topic.h +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o: /opt/ros/hydro/include/ros/transport_hints.h +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o: /opt/ros/hydro/include/ros/types.h +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o: /opt/ros/hydro/include/ros/wall_timer.h +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o: /opt/ros/hydro/include/ros/wall_timer_options.h +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o: /opt/ros/hydro/include/rosconsole/macros_generated.h +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o: /opt/ros/hydro/include/sensor_msgs/ChannelFloat32.h +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o: /opt/ros/hydro/include/sensor_msgs/PointCloud.h +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o: /opt/ros/hydro/include/std_msgs/Float32.h +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o: /opt/ros/hydro/include/std_msgs/Header.h +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o: /opt/ros/hydro/include/std_srvs/Empty.h +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o: /opt/ros/hydro/include/std_srvs/EmptyRequest.h +safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o: /opt/ros/hydro/include/std_srvs/EmptyResponse.h + diff --git a/Legacy/ws_linux/build/safety/CMakeFiles/cloud_reader.dir/flags.make b/Legacy/ws_linux/build/safety/CMakeFiles/cloud_reader.dir/flags.make new file mode 100644 index 0000000..8c6832e --- /dev/null +++ b/Legacy/ws_linux/build/safety/CMakeFiles/cloud_reader.dir/flags.make @@ -0,0 +1,8 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +# compile CXX with /usr/bin/c++ +CXX_FLAGS = -I/home/lab1_5/ws/ws_linux/src/safety/include -I/home/lab1_5/ws/ws_linux/devel/include -I/opt/ros/hydro/include + +CXX_DEFINES = -DROS_BUILD_SHARED_LIBS=1 -DROS_PACKAGE_NAME=\"safety\" -DROSCONSOLE_BACKEND_LOG4CXX + diff --git a/Legacy/ws_linux/build/safety/CMakeFiles/cloud_reader.dir/link.txt b/Legacy/ws_linux/build/safety/CMakeFiles/cloud_reader.dir/link.txt new file mode 100644 index 0000000..2655fbf --- /dev/null +++ b/Legacy/ws_linux/build/safety/CMakeFiles/cloud_reader.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o -o /home/lab1_5/ws/ws_linux/devel/lib/safety/cloud_reader -rdynamic /opt/ros/hydro/lib/libtf.so /opt/ros/hydro/lib/libtf2_ros.so /opt/ros/hydro/lib/libactionlib.so /opt/ros/hydro/lib/libmessage_filters.so /opt/ros/hydro/lib/libroscpp.so -lboost_signals-mt -lboost_filesystem-mt /opt/ros/hydro/lib/libxmlrpcpp.so /opt/ros/hydro/lib/libtf2.so /opt/ros/hydro/lib/libroscpp_serialization.so /opt/ros/hydro/lib/librosconsole.so /opt/ros/hydro/lib/librosconsole_log4cxx.so /opt/ros/hydro/lib/librosconsole_backend_interface.so -llog4cxx -lboost_regex-mt /opt/ros/hydro/lib/librostime.so -lboost_date_time-mt -lboost_system-mt -lboost_thread-mt -lpthread /opt/ros/hydro/lib/libcpp_common.so /opt/ros/hydro/lib/libconsole_bridge.so -Wl,-rpath,/opt/ros/hydro/lib diff --git a/Legacy/ws_linux/build/safety/CMakeFiles/cloud_reader.dir/progress.make b/Legacy/ws_linux/build/safety/CMakeFiles/cloud_reader.dir/progress.make new file mode 100644 index 0000000..164e1d2 --- /dev/null +++ b/Legacy/ws_linux/build/safety/CMakeFiles/cloud_reader.dir/progress.make @@ -0,0 +1,2 @@ +CMAKE_PROGRESS_1 = 2 + diff --git a/Legacy/ws_linux/build/safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o b/Legacy/ws_linux/build/safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o new file mode 100644 index 0000000000000000000000000000000000000000..f73e440899ac80e69eb26bc2de0fcfd68aeace3b GIT binary patch literal 681648 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 Yz7T&6UxB}lce=39{%|at-XHA$05fx-GXMYp literal 0 HcmV?d00001 diff --git a/Legacy/ws_linux/build/safety/CMakeFiles/progress.marks b/Legacy/ws_linux/build/safety/CMakeFiles/progress.marks new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Legacy/ws_linux/build/safety/CMakeFiles/progress.marks @@ -0,0 +1 @@ +1 diff --git a/Legacy/ws_linux/build/safety/CMakeFiles/safety_gencpp.dir/DependInfo.cmake b/Legacy/ws_linux/build/safety/CMakeFiles/safety_gencpp.dir/DependInfo.cmake new file mode 100644 index 0000000..a7fba27 --- /dev/null +++ b/Legacy/ws_linux/build/safety/CMakeFiles/safety_gencpp.dir/DependInfo.cmake @@ -0,0 +1,15 @@ +# The set of languages for which implicit dependencies are needed: +SET(CMAKE_DEPENDS_LANGUAGES + ) +# The set of files for implicit dependencies of each language: + +# Preprocessor definitions for this target. +SET(CMAKE_TARGET_DEFINITIONS + "ROS_BUILD_SHARED_LIBS=1" + "ROS_PACKAGE_NAME=\"safety\"" + "ROSCONSOLE_BACKEND_LOG4CXX" + ) + +# Targets to which this target links. +SET(CMAKE_TARGET_LINKED_INFO_FILES + ) diff --git a/Legacy/ws_linux/build/safety/CMakeFiles/safety_gencpp.dir/build.make b/Legacy/ws_linux/build/safety/CMakeFiles/safety_gencpp.dir/build.make new file mode 100644 index 0000000..34be82b --- /dev/null +++ b/Legacy/ws_linux/build/safety/CMakeFiles/safety_gencpp.dir/build.make @@ -0,0 +1,62 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/lab1_5/ws/ws_linux/src + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/lab1_5/ws/ws_linux/build + +# Utility rule file for safety_gencpp. + +# Include the progress variables for this target. +include safety/CMakeFiles/safety_gencpp.dir/progress.make + +safety/CMakeFiles/safety_gencpp: + +safety_gencpp: safety/CMakeFiles/safety_gencpp +safety_gencpp: safety/CMakeFiles/safety_gencpp.dir/build.make +.PHONY : safety_gencpp + +# Rule to build all files generated by this target. +safety/CMakeFiles/safety_gencpp.dir/build: safety_gencpp +.PHONY : safety/CMakeFiles/safety_gencpp.dir/build + +safety/CMakeFiles/safety_gencpp.dir/clean: + cd /home/lab1_5/ws/ws_linux/build/safety && $(CMAKE_COMMAND) -P CMakeFiles/safety_gencpp.dir/cmake_clean.cmake +.PHONY : safety/CMakeFiles/safety_gencpp.dir/clean + +safety/CMakeFiles/safety_gencpp.dir/depend: + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/lab1_5/ws/ws_linux/src /home/lab1_5/ws/ws_linux/src/safety /home/lab1_5/ws/ws_linux/build /home/lab1_5/ws/ws_linux/build/safety /home/lab1_5/ws/ws_linux/build/safety/CMakeFiles/safety_gencpp.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : safety/CMakeFiles/safety_gencpp.dir/depend + diff --git a/Legacy/ws_linux/build/safety/CMakeFiles/safety_gencpp.dir/cmake_clean.cmake b/Legacy/ws_linux/build/safety/CMakeFiles/safety_gencpp.dir/cmake_clean.cmake new file mode 100644 index 0000000..5994f9d --- /dev/null +++ b/Legacy/ws_linux/build/safety/CMakeFiles/safety_gencpp.dir/cmake_clean.cmake @@ -0,0 +1,8 @@ +FILE(REMOVE_RECURSE + "CMakeFiles/safety_gencpp" +) + +# Per-language clean rules from dependency scanning. +FOREACH(lang) + INCLUDE(CMakeFiles/safety_gencpp.dir/cmake_clean_${lang}.cmake OPTIONAL) +ENDFOREACH(lang) diff --git a/Legacy/ws_linux/build/safety/CMakeFiles/safety_gencpp.dir/progress.make b/Legacy/ws_linux/build/safety/CMakeFiles/safety_gencpp.dir/progress.make new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/Legacy/ws_linux/build/safety/CMakeFiles/safety_gencpp.dir/progress.make @@ -0,0 +1 @@ + diff --git a/Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages.dir/DependInfo.cmake b/Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages.dir/DependInfo.cmake new file mode 100644 index 0000000..a7fba27 --- /dev/null +++ b/Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages.dir/DependInfo.cmake @@ -0,0 +1,15 @@ +# The set of languages for which implicit dependencies are needed: +SET(CMAKE_DEPENDS_LANGUAGES + ) +# The set of files for implicit dependencies of each language: + +# Preprocessor definitions for this target. +SET(CMAKE_TARGET_DEFINITIONS + "ROS_BUILD_SHARED_LIBS=1" + "ROS_PACKAGE_NAME=\"safety\"" + "ROSCONSOLE_BACKEND_LOG4CXX" + ) + +# Targets to which this target links. +SET(CMAKE_TARGET_LINKED_INFO_FILES + ) diff --git a/Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages.dir/build.make b/Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages.dir/build.make new file mode 100644 index 0000000..63419e2 --- /dev/null +++ b/Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages.dir/build.make @@ -0,0 +1,62 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/lab1_5/ws/ws_linux/src + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/lab1_5/ws/ws_linux/build + +# Utility rule file for safety_generate_messages. + +# Include the progress variables for this target. +include safety/CMakeFiles/safety_generate_messages.dir/progress.make + +safety/CMakeFiles/safety_generate_messages: + +safety_generate_messages: safety/CMakeFiles/safety_generate_messages +safety_generate_messages: safety/CMakeFiles/safety_generate_messages.dir/build.make +.PHONY : safety_generate_messages + +# Rule to build all files generated by this target. +safety/CMakeFiles/safety_generate_messages.dir/build: safety_generate_messages +.PHONY : safety/CMakeFiles/safety_generate_messages.dir/build + +safety/CMakeFiles/safety_generate_messages.dir/clean: + cd /home/lab1_5/ws/ws_linux/build/safety && $(CMAKE_COMMAND) -P CMakeFiles/safety_generate_messages.dir/cmake_clean.cmake +.PHONY : safety/CMakeFiles/safety_generate_messages.dir/clean + +safety/CMakeFiles/safety_generate_messages.dir/depend: + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/lab1_5/ws/ws_linux/src /home/lab1_5/ws/ws_linux/src/safety /home/lab1_5/ws/ws_linux/build /home/lab1_5/ws/ws_linux/build/safety /home/lab1_5/ws/ws_linux/build/safety/CMakeFiles/safety_generate_messages.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : safety/CMakeFiles/safety_generate_messages.dir/depend + diff --git a/Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages.dir/cmake_clean.cmake b/Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages.dir/cmake_clean.cmake new file mode 100644 index 0000000..05745ed --- /dev/null +++ b/Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages.dir/cmake_clean.cmake @@ -0,0 +1,8 @@ +FILE(REMOVE_RECURSE + "CMakeFiles/safety_generate_messages" +) + +# Per-language clean rules from dependency scanning. +FOREACH(lang) + INCLUDE(CMakeFiles/safety_generate_messages.dir/cmake_clean_${lang}.cmake OPTIONAL) +ENDFOREACH(lang) diff --git a/Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages.dir/depend.internal b/Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages.dir/depend.internal new file mode 100644 index 0000000..38eae05 --- /dev/null +++ b/Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages.dir/depend.internal @@ -0,0 +1,3 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + diff --git a/Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages.dir/depend.make b/Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages.dir/depend.make new file mode 100644 index 0000000..38eae05 --- /dev/null +++ b/Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages.dir/depend.make @@ -0,0 +1,3 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + diff --git a/Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages.dir/progress.make b/Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages.dir/progress.make new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages.dir/progress.make @@ -0,0 +1 @@ + diff --git a/Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages_cpp.dir/DependInfo.cmake b/Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages_cpp.dir/DependInfo.cmake new file mode 100644 index 0000000..a7fba27 --- /dev/null +++ b/Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages_cpp.dir/DependInfo.cmake @@ -0,0 +1,15 @@ +# The set of languages for which implicit dependencies are needed: +SET(CMAKE_DEPENDS_LANGUAGES + ) +# The set of files for implicit dependencies of each language: + +# Preprocessor definitions for this target. +SET(CMAKE_TARGET_DEFINITIONS + "ROS_BUILD_SHARED_LIBS=1" + "ROS_PACKAGE_NAME=\"safety\"" + "ROSCONSOLE_BACKEND_LOG4CXX" + ) + +# Targets to which this target links. +SET(CMAKE_TARGET_LINKED_INFO_FILES + ) diff --git a/Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages_cpp.dir/build.make b/Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages_cpp.dir/build.make new file mode 100644 index 0000000..8ba7291 --- /dev/null +++ b/Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages_cpp.dir/build.make @@ -0,0 +1,62 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/lab1_5/ws/ws_linux/src + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/lab1_5/ws/ws_linux/build + +# Utility rule file for safety_generate_messages_cpp. + +# Include the progress variables for this target. +include safety/CMakeFiles/safety_generate_messages_cpp.dir/progress.make + +safety/CMakeFiles/safety_generate_messages_cpp: + +safety_generate_messages_cpp: safety/CMakeFiles/safety_generate_messages_cpp +safety_generate_messages_cpp: safety/CMakeFiles/safety_generate_messages_cpp.dir/build.make +.PHONY : safety_generate_messages_cpp + +# Rule to build all files generated by this target. +safety/CMakeFiles/safety_generate_messages_cpp.dir/build: safety_generate_messages_cpp +.PHONY : safety/CMakeFiles/safety_generate_messages_cpp.dir/build + +safety/CMakeFiles/safety_generate_messages_cpp.dir/clean: + cd /home/lab1_5/ws/ws_linux/build/safety && $(CMAKE_COMMAND) -P CMakeFiles/safety_generate_messages_cpp.dir/cmake_clean.cmake +.PHONY : safety/CMakeFiles/safety_generate_messages_cpp.dir/clean + +safety/CMakeFiles/safety_generate_messages_cpp.dir/depend: + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/lab1_5/ws/ws_linux/src /home/lab1_5/ws/ws_linux/src/safety /home/lab1_5/ws/ws_linux/build /home/lab1_5/ws/ws_linux/build/safety /home/lab1_5/ws/ws_linux/build/safety/CMakeFiles/safety_generate_messages_cpp.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : safety/CMakeFiles/safety_generate_messages_cpp.dir/depend + diff --git a/Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages_cpp.dir/cmake_clean.cmake b/Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages_cpp.dir/cmake_clean.cmake new file mode 100644 index 0000000..5c27385 --- /dev/null +++ b/Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages_cpp.dir/cmake_clean.cmake @@ -0,0 +1,8 @@ +FILE(REMOVE_RECURSE + "CMakeFiles/safety_generate_messages_cpp" +) + +# Per-language clean rules from dependency scanning. +FOREACH(lang) + INCLUDE(CMakeFiles/safety_generate_messages_cpp.dir/cmake_clean_${lang}.cmake OPTIONAL) +ENDFOREACH(lang) diff --git a/Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages_cpp.dir/depend.internal b/Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages_cpp.dir/depend.internal new file mode 100644 index 0000000..38eae05 --- /dev/null +++ b/Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages_cpp.dir/depend.internal @@ -0,0 +1,3 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + diff --git a/Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages_cpp.dir/depend.make b/Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages_cpp.dir/depend.make new file mode 100644 index 0000000..38eae05 --- /dev/null +++ b/Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages_cpp.dir/depend.make @@ -0,0 +1,3 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + diff --git a/Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages_cpp.dir/progress.make b/Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages_cpp.dir/progress.make new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages_cpp.dir/progress.make @@ -0,0 +1 @@ + diff --git a/Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages_lisp.dir/DependInfo.cmake b/Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages_lisp.dir/DependInfo.cmake new file mode 100644 index 0000000..a7fba27 --- /dev/null +++ b/Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages_lisp.dir/DependInfo.cmake @@ -0,0 +1,15 @@ +# The set of languages for which implicit dependencies are needed: +SET(CMAKE_DEPENDS_LANGUAGES + ) +# The set of files for implicit dependencies of each language: + +# Preprocessor definitions for this target. +SET(CMAKE_TARGET_DEFINITIONS + "ROS_BUILD_SHARED_LIBS=1" + "ROS_PACKAGE_NAME=\"safety\"" + "ROSCONSOLE_BACKEND_LOG4CXX" + ) + +# Targets to which this target links. +SET(CMAKE_TARGET_LINKED_INFO_FILES + ) diff --git a/Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages_lisp.dir/build.make b/Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages_lisp.dir/build.make new file mode 100644 index 0000000..cac976b --- /dev/null +++ b/Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages_lisp.dir/build.make @@ -0,0 +1,62 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/lab1_5/ws/ws_linux/src + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/lab1_5/ws/ws_linux/build + +# Utility rule file for safety_generate_messages_lisp. + +# Include the progress variables for this target. +include safety/CMakeFiles/safety_generate_messages_lisp.dir/progress.make + +safety/CMakeFiles/safety_generate_messages_lisp: + +safety_generate_messages_lisp: safety/CMakeFiles/safety_generate_messages_lisp +safety_generate_messages_lisp: safety/CMakeFiles/safety_generate_messages_lisp.dir/build.make +.PHONY : safety_generate_messages_lisp + +# Rule to build all files generated by this target. +safety/CMakeFiles/safety_generate_messages_lisp.dir/build: safety_generate_messages_lisp +.PHONY : safety/CMakeFiles/safety_generate_messages_lisp.dir/build + +safety/CMakeFiles/safety_generate_messages_lisp.dir/clean: + cd /home/lab1_5/ws/ws_linux/build/safety && $(CMAKE_COMMAND) -P CMakeFiles/safety_generate_messages_lisp.dir/cmake_clean.cmake +.PHONY : safety/CMakeFiles/safety_generate_messages_lisp.dir/clean + +safety/CMakeFiles/safety_generate_messages_lisp.dir/depend: + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/lab1_5/ws/ws_linux/src /home/lab1_5/ws/ws_linux/src/safety /home/lab1_5/ws/ws_linux/build /home/lab1_5/ws/ws_linux/build/safety /home/lab1_5/ws/ws_linux/build/safety/CMakeFiles/safety_generate_messages_lisp.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : safety/CMakeFiles/safety_generate_messages_lisp.dir/depend + diff --git a/Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages_lisp.dir/cmake_clean.cmake b/Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages_lisp.dir/cmake_clean.cmake new file mode 100644 index 0000000..4bac217 --- /dev/null +++ b/Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages_lisp.dir/cmake_clean.cmake @@ -0,0 +1,8 @@ +FILE(REMOVE_RECURSE + "CMakeFiles/safety_generate_messages_lisp" +) + +# Per-language clean rules from dependency scanning. +FOREACH(lang) + INCLUDE(CMakeFiles/safety_generate_messages_lisp.dir/cmake_clean_${lang}.cmake OPTIONAL) +ENDFOREACH(lang) diff --git a/Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages_lisp.dir/depend.internal b/Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages_lisp.dir/depend.internal new file mode 100644 index 0000000..38eae05 --- /dev/null +++ b/Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages_lisp.dir/depend.internal @@ -0,0 +1,3 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + diff --git a/Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages_lisp.dir/depend.make b/Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages_lisp.dir/depend.make new file mode 100644 index 0000000..38eae05 --- /dev/null +++ b/Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages_lisp.dir/depend.make @@ -0,0 +1,3 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + diff --git a/Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages_lisp.dir/progress.make b/Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages_lisp.dir/progress.make new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages_lisp.dir/progress.make @@ -0,0 +1 @@ + diff --git a/Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages_py.dir/DependInfo.cmake b/Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages_py.dir/DependInfo.cmake new file mode 100644 index 0000000..a7fba27 --- /dev/null +++ b/Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages_py.dir/DependInfo.cmake @@ -0,0 +1,15 @@ +# The set of languages for which implicit dependencies are needed: +SET(CMAKE_DEPENDS_LANGUAGES + ) +# The set of files for implicit dependencies of each language: + +# Preprocessor definitions for this target. +SET(CMAKE_TARGET_DEFINITIONS + "ROS_BUILD_SHARED_LIBS=1" + "ROS_PACKAGE_NAME=\"safety\"" + "ROSCONSOLE_BACKEND_LOG4CXX" + ) + +# Targets to which this target links. +SET(CMAKE_TARGET_LINKED_INFO_FILES + ) diff --git a/Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages_py.dir/build.make b/Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages_py.dir/build.make new file mode 100644 index 0000000..456577a --- /dev/null +++ b/Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages_py.dir/build.make @@ -0,0 +1,62 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/lab1_5/ws/ws_linux/src + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/lab1_5/ws/ws_linux/build + +# Utility rule file for safety_generate_messages_py. + +# Include the progress variables for this target. +include safety/CMakeFiles/safety_generate_messages_py.dir/progress.make + +safety/CMakeFiles/safety_generate_messages_py: + +safety_generate_messages_py: safety/CMakeFiles/safety_generate_messages_py +safety_generate_messages_py: safety/CMakeFiles/safety_generate_messages_py.dir/build.make +.PHONY : safety_generate_messages_py + +# Rule to build all files generated by this target. +safety/CMakeFiles/safety_generate_messages_py.dir/build: safety_generate_messages_py +.PHONY : safety/CMakeFiles/safety_generate_messages_py.dir/build + +safety/CMakeFiles/safety_generate_messages_py.dir/clean: + cd /home/lab1_5/ws/ws_linux/build/safety && $(CMAKE_COMMAND) -P CMakeFiles/safety_generate_messages_py.dir/cmake_clean.cmake +.PHONY : safety/CMakeFiles/safety_generate_messages_py.dir/clean + +safety/CMakeFiles/safety_generate_messages_py.dir/depend: + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/lab1_5/ws/ws_linux/src /home/lab1_5/ws/ws_linux/src/safety /home/lab1_5/ws/ws_linux/build /home/lab1_5/ws/ws_linux/build/safety /home/lab1_5/ws/ws_linux/build/safety/CMakeFiles/safety_generate_messages_py.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : safety/CMakeFiles/safety_generate_messages_py.dir/depend + diff --git a/Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages_py.dir/cmake_clean.cmake b/Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages_py.dir/cmake_clean.cmake new file mode 100644 index 0000000..5b52075 --- /dev/null +++ b/Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages_py.dir/cmake_clean.cmake @@ -0,0 +1,8 @@ +FILE(REMOVE_RECURSE + "CMakeFiles/safety_generate_messages_py" +) + +# Per-language clean rules from dependency scanning. +FOREACH(lang) + INCLUDE(CMakeFiles/safety_generate_messages_py.dir/cmake_clean_${lang}.cmake OPTIONAL) +ENDFOREACH(lang) diff --git a/Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages_py.dir/depend.internal b/Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages_py.dir/depend.internal new file mode 100644 index 0000000..38eae05 --- /dev/null +++ b/Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages_py.dir/depend.internal @@ -0,0 +1,3 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + diff --git a/Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages_py.dir/depend.make b/Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages_py.dir/depend.make new file mode 100644 index 0000000..38eae05 --- /dev/null +++ b/Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages_py.dir/depend.make @@ -0,0 +1,3 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + diff --git a/Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages_py.dir/progress.make b/Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages_py.dir/progress.make new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/Legacy/ws_linux/build/safety/CMakeFiles/safety_generate_messages_py.dir/progress.make @@ -0,0 +1 @@ + diff --git a/Legacy/ws_linux/build/safety/CMakeFiles/safety_genlisp.dir/DependInfo.cmake b/Legacy/ws_linux/build/safety/CMakeFiles/safety_genlisp.dir/DependInfo.cmake new file mode 100644 index 0000000..a7fba27 --- /dev/null +++ b/Legacy/ws_linux/build/safety/CMakeFiles/safety_genlisp.dir/DependInfo.cmake @@ -0,0 +1,15 @@ +# The set of languages for which implicit dependencies are needed: +SET(CMAKE_DEPENDS_LANGUAGES + ) +# The set of files for implicit dependencies of each language: + +# Preprocessor definitions for this target. +SET(CMAKE_TARGET_DEFINITIONS + "ROS_BUILD_SHARED_LIBS=1" + "ROS_PACKAGE_NAME=\"safety\"" + "ROSCONSOLE_BACKEND_LOG4CXX" + ) + +# Targets to which this target links. +SET(CMAKE_TARGET_LINKED_INFO_FILES + ) diff --git a/Legacy/ws_linux/build/safety/CMakeFiles/safety_genlisp.dir/build.make b/Legacy/ws_linux/build/safety/CMakeFiles/safety_genlisp.dir/build.make new file mode 100644 index 0000000..7bd7962 --- /dev/null +++ b/Legacy/ws_linux/build/safety/CMakeFiles/safety_genlisp.dir/build.make @@ -0,0 +1,62 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/lab1_5/ws/ws_linux/src + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/lab1_5/ws/ws_linux/build + +# Utility rule file for safety_genlisp. + +# Include the progress variables for this target. +include safety/CMakeFiles/safety_genlisp.dir/progress.make + +safety/CMakeFiles/safety_genlisp: + +safety_genlisp: safety/CMakeFiles/safety_genlisp +safety_genlisp: safety/CMakeFiles/safety_genlisp.dir/build.make +.PHONY : safety_genlisp + +# Rule to build all files generated by this target. +safety/CMakeFiles/safety_genlisp.dir/build: safety_genlisp +.PHONY : safety/CMakeFiles/safety_genlisp.dir/build + +safety/CMakeFiles/safety_genlisp.dir/clean: + cd /home/lab1_5/ws/ws_linux/build/safety && $(CMAKE_COMMAND) -P CMakeFiles/safety_genlisp.dir/cmake_clean.cmake +.PHONY : safety/CMakeFiles/safety_genlisp.dir/clean + +safety/CMakeFiles/safety_genlisp.dir/depend: + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/lab1_5/ws/ws_linux/src /home/lab1_5/ws/ws_linux/src/safety /home/lab1_5/ws/ws_linux/build /home/lab1_5/ws/ws_linux/build/safety /home/lab1_5/ws/ws_linux/build/safety/CMakeFiles/safety_genlisp.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : safety/CMakeFiles/safety_genlisp.dir/depend + diff --git a/Legacy/ws_linux/build/safety/CMakeFiles/safety_genlisp.dir/cmake_clean.cmake b/Legacy/ws_linux/build/safety/CMakeFiles/safety_genlisp.dir/cmake_clean.cmake new file mode 100644 index 0000000..fa46b02 --- /dev/null +++ b/Legacy/ws_linux/build/safety/CMakeFiles/safety_genlisp.dir/cmake_clean.cmake @@ -0,0 +1,8 @@ +FILE(REMOVE_RECURSE + "CMakeFiles/safety_genlisp" +) + +# Per-language clean rules from dependency scanning. +FOREACH(lang) + INCLUDE(CMakeFiles/safety_genlisp.dir/cmake_clean_${lang}.cmake OPTIONAL) +ENDFOREACH(lang) diff --git a/Legacy/ws_linux/build/safety/CMakeFiles/safety_genlisp.dir/progress.make b/Legacy/ws_linux/build/safety/CMakeFiles/safety_genlisp.dir/progress.make new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/Legacy/ws_linux/build/safety/CMakeFiles/safety_genlisp.dir/progress.make @@ -0,0 +1 @@ + diff --git a/Legacy/ws_linux/build/safety/CMakeFiles/safety_genpy.dir/DependInfo.cmake b/Legacy/ws_linux/build/safety/CMakeFiles/safety_genpy.dir/DependInfo.cmake new file mode 100644 index 0000000..a7fba27 --- /dev/null +++ b/Legacy/ws_linux/build/safety/CMakeFiles/safety_genpy.dir/DependInfo.cmake @@ -0,0 +1,15 @@ +# The set of languages for which implicit dependencies are needed: +SET(CMAKE_DEPENDS_LANGUAGES + ) +# The set of files for implicit dependencies of each language: + +# Preprocessor definitions for this target. +SET(CMAKE_TARGET_DEFINITIONS + "ROS_BUILD_SHARED_LIBS=1" + "ROS_PACKAGE_NAME=\"safety\"" + "ROSCONSOLE_BACKEND_LOG4CXX" + ) + +# Targets to which this target links. +SET(CMAKE_TARGET_LINKED_INFO_FILES + ) diff --git a/Legacy/ws_linux/build/safety/CMakeFiles/safety_genpy.dir/build.make b/Legacy/ws_linux/build/safety/CMakeFiles/safety_genpy.dir/build.make new file mode 100644 index 0000000..ac1e40d --- /dev/null +++ b/Legacy/ws_linux/build/safety/CMakeFiles/safety_genpy.dir/build.make @@ -0,0 +1,62 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/lab1_5/ws/ws_linux/src + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/lab1_5/ws/ws_linux/build + +# Utility rule file for safety_genpy. + +# Include the progress variables for this target. +include safety/CMakeFiles/safety_genpy.dir/progress.make + +safety/CMakeFiles/safety_genpy: + +safety_genpy: safety/CMakeFiles/safety_genpy +safety_genpy: safety/CMakeFiles/safety_genpy.dir/build.make +.PHONY : safety_genpy + +# Rule to build all files generated by this target. +safety/CMakeFiles/safety_genpy.dir/build: safety_genpy +.PHONY : safety/CMakeFiles/safety_genpy.dir/build + +safety/CMakeFiles/safety_genpy.dir/clean: + cd /home/lab1_5/ws/ws_linux/build/safety && $(CMAKE_COMMAND) -P CMakeFiles/safety_genpy.dir/cmake_clean.cmake +.PHONY : safety/CMakeFiles/safety_genpy.dir/clean + +safety/CMakeFiles/safety_genpy.dir/depend: + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/lab1_5/ws/ws_linux/src /home/lab1_5/ws/ws_linux/src/safety /home/lab1_5/ws/ws_linux/build /home/lab1_5/ws/ws_linux/build/safety /home/lab1_5/ws/ws_linux/build/safety/CMakeFiles/safety_genpy.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : safety/CMakeFiles/safety_genpy.dir/depend + diff --git a/Legacy/ws_linux/build/safety/CMakeFiles/safety_genpy.dir/cmake_clean.cmake b/Legacy/ws_linux/build/safety/CMakeFiles/safety_genpy.dir/cmake_clean.cmake new file mode 100644 index 0000000..003437e --- /dev/null +++ b/Legacy/ws_linux/build/safety/CMakeFiles/safety_genpy.dir/cmake_clean.cmake @@ -0,0 +1,8 @@ +FILE(REMOVE_RECURSE + "CMakeFiles/safety_genpy" +) + +# Per-language clean rules from dependency scanning. +FOREACH(lang) + INCLUDE(CMakeFiles/safety_genpy.dir/cmake_clean_${lang}.cmake OPTIONAL) +ENDFOREACH(lang) diff --git a/Legacy/ws_linux/build/safety/CMakeFiles/safety_genpy.dir/progress.make b/Legacy/ws_linux/build/safety/CMakeFiles/safety_genpy.dir/progress.make new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/Legacy/ws_linux/build/safety/CMakeFiles/safety_genpy.dir/progress.make @@ -0,0 +1 @@ + diff --git a/Legacy/ws_linux/build/safety/CTestTestfile.cmake b/Legacy/ws_linux/build/safety/CTestTestfile.cmake new file mode 100644 index 0000000..9c287eb --- /dev/null +++ b/Legacy/ws_linux/build/safety/CTestTestfile.cmake @@ -0,0 +1,6 @@ +# CMake generated Testfile for +# Source directory: /home/lab1_5/ws/ws_linux/src/safety +# Build directory: /home/lab1_5/ws/ws_linux/build/safety +# +# This file includes the relevent testing commands required for +# testing this directory and lists subdirectories to be tested as well. diff --git a/Legacy/ws_linux/build/safety/Makefile b/Legacy/ws_linux/build/safety/Makefile new file mode 100644 index 0000000..b6e3cb8 --- /dev/null +++ b/Legacy/ws_linux/build/safety/Makefile @@ -0,0 +1,322 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +# Default target executed when no arguments are given to make. +default_target: all +.PHONY : default_target + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/lab1_5/ws/ws_linux/src + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/lab1_5/ws/ws_linux/build + +#============================================================================= +# Targets provided globally by CMake. + +# Special rule for the target edit_cache +edit_cache: + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running interactive CMake command-line interface..." + /usr/bin/cmake -i . +.PHONY : edit_cache + +# Special rule for the target edit_cache +edit_cache/fast: edit_cache +.PHONY : edit_cache/fast + +# Special rule for the target install +install: preinstall + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Install the project..." + /usr/bin/cmake -P cmake_install.cmake +.PHONY : install + +# Special rule for the target install +install/fast: preinstall/fast + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Install the project..." + /usr/bin/cmake -P cmake_install.cmake +.PHONY : install/fast + +# Special rule for the target install/local +install/local: preinstall + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Installing only the local directory..." + /usr/bin/cmake -DCMAKE_INSTALL_LOCAL_ONLY=1 -P cmake_install.cmake +.PHONY : install/local + +# Special rule for the target install/local +install/local/fast: install/local +.PHONY : install/local/fast + +# Special rule for the target install/strip +install/strip: preinstall + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Installing the project stripped..." + /usr/bin/cmake -DCMAKE_INSTALL_DO_STRIP=1 -P cmake_install.cmake +.PHONY : install/strip + +# Special rule for the target install/strip +install/strip/fast: install/strip +.PHONY : install/strip/fast + +# Special rule for the target list_install_components +list_install_components: + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Available install components are: \"Unspecified\"" +.PHONY : list_install_components + +# Special rule for the target list_install_components +list_install_components/fast: list_install_components +.PHONY : list_install_components/fast + +# Special rule for the target rebuild_cache +rebuild_cache: + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running CMake to regenerate build system..." + /usr/bin/cmake -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) +.PHONY : rebuild_cache + +# Special rule for the target rebuild_cache +rebuild_cache/fast: rebuild_cache +.PHONY : rebuild_cache/fast + +# Special rule for the target test +test: + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running tests..." + /usr/bin/ctest --force-new-ctest-process $(ARGS) +.PHONY : test + +# Special rule for the target test +test/fast: test +.PHONY : test/fast + +# The main all target +all: cmake_check_build_system + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -E cmake_progress_start /home/lab1_5/ws/ws_linux/build/CMakeFiles /home/lab1_5/ws/ws_linux/build/safety/CMakeFiles/progress.marks + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 safety/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/lab1_5/ws/ws_linux/build/CMakeFiles 0 +.PHONY : all + +# The main clean target +clean: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 safety/clean +.PHONY : clean + +# The main clean target +clean/fast: clean +.PHONY : clean/fast + +# Prepare targets for installation. +preinstall: all + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 safety/preinstall +.PHONY : preinstall + +# Prepare targets for installation. +preinstall/fast: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 safety/preinstall +.PHONY : preinstall/fast + +# clear depends +depend: + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 1 +.PHONY : depend + +# Convenience name for target. +safety/CMakeFiles/cloud_reader.dir/rule: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 safety/CMakeFiles/cloud_reader.dir/rule +.PHONY : safety/CMakeFiles/cloud_reader.dir/rule + +# Convenience name for target. +cloud_reader: safety/CMakeFiles/cloud_reader.dir/rule +.PHONY : cloud_reader + +# fast build rule for target. +cloud_reader/fast: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f safety/CMakeFiles/cloud_reader.dir/build.make safety/CMakeFiles/cloud_reader.dir/build +.PHONY : cloud_reader/fast + +# Convenience name for target. +safety/CMakeFiles/safety_gencpp.dir/rule: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 safety/CMakeFiles/safety_gencpp.dir/rule +.PHONY : safety/CMakeFiles/safety_gencpp.dir/rule + +# Convenience name for target. +safety_gencpp: safety/CMakeFiles/safety_gencpp.dir/rule +.PHONY : safety_gencpp + +# fast build rule for target. +safety_gencpp/fast: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f safety/CMakeFiles/safety_gencpp.dir/build.make safety/CMakeFiles/safety_gencpp.dir/build +.PHONY : safety_gencpp/fast + +# Convenience name for target. +safety/CMakeFiles/safety_generate_messages.dir/rule: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 safety/CMakeFiles/safety_generate_messages.dir/rule +.PHONY : safety/CMakeFiles/safety_generate_messages.dir/rule + +# Convenience name for target. +safety_generate_messages: safety/CMakeFiles/safety_generate_messages.dir/rule +.PHONY : safety_generate_messages + +# fast build rule for target. +safety_generate_messages/fast: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f safety/CMakeFiles/safety_generate_messages.dir/build.make safety/CMakeFiles/safety_generate_messages.dir/build +.PHONY : safety_generate_messages/fast + +# Convenience name for target. +safety/CMakeFiles/safety_generate_messages_cpp.dir/rule: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 safety/CMakeFiles/safety_generate_messages_cpp.dir/rule +.PHONY : safety/CMakeFiles/safety_generate_messages_cpp.dir/rule + +# Convenience name for target. +safety_generate_messages_cpp: safety/CMakeFiles/safety_generate_messages_cpp.dir/rule +.PHONY : safety_generate_messages_cpp + +# fast build rule for target. +safety_generate_messages_cpp/fast: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f safety/CMakeFiles/safety_generate_messages_cpp.dir/build.make safety/CMakeFiles/safety_generate_messages_cpp.dir/build +.PHONY : safety_generate_messages_cpp/fast + +# Convenience name for target. +safety/CMakeFiles/safety_generate_messages_lisp.dir/rule: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 safety/CMakeFiles/safety_generate_messages_lisp.dir/rule +.PHONY : safety/CMakeFiles/safety_generate_messages_lisp.dir/rule + +# Convenience name for target. +safety_generate_messages_lisp: safety/CMakeFiles/safety_generate_messages_lisp.dir/rule +.PHONY : safety_generate_messages_lisp + +# fast build rule for target. +safety_generate_messages_lisp/fast: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f safety/CMakeFiles/safety_generate_messages_lisp.dir/build.make safety/CMakeFiles/safety_generate_messages_lisp.dir/build +.PHONY : safety_generate_messages_lisp/fast + +# Convenience name for target. +safety/CMakeFiles/safety_generate_messages_py.dir/rule: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 safety/CMakeFiles/safety_generate_messages_py.dir/rule +.PHONY : safety/CMakeFiles/safety_generate_messages_py.dir/rule + +# Convenience name for target. +safety_generate_messages_py: safety/CMakeFiles/safety_generate_messages_py.dir/rule +.PHONY : safety_generate_messages_py + +# fast build rule for target. +safety_generate_messages_py/fast: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f safety/CMakeFiles/safety_generate_messages_py.dir/build.make safety/CMakeFiles/safety_generate_messages_py.dir/build +.PHONY : safety_generate_messages_py/fast + +# Convenience name for target. +safety/CMakeFiles/safety_genlisp.dir/rule: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 safety/CMakeFiles/safety_genlisp.dir/rule +.PHONY : safety/CMakeFiles/safety_genlisp.dir/rule + +# Convenience name for target. +safety_genlisp: safety/CMakeFiles/safety_genlisp.dir/rule +.PHONY : safety_genlisp + +# fast build rule for target. +safety_genlisp/fast: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f safety/CMakeFiles/safety_genlisp.dir/build.make safety/CMakeFiles/safety_genlisp.dir/build +.PHONY : safety_genlisp/fast + +# Convenience name for target. +safety/CMakeFiles/safety_genpy.dir/rule: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 safety/CMakeFiles/safety_genpy.dir/rule +.PHONY : safety/CMakeFiles/safety_genpy.dir/rule + +# Convenience name for target. +safety_genpy: safety/CMakeFiles/safety_genpy.dir/rule +.PHONY : safety_genpy + +# fast build rule for target. +safety_genpy/fast: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f safety/CMakeFiles/safety_genpy.dir/build.make safety/CMakeFiles/safety_genpy.dir/build +.PHONY : safety_genpy/fast + +src/cloud_reader.o: src/cloud_reader.cpp.o +.PHONY : src/cloud_reader.o + +# target to build an object file +src/cloud_reader.cpp.o: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f safety/CMakeFiles/cloud_reader.dir/build.make safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.o +.PHONY : src/cloud_reader.cpp.o + +src/cloud_reader.i: src/cloud_reader.cpp.i +.PHONY : src/cloud_reader.i + +# target to preprocess a source file +src/cloud_reader.cpp.i: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f safety/CMakeFiles/cloud_reader.dir/build.make safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.i +.PHONY : src/cloud_reader.cpp.i + +src/cloud_reader.s: src/cloud_reader.cpp.s +.PHONY : src/cloud_reader.s + +# target to generate assembly for a file +src/cloud_reader.cpp.s: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f safety/CMakeFiles/cloud_reader.dir/build.make safety/CMakeFiles/cloud_reader.dir/src/cloud_reader.cpp.s +.PHONY : src/cloud_reader.cpp.s + +# Help Target +help: + @echo "The following are some of the valid targets for this Makefile:" + @echo "... all (the default if no target is provided)" + @echo "... clean" + @echo "... depend" + @echo "... cloud_reader" + @echo "... edit_cache" + @echo "... install" + @echo "... install/local" + @echo "... install/strip" + @echo "... list_install_components" + @echo "... rebuild_cache" + @echo "... safety_gencpp" + @echo "... safety_generate_messages" + @echo "... safety_generate_messages_cpp" + @echo "... safety_generate_messages_lisp" + @echo "... safety_generate_messages_py" + @echo "... safety_genlisp" + @echo "... safety_genpy" + @echo "... test" + @echo "... src/cloud_reader.o" + @echo "... src/cloud_reader.i" + @echo "... src/cloud_reader.s" +.PHONY : help + + + +#============================================================================= +# Special targets to cleanup operation of make. + +# Special rule to run CMake to check the build system integrity. +# No rule that depends on this can have commands that come from listfiles +# because they might be regenerated. +cmake_check_build_system: + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 0 +.PHONY : cmake_check_build_system + diff --git a/Legacy/ws_linux/build/safety/catkin_generated/installspace/safety-msg-extras.cmake b/Legacy/ws_linux/build/safety/catkin_generated/installspace/safety-msg-extras.cmake new file mode 100644 index 0000000..c1b75eb --- /dev/null +++ b/Legacy/ws_linux/build/safety/catkin_generated/installspace/safety-msg-extras.cmake @@ -0,0 +1,2 @@ +set(safety_MESSAGE_FILES "") +set(safety_SERVICE_FILES "") diff --git a/Legacy/ws_linux/build/safety/catkin_generated/installspace/safety-msg-paths-context.py b/Legacy/ws_linux/build/safety/catkin_generated/installspace/safety-msg-paths-context.py new file mode 100644 index 0000000..734ff24 --- /dev/null +++ b/Legacy/ws_linux/build/safety/catkin_generated/installspace/safety-msg-paths-context.py @@ -0,0 +1,8 @@ +# generated from genmsg/cmake/pkg-msg-paths.context.in + +DEVELSPACE = 'FALSE' == 'TRUE' +INSTALLSPACE = 'TRUE' == 'TRUE' + +PROJECT_NAME = 'safety' +PKG_MSG_INCLUDE_DIRS = '' +ARG_DEPENDENCIES = 'std_msgs' diff --git a/Legacy/ws_linux/build/safety/catkin_generated/installspace/safety-msg-paths.cmake b/Legacy/ws_linux/build/safety/catkin_generated/installspace/safety-msg-paths.cmake new file mode 100644 index 0000000..83dcf9c --- /dev/null +++ b/Legacy/ws_linux/build/safety/catkin_generated/installspace/safety-msg-paths.cmake @@ -0,0 +1,5 @@ +# generated from genmsg/cmake/pkg-msg-paths.cmake.em + +# message include dirs in installspace +_prepend_path("${safety_DIR}/.." "" safety_MSG_INCLUDE_DIRS UNIQUE) +set(safety_MSG_DEPENDENCIES std_msgs) diff --git a/Legacy/ws_linux/build/safety/catkin_generated/installspace/safety.pc b/Legacy/ws_linux/build/safety/catkin_generated/installspace/safety.pc new file mode 100644 index 0000000..e48086e --- /dev/null +++ b/Legacy/ws_linux/build/safety/catkin_generated/installspace/safety.pc @@ -0,0 +1,8 @@ +prefix=/home/lab1_5/ws/ws_linux/install + +Name: safety +Description: Description of safety +Version: 0.2.1 +Cflags: +Libs: -L/home/lab1_5/ws/ws_linux/install/lib -lsafety +Requires: message_runtime roscpp rospy std_msgs rosaria diff --git a/Legacy/ws_linux/build/safety/catkin_generated/installspace/safetyConfig-version.cmake b/Legacy/ws_linux/build/safety/catkin_generated/installspace/safetyConfig-version.cmake new file mode 100644 index 0000000..40ac4c2 --- /dev/null +++ b/Legacy/ws_linux/build/safety/catkin_generated/installspace/safetyConfig-version.cmake @@ -0,0 +1,14 @@ +# generated from catkin/cmake/template/pkgConfig-version.cmake.in +set(PACKAGE_VERSION "0.2.1") + +set(PACKAGE_VERSION_EXACT False) +set(PACKAGE_VERSION_COMPATIBLE False) + +if("${PACKAGE_FIND_VERSION}" VERSION_EQUAL "${PACKAGE_VERSION}") + set(PACKAGE_VERSION_EXACT True) + set(PACKAGE_VERSION_COMPATIBLE True) +endif() + +if("${PACKAGE_FIND_VERSION}" VERSION_LESS "${PACKAGE_VERSION}") + set(PACKAGE_VERSION_COMPATIBLE True) +endif() diff --git a/Legacy/ws_linux/build/safety/catkin_generated/installspace/safetyConfig.cmake b/Legacy/ws_linux/build/safety/catkin_generated/installspace/safetyConfig.cmake new file mode 100644 index 0000000..b914a42 --- /dev/null +++ b/Legacy/ws_linux/build/safety/catkin_generated/installspace/safetyConfig.cmake @@ -0,0 +1,191 @@ +# generated from catkin/cmake/template/pkgConfig.cmake.in + +# append elements to a list and remove existing duplicates from the list +# copied from catkin/cmake/list_append_deduplicate.cmake to keep pkgConfig +# self contained +macro(_list_append_deduplicate listname) + if(NOT "${ARGN}" STREQUAL "") + if(${listname}) + list(REMOVE_ITEM ${listname} ${ARGN}) + endif() + list(APPEND ${listname} ${ARGN}) + endif() +endmacro() + +# append elements to a list if they are not already in the list +# copied from catkin/cmake/list_append_unique.cmake to keep pkgConfig +# self contained +macro(_list_append_unique listname) + foreach(_item ${ARGN}) + list(FIND ${listname} ${_item} _index) + if(_index EQUAL -1) + list(APPEND ${listname} ${_item}) + endif() + endforeach() +endmacro() + +# pack a list of libraries with optional build configuration keywords +# copied from catkin/cmake/catkin_libraries.cmake to keep pkgConfig +# self contained +macro(_pack_libraries_with_build_configuration VAR) + set(${VAR} "") + set(_argn ${ARGN}) + list(LENGTH _argn _count) + set(_index 0) + while(${_index} LESS ${_count}) + list(GET _argn ${_index} lib) + if("${lib}" MATCHES "^debug|optimized|general$") + math(EXPR _index "${_index} + 1") + if(${_index} EQUAL ${_count}) + message(FATAL_ERROR "_pack_libraries_with_build_configuration() the list of libraries '${ARGN}' ends with '${lib}' which is a build configuration keyword and must be followed by a library") + endif() + list(GET _argn ${_index} library) + list(APPEND ${VAR} "${lib}${CATKIN_BUILD_CONFIGURATION_KEYWORD_SEPARATOR}${library}") + else() + list(APPEND ${VAR} "${lib}") + endif() + math(EXPR _index "${_index} + 1") + endwhile() +endmacro() + +# unpack a list of libraries with optional build configuration keyword prefixes +# copied from catkin/cmake/catkin_libraries.cmake to keep pkgConfig +# self contained +macro(_unpack_libraries_with_build_configuration VAR) + set(${VAR} "") + foreach(lib ${ARGN}) + string(REGEX REPLACE "^(debug|optimized|general)${CATKIN_BUILD_CONFIGURATION_KEYWORD_SEPARATOR}(.+)$" "\\1;\\2" lib "${lib}") + list(APPEND ${VAR} "${lib}") + endforeach() +endmacro() + + +if(safety_CONFIG_INCLUDED) + return() +endif() +set(safety_CONFIG_INCLUDED TRUE) + +# set variables for source/devel/install prefixes +if("FALSE" STREQUAL "TRUE") + set(safety_SOURCE_PREFIX /home/lab1_5/ws/ws_linux/src/safety) + set(safety_DEVEL_PREFIX /home/lab1_5/ws/ws_linux/devel) + set(safety_INSTALL_PREFIX "") + set(safety_PREFIX ${safety_DEVEL_PREFIX}) +else() + set(safety_SOURCE_PREFIX "") + set(safety_DEVEL_PREFIX "") + set(safety_INSTALL_PREFIX /home/lab1_5/ws/ws_linux/install) + set(safety_PREFIX ${safety_INSTALL_PREFIX}) +endif() + +# warn when using a deprecated package +if(NOT "" STREQUAL "") + set(_msg "WARNING: package 'safety' is deprecated") + # append custom deprecation text if available + if(NOT "" STREQUAL "TRUE") + set(_msg "${_msg} ()") + endif() + message("${_msg}") +endif() + +# flag project as catkin-based to distinguish if a find_package()-ed project is a catkin project +set(safety_FOUND_CATKIN_PROJECT TRUE) + +if(NOT "" STREQUAL "") + set(safety_INCLUDE_DIRS "") + set(_include_dirs "") + foreach(idir ${_include_dirs}) + if(IS_ABSOLUTE ${idir} AND IS_DIRECTORY ${idir}) + set(include ${idir}) + elseif("${idir}" STREQUAL "include") + get_filename_component(include "${safety_DIR}/../../../include" ABSOLUTE) + if(NOT IS_DIRECTORY ${include}) + message(FATAL_ERROR "Project 'safety' specifies '${idir}' as an include dir, which is not found. It does not exist in '${include}'. Ask the maintainer 'Aleksandra Grzelak ' to fix it.") + endif() + else() + message(FATAL_ERROR "Project 'safety' specifies '${idir}' as an include dir, which is not found. It does neither exist as an absolute directory nor in '/home/lab1_5/ws/ws_linux/install/${idir}'. Ask the maintainer 'Aleksandra Grzelak ' to fix it.") + endif() + _list_append_unique(safety_INCLUDE_DIRS ${include}) + endforeach() +endif() + +set(libraries "safety") +foreach(library ${libraries}) + # keep build configuration keywords, target names and absolute libraries as-is + if("${library}" MATCHES "^debug|optimized|general$") + list(APPEND safety_LIBRARIES ${library}) + elseif(TARGET ${library}) + list(APPEND safety_LIBRARIES ${library}) + elseif(IS_ABSOLUTE ${library}) + list(APPEND safety_LIBRARIES ${library}) + else() + set(lib_path "") + set(lib "${library}-NOTFOUND") + # since the path where the library is found is returned we have to iterate over the paths manually + foreach(path /home/lab1_5/ws/ws_linux/install/lib;/home/lab1_5/ws/ws_linux/devel/lib;/home/lab1_5/ws/ws_xeno/devel/lib;/home/lab1_5/ws/ws_isolated/install_isolated/lib;/opt/ros/hydro/lib) + find_library(lib ${library} + PATHS ${path} + NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH) + if(lib) + set(lib_path ${path}) + break() + endif() + endforeach() + if(lib) + _list_append_unique(safety_LIBRARY_DIRS ${lib_path}) + list(APPEND safety_LIBRARIES ${lib}) + else() + # as a fall back for non-catkin libraries try to search globally + find_library(lib ${library}) + if(NOT lib) + message(FATAL_ERROR "Project '${PROJECT_NAME}' tried to find library '${library}'. The library is neither a target nor built/installed properly. Did you compile project 'safety'? Did you find_package() it before the subdirectory containing its code is included?") + endif() + list(APPEND safety_LIBRARIES ${lib}) + endif() + endif() +endforeach() + +set(safety_EXPORTED_TARGETS "safety_generate_messages_cpp;safety_generate_messages_lisp;safety_generate_messages_py") +# create dummy targets for exported code generation targets to make life of users easier +foreach(t ${safety_EXPORTED_TARGETS}) + if(NOT TARGET ${t}) + add_custom_target(${t}) + endif() +endforeach() + +set(depends "message_runtime;roscpp;rospy;std_msgs;rosaria") +foreach(depend ${depends}) + string(REPLACE " " ";" depend_list ${depend}) + # the package name of the dependency must be kept in a unique variable so that it is not overwritten in recursive calls + list(GET depend_list 0 safety_dep) + list(LENGTH depend_list count) + if(${count} EQUAL 1) + # simple dependencies must only be find_package()-ed once + if(NOT ${safety_dep}_FOUND) + find_package(${safety_dep} REQUIRED) + endif() + else() + # dependencies with components must be find_package()-ed again + list(REMOVE_AT depend_list 0) + find_package(${safety_dep} REQUIRED ${depend_list}) + endif() + _list_append_unique(safety_INCLUDE_DIRS ${${safety_dep}_INCLUDE_DIRS}) + + # merge build configuration keywords with library names to correctly deduplicate + _pack_libraries_with_build_configuration(safety_LIBRARIES ${safety_LIBRARIES}) + _pack_libraries_with_build_configuration(_libraries ${${safety_dep}_LIBRARIES}) + _list_append_deduplicate(safety_LIBRARIES ${_libraries}) + # undo build configuration keyword merging after deduplication + _unpack_libraries_with_build_configuration(safety_LIBRARIES ${safety_LIBRARIES}) + + _list_append_unique(safety_LIBRARY_DIRS ${${safety_dep}_LIBRARY_DIRS}) + list(APPEND safety_EXPORTED_TARGETS ${${safety_dep}_EXPORTED_TARGETS}) +endforeach() + +set(pkg_cfg_extras "safety-msg-extras.cmake") +foreach(extra ${pkg_cfg_extras}) + if(NOT IS_ABSOLUTE ${extra}) + set(extra ${safety_DIR}/${extra}) + endif() + include(${extra}) +endforeach() diff --git a/Legacy/ws_linux/build/safety/catkin_generated/ordered_paths.cmake b/Legacy/ws_linux/build/safety/catkin_generated/ordered_paths.cmake new file mode 100644 index 0000000..3b5d318 --- /dev/null +++ b/Legacy/ws_linux/build/safety/catkin_generated/ordered_paths.cmake @@ -0,0 +1 @@ +set(ORDERED_PATHS "/opt/ros/hydro/lib") \ No newline at end of file diff --git a/Legacy/ws_linux/build/safety/catkin_generated/package.cmake b/Legacy/ws_linux/build/safety/catkin_generated/package.cmake new file mode 100644 index 0000000..43b4ce7 --- /dev/null +++ b/Legacy/ws_linux/build/safety/catkin_generated/package.cmake @@ -0,0 +1,7 @@ +set(_CATKIN_CURRENT_PACKAGE "safety") +set(safety_MAINTAINER "Aleksandra Grzelak ") +set(safety_DEPRECATED "") +set(safety_VERSION "0.2.1") +set(safety_BUILD_DEPENDS "message_generation" "roscpp" "rospy" "std_msgs" "rosaria") +set(safety_RUN_DEPENDS "message_runtime" "roscpp" "rospy" "std_msgs" "rosaria") +set(safety_BUILDTOOL_DEPENDS "catkin") \ No newline at end of file diff --git a/Legacy/ws_linux/build/safety/catkin_generated/pkg.develspace.context.pc.py b/Legacy/ws_linux/build/safety/catkin_generated/pkg.develspace.context.pc.py new file mode 100644 index 0000000..9f303ed --- /dev/null +++ b/Legacy/ws_linux/build/safety/catkin_generated/pkg.develspace.context.pc.py @@ -0,0 +1,8 @@ +# generated from catkin/cmake/template/pkg.context.pc.in +CATKIN_PACKAGE_PREFIX = "" +PROJECT_PKG_CONFIG_INCLUDE_DIRS = "".split(';') if "" != "" else [] +PROJECT_CATKIN_DEPENDS = "message_runtime;roscpp;rospy;std_msgs;rosaria".replace(';', ' ') +PKG_CONFIG_LIBRARIES_WITH_PREFIX = "-lsafety".split(';') if "-lsafety" != "" else [] +PROJECT_NAME = "safety" +PROJECT_SPACE_DIR = "/home/lab1_5/ws/ws_linux/devel" +PROJECT_VERSION = "0.2.1" diff --git a/Legacy/ws_linux/build/safety/catkin_generated/pkg.installspace.context.pc.py b/Legacy/ws_linux/build/safety/catkin_generated/pkg.installspace.context.pc.py new file mode 100644 index 0000000..5f168ac --- /dev/null +++ b/Legacy/ws_linux/build/safety/catkin_generated/pkg.installspace.context.pc.py @@ -0,0 +1,8 @@ +# generated from catkin/cmake/template/pkg.context.pc.in +CATKIN_PACKAGE_PREFIX = "" +PROJECT_PKG_CONFIG_INCLUDE_DIRS = "".split(';') if "" != "" else [] +PROJECT_CATKIN_DEPENDS = "message_runtime;roscpp;rospy;std_msgs;rosaria".replace(';', ' ') +PKG_CONFIG_LIBRARIES_WITH_PREFIX = "-lsafety".split(';') if "-lsafety" != "" else [] +PROJECT_NAME = "safety" +PROJECT_SPACE_DIR = "/home/lab1_5/ws/ws_linux/install" +PROJECT_VERSION = "0.2.1" diff --git a/Legacy/ws_linux/build/safety/catkin_generated/safety-msg-extras.cmake.develspace.in b/Legacy/ws_linux/build/safety/catkin_generated/safety-msg-extras.cmake.develspace.in new file mode 100644 index 0000000..c1b75eb --- /dev/null +++ b/Legacy/ws_linux/build/safety/catkin_generated/safety-msg-extras.cmake.develspace.in @@ -0,0 +1,2 @@ +set(safety_MESSAGE_FILES "") +set(safety_SERVICE_FILES "") diff --git a/Legacy/ws_linux/build/safety/catkin_generated/safety-msg-extras.cmake.installspace.in b/Legacy/ws_linux/build/safety/catkin_generated/safety-msg-extras.cmake.installspace.in new file mode 100644 index 0000000..c1b75eb --- /dev/null +++ b/Legacy/ws_linux/build/safety/catkin_generated/safety-msg-extras.cmake.installspace.in @@ -0,0 +1,2 @@ +set(safety_MESSAGE_FILES "") +set(safety_SERVICE_FILES "") diff --git a/Legacy/ws_linux/build/safety/catkin_generated/safety-msg-paths-context.py b/Legacy/ws_linux/build/safety/catkin_generated/safety-msg-paths-context.py new file mode 100644 index 0000000..0b12a4d --- /dev/null +++ b/Legacy/ws_linux/build/safety/catkin_generated/safety-msg-paths-context.py @@ -0,0 +1,8 @@ +# generated from genmsg/cmake/pkg-msg-paths.context.in + +DEVELSPACE = 'TRUE' == 'TRUE' +INSTALLSPACE = 'FALSE' == 'TRUE' + +PROJECT_NAME = 'safety' +PKG_MSG_INCLUDE_DIRS = '' +ARG_DEPENDENCIES = 'std_msgs' diff --git a/Legacy/ws_linux/build/safety/catkin_generated/stamps/safety/package.xml.stamp b/Legacy/ws_linux/build/safety/catkin_generated/stamps/safety/package.xml.stamp new file mode 100644 index 0000000..c73f4e1 --- /dev/null +++ b/Legacy/ws_linux/build/safety/catkin_generated/stamps/safety/package.xml.stamp @@ -0,0 +1,24 @@ + + + safety + 0.2.1 + Package prevents robot from crashing into obstacle. Enables robot brakes when the distance is smaller than minimum_distance. + + Aleksandra Grzelak + GNU GPLv3 + + message_generation + message_runtime + catkin + roscpp + rospy + std_msgs + rosaria + + roscpp + rospy + std_msgs + rosaria + + + diff --git a/Legacy/ws_linux/build/safety/catkin_generated/stamps/safety/pkg-genmsg.cmake.em.stamp b/Legacy/ws_linux/build/safety/catkin_generated/stamps/safety/pkg-genmsg.cmake.em.stamp new file mode 100644 index 0000000..5182859 --- /dev/null +++ b/Legacy/ws_linux/build/safety/catkin_generated/stamps/safety/pkg-genmsg.cmake.em.stamp @@ -0,0 +1,141 @@ +# generated from genmsg/cmake/pkg-genmsg.cmake.em + +@{ +import os +import sys + +import genmsg +import genmsg.base +genmsg.base.log_verbose('GENMSG_VERBOSE' in os.environ) +import genmsg.deps +import genmsg.gentools + +# split incoming variables +messages = messages_str.split(';') if messages_str != '' else [] +services = services_str.split(';') if services_str != '' else [] +dependencies = dependencies_str.split(';') if dependencies_str != '' else [] +dep_search_paths = dep_include_paths_str.split(';') if dep_include_paths_str != '' else [] + +dep_search_paths_dict = {} +dep_search_paths_tuple_list = [] +is_even = True +for val in dep_search_paths: + if is_even: + dep_search_paths_dict.setdefault(val, []) + val_prev = val + is_even = False + else: + dep_search_paths_dict[val_prev].append(val) + dep_search_paths_tuple_list.append((val_prev, val)) + is_even = True +dep_search_paths = dep_search_paths_dict + +if not messages and not services: + print('message(WARNING "Invoking generate_messages() without having added any message or service file before.\nYou should either add add_message_files() and/or add_service_files() calls or remove the invocation of generate_messages().")') + +msg_deps = {} +for m in messages: + try: + msg_deps[m] = genmsg.deps.find_msg_dependencies(pkg_name, m, dep_search_paths) + except genmsg.MsgNotFound as e: + print('message(FATAL_ERROR "Could not find messages which \'%s\' depends on. Did you forget to specify generate_messages(DEPENDENCIES ...)?\n%s")' % (m, str(e))) + +srv_deps = {} +for s in services: + try: + srv_deps[s] = genmsg.deps.find_srv_dependencies(pkg_name, s, dep_search_paths) + except genmsg.MsgNotFound as e: + print('message(FATAL_ERROR "Could not find messages which \'%s\' depends on. Did you forget to specify generate_messages(DEPENDENCIES ...)?\n%s")' % (s, str(e))) + +}@ +message(STATUS "@(pkg_name): @(len(messages)) messages, @(len(services)) services") + +set(MSG_I_FLAGS "@(';'.join(["-I%s:%s" % (dep, dir) for dep, dir in dep_search_paths_tuple_list]))") + +# Find all generators +@[if langs]@ +@[for l in langs.split(';')]@ +find_package(@l REQUIRED) +@[end for]@ +@[end if]@ + +add_custom_target(@(pkg_name)_generate_messages ALL) + +# +# langs = @langs +# + +@[if langs]@ +@[for l in langs.split(';')]@ +### Section generating for lang: @l +### Generating Messages +@[for m in msg_deps.keys()]@ +_generate_msg_@(l[3:])(@pkg_name + "@m" + "${MSG_I_FLAGS}" + "@(';'.join(msg_deps[m]).replace("\\","/"))" + ${CATKIN_DEVEL_PREFIX}/${@(l)_INSTALL_DIR}/@pkg_name +) +@[end for]@# messages + +### Generating Services +@[for s in srv_deps.keys()]@ +_generate_srv_@(l[3:])(@pkg_name + "@s" + "${MSG_I_FLAGS}" + "@(';'.join(srv_deps[s]).replace("\\","/"))" + ${CATKIN_DEVEL_PREFIX}/${@(l)_INSTALL_DIR}/@pkg_name +) +@[end for]@# services + +### Generating Module File +_generate_module_@(l[3:])(@pkg_name + ${CATKIN_DEVEL_PREFIX}/${@(l)_INSTALL_DIR}/@pkg_name + "${ALL_GEN_OUTPUT_FILES_@(l[3:])}" +) + +add_custom_target(@(pkg_name)_generate_messages_@(l[3:]) + DEPENDS ${ALL_GEN_OUTPUT_FILES_@(l[3:])} +) +add_dependencies(@(pkg_name)_generate_messages @(pkg_name)_generate_messages_@(l[3:])) + +# target for backward compatibility +add_custom_target(@(pkg_name)_@(l)) +add_dependencies(@(pkg_name)_@(l) @(pkg_name)_generate_messages_@(l[3:])) + +# register target for catkin_package(EXPORTED_TARGETS) +list(APPEND ${PROJECT_NAME}_EXPORTED_TARGETS @(pkg_name)_generate_messages_@(l[3:])) + +@[end for]@# langs +@[end if]@ + +@[if langs]@ +@[for l in langs.split(';')]@ + +if(@(l)_INSTALL_DIR AND EXISTS ${CATKIN_DEVEL_PREFIX}/${@(l)_INSTALL_DIR}/@pkg_name) +@[if l == 'genpy']@ + install(CODE "execute_process(COMMAND \"@(PYTHON_EXECUTABLE)\" -m compileall \"${CATKIN_DEVEL_PREFIX}/${@(l)_INSTALL_DIR}/@pkg_name\")") +@[end if]@ + # install generated code + install( + DIRECTORY ${CATKIN_DEVEL_PREFIX}/${@(l)_INSTALL_DIR}/@pkg_name + DESTINATION ${@(l)_INSTALL_DIR} +@[if l == 'genpy' and package_has_static_sources]@ + # skip all init files + PATTERN "__init__.py" EXCLUDE + PATTERN "__init__.pyc" EXCLUDE + ) + # install init files which are not in the root folder of the generated code + install( + DIRECTORY ${CATKIN_DEVEL_PREFIX}/${@(l)_INSTALL_DIR}/@pkg_name + DESTINATION ${@(l)_INSTALL_DIR} + FILES_MATCHING + REGEX "${CATKIN_DEVEL_PREFIX}/${@(l)_INSTALL_DIR}/@(pkg_name)/.+/__init__.pyc?$" +@[end if]@ + ) +endif() +@[for d in dependencies]@ +add_dependencies(@(pkg_name)_generate_messages_@(l[3:]) @(d)_generate_messages_@(l[3:])) +@[end for]@# dependencies +@[end for]@# langs +@[end if]@ diff --git a/Legacy/ws_linux/build/safety/catkin_generated/stamps/safety/pkg-msg-paths.cmake.em.stamp b/Legacy/ws_linux/build/safety/catkin_generated/stamps/safety/pkg-msg-paths.cmake.em.stamp new file mode 100644 index 0000000..eb6f88a --- /dev/null +++ b/Legacy/ws_linux/build/safety/catkin_generated/stamps/safety/pkg-msg-paths.cmake.em.stamp @@ -0,0 +1,10 @@ +# generated from genmsg/cmake/pkg-msg-paths.cmake.em + +@[if DEVELSPACE]@ +# message include dirs in develspace +set(@(PROJECT_NAME)_MSG_INCLUDE_DIRS "@(PKG_MSG_INCLUDE_DIRS)") +@[else]@ +# message include dirs in installspace +_prepend_path("${@(PROJECT_NAME)_DIR}/.." "@(PKG_MSG_INCLUDE_DIRS)" @(PROJECT_NAME)_MSG_INCLUDE_DIRS UNIQUE) +@[end if]@ +set(@(PROJECT_NAME)_MSG_DEPENDENCIES @(ARG_DEPENDENCIES)) diff --git a/Legacy/ws_linux/build/safety/catkin_generated/stamps/safety/pkg.pc.em.stamp b/Legacy/ws_linux/build/safety/catkin_generated/stamps/safety/pkg.pc.em.stamp new file mode 100644 index 0000000..a4f7257 --- /dev/null +++ b/Legacy/ws_linux/build/safety/catkin_generated/stamps/safety/pkg.pc.em.stamp @@ -0,0 +1,8 @@ +prefix=@PROJECT_SPACE_DIR + +Name: @(CATKIN_PACKAGE_PREFIX + PROJECT_NAME) +Description: Description of @PROJECT_NAME +Version: @PROJECT_VERSION +Cflags: @(' '.join(['-I%s' % include for include in PROJECT_PKG_CONFIG_INCLUDE_DIRS])) +Libs: -L@PROJECT_SPACE_DIR/lib @(' '.join(PKG_CONFIG_LIBRARIES_WITH_PREFIX)) +Requires: @(PROJECT_CATKIN_DEPENDS) diff --git a/Legacy/ws_linux/build/safety/cmake/safety-genmsg-context.py b/Legacy/ws_linux/build/safety/cmake/safety-genmsg-context.py new file mode 100644 index 0000000..e74a5ff --- /dev/null +++ b/Legacy/ws_linux/build/safety/cmake/safety-genmsg-context.py @@ -0,0 +1,10 @@ +# generated from genmsg/cmake/pkg-genmsg.context.in + +messages_str = "" +services_str = "" +pkg_name = "safety" +dependencies_str = "std_msgs" +langs = "gencpp;genlisp;genpy" +dep_include_paths_str = "std_msgs;/opt/ros/hydro/share/std_msgs/cmake/../msg" +PYTHON_EXECUTABLE = "/usr/bin/python" +package_has_static_sources = '' == 'TRUE' diff --git a/Legacy/ws_linux/build/safety/cmake/safety-genmsg.cmake b/Legacy/ws_linux/build/safety/cmake/safety-genmsg.cmake new file mode 100644 index 0000000..d607ccf --- /dev/null +++ b/Legacy/ws_linux/build/safety/cmake/safety-genmsg.cmake @@ -0,0 +1,117 @@ +# generated from genmsg/cmake/pkg-genmsg.cmake.em + +message(WARNING "Invoking generate_messages() without having added any message or service file before. +You should either add add_message_files() and/or add_service_files() calls or remove the invocation of generate_messages().") +message(STATUS "safety: 0 messages, 0 services") + +set(MSG_I_FLAGS "-Istd_msgs:/opt/ros/hydro/share/std_msgs/cmake/../msg") + +# Find all generators +find_package(gencpp REQUIRED) +find_package(genlisp REQUIRED) +find_package(genpy REQUIRED) + +add_custom_target(safety_generate_messages ALL) + +# +# langs = gencpp;genlisp;genpy +# + +### Section generating for lang: gencpp +### Generating Messages + +### Generating Services + +### Generating Module File +_generate_module_cpp(safety + ${CATKIN_DEVEL_PREFIX}/${gencpp_INSTALL_DIR}/safety + "${ALL_GEN_OUTPUT_FILES_cpp}" +) + +add_custom_target(safety_generate_messages_cpp + DEPENDS ${ALL_GEN_OUTPUT_FILES_cpp} +) +add_dependencies(safety_generate_messages safety_generate_messages_cpp) + +# target for backward compatibility +add_custom_target(safety_gencpp) +add_dependencies(safety_gencpp safety_generate_messages_cpp) + +# register target for catkin_package(EXPORTED_TARGETS) +list(APPEND ${PROJECT_NAME}_EXPORTED_TARGETS safety_generate_messages_cpp) + +### Section generating for lang: genlisp +### Generating Messages + +### Generating Services + +### Generating Module File +_generate_module_lisp(safety + ${CATKIN_DEVEL_PREFIX}/${genlisp_INSTALL_DIR}/safety + "${ALL_GEN_OUTPUT_FILES_lisp}" +) + +add_custom_target(safety_generate_messages_lisp + DEPENDS ${ALL_GEN_OUTPUT_FILES_lisp} +) +add_dependencies(safety_generate_messages safety_generate_messages_lisp) + +# target for backward compatibility +add_custom_target(safety_genlisp) +add_dependencies(safety_genlisp safety_generate_messages_lisp) + +# register target for catkin_package(EXPORTED_TARGETS) +list(APPEND ${PROJECT_NAME}_EXPORTED_TARGETS safety_generate_messages_lisp) + +### Section generating for lang: genpy +### Generating Messages + +### Generating Services + +### Generating Module File +_generate_module_py(safety + ${CATKIN_DEVEL_PREFIX}/${genpy_INSTALL_DIR}/safety + "${ALL_GEN_OUTPUT_FILES_py}" +) + +add_custom_target(safety_generate_messages_py + DEPENDS ${ALL_GEN_OUTPUT_FILES_py} +) +add_dependencies(safety_generate_messages safety_generate_messages_py) + +# target for backward compatibility +add_custom_target(safety_genpy) +add_dependencies(safety_genpy safety_generate_messages_py) + +# register target for catkin_package(EXPORTED_TARGETS) +list(APPEND ${PROJECT_NAME}_EXPORTED_TARGETS safety_generate_messages_py) + + + +if(gencpp_INSTALL_DIR AND EXISTS ${CATKIN_DEVEL_PREFIX}/${gencpp_INSTALL_DIR}/safety) + # install generated code + install( + DIRECTORY ${CATKIN_DEVEL_PREFIX}/${gencpp_INSTALL_DIR}/safety + DESTINATION ${gencpp_INSTALL_DIR} + ) +endif() +add_dependencies(safety_generate_messages_cpp std_msgs_generate_messages_cpp) + +if(genlisp_INSTALL_DIR AND EXISTS ${CATKIN_DEVEL_PREFIX}/${genlisp_INSTALL_DIR}/safety) + # install generated code + install( + DIRECTORY ${CATKIN_DEVEL_PREFIX}/${genlisp_INSTALL_DIR}/safety + DESTINATION ${genlisp_INSTALL_DIR} + ) +endif() +add_dependencies(safety_generate_messages_lisp std_msgs_generate_messages_lisp) + +if(genpy_INSTALL_DIR AND EXISTS ${CATKIN_DEVEL_PREFIX}/${genpy_INSTALL_DIR}/safety) + install(CODE "execute_process(COMMAND \"/usr/bin/python\" -m compileall \"${CATKIN_DEVEL_PREFIX}/${genpy_INSTALL_DIR}/safety\")") + # install generated code + install( + DIRECTORY ${CATKIN_DEVEL_PREFIX}/${genpy_INSTALL_DIR}/safety + DESTINATION ${genpy_INSTALL_DIR} + ) +endif() +add_dependencies(safety_generate_messages_py std_msgs_generate_messages_py) diff --git a/Legacy/ws_linux/build/safety/cmake_install.cmake b/Legacy/ws_linux/build/safety/cmake_install.cmake new file mode 100644 index 0000000..6d09437 --- /dev/null +++ b/Legacy/ws_linux/build/safety/cmake_install.cmake @@ -0,0 +1,65 @@ +# Install script for directory: /home/lab1_5/ws/ws_linux/src/safety + +# Set the install prefix +IF(NOT DEFINED CMAKE_INSTALL_PREFIX) + SET(CMAKE_INSTALL_PREFIX "/home/lab1_5/ws/ws_linux/install") +ENDIF(NOT DEFINED CMAKE_INSTALL_PREFIX) +STRING(REGEX REPLACE "/$" "" CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}") + +# Set the install configuration name. +IF(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME) + IF(BUILD_TYPE) + STRING(REGEX REPLACE "^[^A-Za-z0-9_]+" "" + CMAKE_INSTALL_CONFIG_NAME "${BUILD_TYPE}") + ELSE(BUILD_TYPE) + SET(CMAKE_INSTALL_CONFIG_NAME "") + ENDIF(BUILD_TYPE) + MESSAGE(STATUS "Install configuration: \"${CMAKE_INSTALL_CONFIG_NAME}\"") +ENDIF(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME) + +# Set the component getting installed. +IF(NOT CMAKE_INSTALL_COMPONENT) + IF(COMPONENT) + MESSAGE(STATUS "Install component: \"${COMPONENT}\"") + SET(CMAKE_INSTALL_COMPONENT "${COMPONENT}") + ELSE(COMPONENT) + SET(CMAKE_INSTALL_COMPONENT) + ENDIF(COMPONENT) +ENDIF(NOT CMAKE_INSTALL_COMPONENT) + +# Install shared libraries without execute permission? +IF(NOT DEFINED CMAKE_INSTALL_SO_NO_EXE) + SET(CMAKE_INSTALL_SO_NO_EXE "1") +ENDIF(NOT DEFINED CMAKE_INSTALL_SO_NO_EXE) + +IF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + FILE(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/share/safety/cmake" TYPE FILE FILES "/home/lab1_5/ws/ws_linux/build/safety/catkin_generated/installspace/safety-msg-paths.cmake") +ENDIF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + +IF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + execute_process(COMMAND "/usr/bin/python" -m compileall "/home/lab1_5/ws/ws_linux/devel/lib/python2.7/dist-packages/safety") +ENDIF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + +IF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + FILE(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/lib/python2.7/dist-packages" TYPE DIRECTORY FILES "/home/lab1_5/ws/ws_linux/devel/lib/python2.7/dist-packages/safety") +ENDIF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + +IF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + FILE(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/lib/pkgconfig" TYPE FILE FILES "/home/lab1_5/ws/ws_linux/build/safety/catkin_generated/installspace/safety.pc") +ENDIF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + +IF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + FILE(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/share/safety/cmake" TYPE FILE FILES "/home/lab1_5/ws/ws_linux/build/safety/catkin_generated/installspace/safety-msg-extras.cmake") +ENDIF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + +IF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + FILE(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/share/safety/cmake" TYPE FILE FILES + "/home/lab1_5/ws/ws_linux/build/safety/catkin_generated/installspace/safetyConfig.cmake" + "/home/lab1_5/ws/ws_linux/build/safety/catkin_generated/installspace/safetyConfig-version.cmake" + ) +ENDIF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + +IF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + FILE(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/share/safety" TYPE FILE FILES "/home/lab1_5/ws/ws_linux/src/safety/package.xml") +ENDIF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + diff --git a/Legacy/ws_linux/build/videostream/CMakeFiles/CMakeDirectoryInformation.cmake b/Legacy/ws_linux/build/videostream/CMakeFiles/CMakeDirectoryInformation.cmake new file mode 100644 index 0000000..7ffe49e --- /dev/null +++ b/Legacy/ws_linux/build/videostream/CMakeFiles/CMakeDirectoryInformation.cmake @@ -0,0 +1,23 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +# Relative path conversion top directories. +SET(CMAKE_RELATIVE_PATH_TOP_SOURCE "/home/lab1_5/ws/ws_linux/src") +SET(CMAKE_RELATIVE_PATH_TOP_BINARY "/home/lab1_5/ws/ws_linux/build") + +# Force unix paths in dependencies. +SET(CMAKE_FORCE_UNIX_PATHS 1) + +# The C and CXX include file search paths: +SET(CMAKE_C_INCLUDE_PATH + "/home/lab1_5/ws/ws_linux/devel/include" + ) +SET(CMAKE_CXX_INCLUDE_PATH ${CMAKE_C_INCLUDE_PATH}) +SET(CMAKE_Fortran_INCLUDE_PATH ${CMAKE_C_INCLUDE_PATH}) +SET(CMAKE_ASM_INCLUDE_PATH ${CMAKE_C_INCLUDE_PATH}) + +# The C and CXX include file regular expressions for this directory. +SET(CMAKE_C_INCLUDE_REGEX_SCAN "^.*$") +SET(CMAKE_C_INCLUDE_REGEX_COMPLAIN "^$") +SET(CMAKE_CXX_INCLUDE_REGEX_SCAN ${CMAKE_C_INCLUDE_REGEX_SCAN}) +SET(CMAKE_CXX_INCLUDE_REGEX_COMPLAIN ${CMAKE_C_INCLUDE_REGEX_COMPLAIN}) diff --git a/Legacy/ws_linux/build/videostream/CMakeFiles/progress.marks b/Legacy/ws_linux/build/videostream/CMakeFiles/progress.marks new file mode 100644 index 0000000..7ed6ff8 --- /dev/null +++ b/Legacy/ws_linux/build/videostream/CMakeFiles/progress.marks @@ -0,0 +1 @@ +5 diff --git a/Legacy/ws_linux/build/videostream/CMakeFiles/videostream.dir/CXX.includecache b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream.dir/CXX.includecache new file mode 100644 index 0000000..1576008 --- /dev/null +++ b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream.dir/CXX.includecache @@ -0,0 +1,82 @@ +#IncludeRegexLine: ^[ ]*#[ ]*(include|import)[ ]*[<"]([^">]+)([">]) + +#IncludeRegexScan: ^.*$ + +#IncludeRegexComplain: ^$ + +#IncludeRegexTransform: + +/home/lab1_5/ws/ws_linux/devel/include/videostream/ip_get.h +ros/service_traits.h +- +videostream/ip_getRequest.h +- +videostream/ip_getResponse.h +- + +/home/lab1_5/ws/ws_linux/devel/include/videostream/ip_getRequest.h +string +- +vector +- +map +- +ros/types.h +- +ros/serialization.h +- +ros/builtin_message_traits.h +- +ros/message_operations.h +- + +/home/lab1_5/ws/ws_linux/devel/include/videostream/ip_getResponse.h +string +- +vector +- +map +- +ros/types.h +- +ros/serialization.h +- +ros/builtin_message_traits.h +- +ros/message_operations.h +- + +/home/lab1_5/ws/ws_linux/src/videostream/src/../include/Videostream.h +ros/ros.h +/home/lab1_5/ws/ws_linux/src/videostream/src/../include/ros/ros.h +videostream/ip_get.h +/home/lab1_5/ws/ws_linux/src/videostream/src/../include/videostream/ip_get.h +std_msgs/String.h +/home/lab1_5/ws/ws_linux/src/videostream/src/../include/std_msgs/String.h +cstdlib +- +string +- +sstream +- +unistd.h +- +sys/types.h +- +sys/stat.h +- +fcntl.h +- +map +- +vector +- +algorithm +- +boost/tr1/regex.hpp +- + +/home/lab1_5/ws/ws_linux/src/videostream/src/videostream.cpp +../include/Videostream.h +/home/lab1_5/ws/ws_linux/src/videostream/src/../include/Videostream.h + diff --git a/Legacy/ws_linux/build/videostream/CMakeFiles/videostream.dir/DependInfo.cmake b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream.dir/DependInfo.cmake new file mode 100644 index 0000000..8cded8b --- /dev/null +++ b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream.dir/DependInfo.cmake @@ -0,0 +1,20 @@ +# The set of languages for which implicit dependencies are needed: +SET(CMAKE_DEPENDS_LANGUAGES + "CXX" + ) +# The set of files for implicit dependencies of each language: +SET(CMAKE_DEPENDS_CHECK_CXX + "/home/lab1_5/ws/ws_linux/src/videostream/src/videostream.cpp" "/home/lab1_5/ws/ws_linux/build/videostream/CMakeFiles/videostream.dir/src/videostream.cpp.o" + ) +SET(CMAKE_CXX_COMPILER_ID "GNU") + +# Preprocessor definitions for this target. +SET(CMAKE_TARGET_DEFINITIONS + "ROS_BUILD_SHARED_LIBS=1" + "ROS_PACKAGE_NAME=\"videostream\"" + "ROSCONSOLE_BACKEND_LOG4CXX" + ) + +# Targets to which this target links. +SET(CMAKE_TARGET_LINKED_INFO_FILES + ) diff --git a/Legacy/ws_linux/build/videostream/CMakeFiles/videostream.dir/build.make b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream.dir/build.make new file mode 100644 index 0000000..55af076 --- /dev/null +++ b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream.dir/build.make @@ -0,0 +1,116 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/lab1_5/ws/ws_linux/src + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/lab1_5/ws/ws_linux/build + +# Include any dependencies generated for this target. +include videostream/CMakeFiles/videostream.dir/depend.make + +# Include the progress variables for this target. +include videostream/CMakeFiles/videostream.dir/progress.make + +# Include the compile flags for this target's objects. +include videostream/CMakeFiles/videostream.dir/flags.make + +videostream/CMakeFiles/videostream.dir/src/videostream.cpp.o: videostream/CMakeFiles/videostream.dir/flags.make +videostream/CMakeFiles/videostream.dir/src/videostream.cpp.o: /home/lab1_5/ws/ws_linux/src/videostream/src/videostream.cpp + $(CMAKE_COMMAND) -E cmake_progress_report /home/lab1_5/ws/ws_linux/build/CMakeFiles $(CMAKE_PROGRESS_1) + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Building CXX object videostream/CMakeFiles/videostream.dir/src/videostream.cpp.o" + cd /home/lab1_5/ws/ws_linux/build/videostream && /usr/bin/c++ $(CXX_DEFINES) $(CXX_FLAGS) -o CMakeFiles/videostream.dir/src/videostream.cpp.o -c /home/lab1_5/ws/ws_linux/src/videostream/src/videostream.cpp + +videostream/CMakeFiles/videostream.dir/src/videostream.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing CXX source to CMakeFiles/videostream.dir/src/videostream.cpp.i" + cd /home/lab1_5/ws/ws_linux/build/videostream && /usr/bin/c++ $(CXX_DEFINES) $(CXX_FLAGS) -E /home/lab1_5/ws/ws_linux/src/videostream/src/videostream.cpp > CMakeFiles/videostream.dir/src/videostream.cpp.i + +videostream/CMakeFiles/videostream.dir/src/videostream.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling CXX source to assembly CMakeFiles/videostream.dir/src/videostream.cpp.s" + cd /home/lab1_5/ws/ws_linux/build/videostream && /usr/bin/c++ $(CXX_DEFINES) $(CXX_FLAGS) -S /home/lab1_5/ws/ws_linux/src/videostream/src/videostream.cpp -o CMakeFiles/videostream.dir/src/videostream.cpp.s + +videostream/CMakeFiles/videostream.dir/src/videostream.cpp.o.requires: +.PHONY : videostream/CMakeFiles/videostream.dir/src/videostream.cpp.o.requires + +videostream/CMakeFiles/videostream.dir/src/videostream.cpp.o.provides: videostream/CMakeFiles/videostream.dir/src/videostream.cpp.o.requires + $(MAKE) -f videostream/CMakeFiles/videostream.dir/build.make videostream/CMakeFiles/videostream.dir/src/videostream.cpp.o.provides.build +.PHONY : videostream/CMakeFiles/videostream.dir/src/videostream.cpp.o.provides + +videostream/CMakeFiles/videostream.dir/src/videostream.cpp.o.provides.build: videostream/CMakeFiles/videostream.dir/src/videostream.cpp.o + +# Object files for target videostream +videostream_OBJECTS = \ +"CMakeFiles/videostream.dir/src/videostream.cpp.o" + +# External object files for target videostream +videostream_EXTERNAL_OBJECTS = + +/home/lab1_5/ws/ws_linux/devel/lib/videostream/videostream: videostream/CMakeFiles/videostream.dir/src/videostream.cpp.o +/home/lab1_5/ws/ws_linux/devel/lib/videostream/videostream: /opt/ros/hydro/lib/libroscpp.so +/home/lab1_5/ws/ws_linux/devel/lib/videostream/videostream: /usr/lib/libboost_signals-mt.so +/home/lab1_5/ws/ws_linux/devel/lib/videostream/videostream: /usr/lib/libboost_filesystem-mt.so +/home/lab1_5/ws/ws_linux/devel/lib/videostream/videostream: /opt/ros/hydro/lib/librosconsole.so +/home/lab1_5/ws/ws_linux/devel/lib/videostream/videostream: /opt/ros/hydro/lib/librosconsole_log4cxx.so +/home/lab1_5/ws/ws_linux/devel/lib/videostream/videostream: /opt/ros/hydro/lib/librosconsole_backend_interface.so +/home/lab1_5/ws/ws_linux/devel/lib/videostream/videostream: /usr/lib/liblog4cxx.so +/home/lab1_5/ws/ws_linux/devel/lib/videostream/videostream: /usr/lib/libboost_regex-mt.so +/home/lab1_5/ws/ws_linux/devel/lib/videostream/videostream: /opt/ros/hydro/lib/libxmlrpcpp.so +/home/lab1_5/ws/ws_linux/devel/lib/videostream/videostream: /opt/ros/hydro/lib/libroscpp_serialization.so +/home/lab1_5/ws/ws_linux/devel/lib/videostream/videostream: /opt/ros/hydro/lib/librostime.so +/home/lab1_5/ws/ws_linux/devel/lib/videostream/videostream: /usr/lib/libboost_date_time-mt.so +/home/lab1_5/ws/ws_linux/devel/lib/videostream/videostream: /usr/lib/libboost_system-mt.so +/home/lab1_5/ws/ws_linux/devel/lib/videostream/videostream: /usr/lib/libboost_thread-mt.so +/home/lab1_5/ws/ws_linux/devel/lib/videostream/videostream: /usr/lib/x86_64-linux-gnu/libpthread.so +/home/lab1_5/ws/ws_linux/devel/lib/videostream/videostream: /opt/ros/hydro/lib/libcpp_common.so +/home/lab1_5/ws/ws_linux/devel/lib/videostream/videostream: /opt/ros/hydro/lib/libconsole_bridge.so +/home/lab1_5/ws/ws_linux/devel/lib/videostream/videostream: videostream/CMakeFiles/videostream.dir/build.make +/home/lab1_5/ws/ws_linux/devel/lib/videostream/videostream: videostream/CMakeFiles/videostream.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --red --bold "Linking CXX executable /home/lab1_5/ws/ws_linux/devel/lib/videostream/videostream" + cd /home/lab1_5/ws/ws_linux/build/videostream && $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/videostream.dir/link.txt --verbose=$(VERBOSE) + +# Rule to build all files generated by this target. +videostream/CMakeFiles/videostream.dir/build: /home/lab1_5/ws/ws_linux/devel/lib/videostream/videostream +.PHONY : videostream/CMakeFiles/videostream.dir/build + +videostream/CMakeFiles/videostream.dir/requires: videostream/CMakeFiles/videostream.dir/src/videostream.cpp.o.requires +.PHONY : videostream/CMakeFiles/videostream.dir/requires + +videostream/CMakeFiles/videostream.dir/clean: + cd /home/lab1_5/ws/ws_linux/build/videostream && $(CMAKE_COMMAND) -P CMakeFiles/videostream.dir/cmake_clean.cmake +.PHONY : videostream/CMakeFiles/videostream.dir/clean + +videostream/CMakeFiles/videostream.dir/depend: + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/lab1_5/ws/ws_linux/src /home/lab1_5/ws/ws_linux/src/videostream /home/lab1_5/ws/ws_linux/build /home/lab1_5/ws/ws_linux/build/videostream /home/lab1_5/ws/ws_linux/build/videostream/CMakeFiles/videostream.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : videostream/CMakeFiles/videostream.dir/depend + diff --git a/Legacy/ws_linux/build/videostream/CMakeFiles/videostream.dir/cmake_clean.cmake b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream.dir/cmake_clean.cmake new file mode 100644 index 0000000..d4bf140 --- /dev/null +++ b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream.dir/cmake_clean.cmake @@ -0,0 +1,10 @@ +FILE(REMOVE_RECURSE + "CMakeFiles/videostream.dir/src/videostream.cpp.o" + "/home/lab1_5/ws/ws_linux/devel/lib/videostream/videostream.pdb" + "/home/lab1_5/ws/ws_linux/devel/lib/videostream/videostream" +) + +# Per-language clean rules from dependency scanning. +FOREACH(lang CXX) + INCLUDE(CMakeFiles/videostream.dir/cmake_clean_${lang}.cmake OPTIONAL) +ENDFOREACH(lang) diff --git a/Legacy/ws_linux/build/videostream/CMakeFiles/videostream.dir/depend.internal b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream.dir/depend.internal new file mode 100644 index 0000000..f6e2334 --- /dev/null +++ b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream.dir/depend.internal @@ -0,0 +1,9 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +videostream/CMakeFiles/videostream.dir/src/videostream.cpp.o + /home/lab1_5/ws/ws_linux/devel/include/videostream/ip_get.h + /home/lab1_5/ws/ws_linux/devel/include/videostream/ip_getRequest.h + /home/lab1_5/ws/ws_linux/devel/include/videostream/ip_getResponse.h + /home/lab1_5/ws/ws_linux/src/videostream/src/../include/Videostream.h + /home/lab1_5/ws/ws_linux/src/videostream/src/videostream.cpp diff --git a/Legacy/ws_linux/build/videostream/CMakeFiles/videostream.dir/depend.make b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream.dir/depend.make new file mode 100644 index 0000000..72f503b --- /dev/null +++ b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream.dir/depend.make @@ -0,0 +1,9 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +videostream/CMakeFiles/videostream.dir/src/videostream.cpp.o: /home/lab1_5/ws/ws_linux/devel/include/videostream/ip_get.h +videostream/CMakeFiles/videostream.dir/src/videostream.cpp.o: /home/lab1_5/ws/ws_linux/devel/include/videostream/ip_getRequest.h +videostream/CMakeFiles/videostream.dir/src/videostream.cpp.o: /home/lab1_5/ws/ws_linux/devel/include/videostream/ip_getResponse.h +videostream/CMakeFiles/videostream.dir/src/videostream.cpp.o: /home/lab1_5/ws/ws_linux/src/videostream/src/../include/Videostream.h +videostream/CMakeFiles/videostream.dir/src/videostream.cpp.o: /home/lab1_5/ws/ws_linux/src/videostream/src/videostream.cpp + diff --git a/Legacy/ws_linux/build/videostream/CMakeFiles/videostream.dir/flags.make b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream.dir/flags.make new file mode 100644 index 0000000..d92e17c --- /dev/null +++ b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream.dir/flags.make @@ -0,0 +1,8 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +# compile CXX with /usr/bin/c++ +CXX_FLAGS = -I/home/lab1_5/ws/ws_linux/devel/include + +CXX_DEFINES = -DROS_BUILD_SHARED_LIBS=1 -DROS_PACKAGE_NAME=\"videostream\" -DROSCONSOLE_BACKEND_LOG4CXX + diff --git a/Legacy/ws_linux/build/videostream/CMakeFiles/videostream.dir/link.txt b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream.dir/link.txt new file mode 100644 index 0000000..0948c18 --- /dev/null +++ b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ CMakeFiles/videostream.dir/src/videostream.cpp.o -o /home/lab1_5/ws/ws_linux/devel/lib/videostream/videostream -rdynamic /opt/ros/hydro/lib/libroscpp.so -lboost_signals-mt -lboost_filesystem-mt /opt/ros/hydro/lib/librosconsole.so /opt/ros/hydro/lib/librosconsole_log4cxx.so /opt/ros/hydro/lib/librosconsole_backend_interface.so -llog4cxx -lboost_regex-mt /opt/ros/hydro/lib/libxmlrpcpp.so /opt/ros/hydro/lib/libroscpp_serialization.so /opt/ros/hydro/lib/librostime.so -lboost_date_time-mt -lboost_system-mt -lboost_thread-mt -lpthread /opt/ros/hydro/lib/libcpp_common.so /opt/ros/hydro/lib/libconsole_bridge.so -Wl,-rpath,/opt/ros/hydro/lib diff --git a/Legacy/ws_linux/build/videostream/CMakeFiles/videostream.dir/progress.make b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream.dir/progress.make new file mode 100644 index 0000000..e9ac291 --- /dev/null +++ b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream.dir/progress.make @@ -0,0 +1,2 @@ +CMAKE_PROGRESS_1 = 18 + diff --git a/Legacy/ws_linux/build/videostream/CMakeFiles/videostream.dir/src/videostream.cpp.o b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream.dir/src/videostream.cpp.o new file mode 100644 index 0000000000000000000000000000000000000000..e142161124005219f6edf352ef6642e1fbe43e38 GIT binary patch literal 441808 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 U&g#)qoqJ-P67r!;`W*590T|&QNdN!< literal 0 HcmV?d00001 diff --git a/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_gencpp.dir/DependInfo.cmake b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_gencpp.dir/DependInfo.cmake new file mode 100644 index 0000000..551e629 --- /dev/null +++ b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_gencpp.dir/DependInfo.cmake @@ -0,0 +1,15 @@ +# The set of languages for which implicit dependencies are needed: +SET(CMAKE_DEPENDS_LANGUAGES + ) +# The set of files for implicit dependencies of each language: + +# Preprocessor definitions for this target. +SET(CMAKE_TARGET_DEFINITIONS + "ROS_BUILD_SHARED_LIBS=1" + "ROS_PACKAGE_NAME=\"videostream\"" + "ROSCONSOLE_BACKEND_LOG4CXX" + ) + +# Targets to which this target links. +SET(CMAKE_TARGET_LINKED_INFO_FILES + ) diff --git a/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_gencpp.dir/build.make b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_gencpp.dir/build.make new file mode 100644 index 0000000..6eb3dc1 --- /dev/null +++ b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_gencpp.dir/build.make @@ -0,0 +1,62 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/lab1_5/ws/ws_linux/src + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/lab1_5/ws/ws_linux/build + +# Utility rule file for videostream_gencpp. + +# Include the progress variables for this target. +include videostream/CMakeFiles/videostream_gencpp.dir/progress.make + +videostream/CMakeFiles/videostream_gencpp: + +videostream_gencpp: videostream/CMakeFiles/videostream_gencpp +videostream_gencpp: videostream/CMakeFiles/videostream_gencpp.dir/build.make +.PHONY : videostream_gencpp + +# Rule to build all files generated by this target. +videostream/CMakeFiles/videostream_gencpp.dir/build: videostream_gencpp +.PHONY : videostream/CMakeFiles/videostream_gencpp.dir/build + +videostream/CMakeFiles/videostream_gencpp.dir/clean: + cd /home/lab1_5/ws/ws_linux/build/videostream && $(CMAKE_COMMAND) -P CMakeFiles/videostream_gencpp.dir/cmake_clean.cmake +.PHONY : videostream/CMakeFiles/videostream_gencpp.dir/clean + +videostream/CMakeFiles/videostream_gencpp.dir/depend: + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/lab1_5/ws/ws_linux/src /home/lab1_5/ws/ws_linux/src/videostream /home/lab1_5/ws/ws_linux/build /home/lab1_5/ws/ws_linux/build/videostream /home/lab1_5/ws/ws_linux/build/videostream/CMakeFiles/videostream_gencpp.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : videostream/CMakeFiles/videostream_gencpp.dir/depend + diff --git a/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_gencpp.dir/cmake_clean.cmake b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_gencpp.dir/cmake_clean.cmake new file mode 100644 index 0000000..e16f56d --- /dev/null +++ b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_gencpp.dir/cmake_clean.cmake @@ -0,0 +1,8 @@ +FILE(REMOVE_RECURSE + "CMakeFiles/videostream_gencpp" +) + +# Per-language clean rules from dependency scanning. +FOREACH(lang) + INCLUDE(CMakeFiles/videostream_gencpp.dir/cmake_clean_${lang}.cmake OPTIONAL) +ENDFOREACH(lang) diff --git a/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_gencpp.dir/progress.make b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_gencpp.dir/progress.make new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_gencpp.dir/progress.make @@ -0,0 +1 @@ + diff --git a/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages.dir/DependInfo.cmake b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages.dir/DependInfo.cmake new file mode 100644 index 0000000..551e629 --- /dev/null +++ b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages.dir/DependInfo.cmake @@ -0,0 +1,15 @@ +# The set of languages for which implicit dependencies are needed: +SET(CMAKE_DEPENDS_LANGUAGES + ) +# The set of files for implicit dependencies of each language: + +# Preprocessor definitions for this target. +SET(CMAKE_TARGET_DEFINITIONS + "ROS_BUILD_SHARED_LIBS=1" + "ROS_PACKAGE_NAME=\"videostream\"" + "ROSCONSOLE_BACKEND_LOG4CXX" + ) + +# Targets to which this target links. +SET(CMAKE_TARGET_LINKED_INFO_FILES + ) diff --git a/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages.dir/build.make b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages.dir/build.make new file mode 100644 index 0000000..ce6c72d --- /dev/null +++ b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages.dir/build.make @@ -0,0 +1,62 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/lab1_5/ws/ws_linux/src + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/lab1_5/ws/ws_linux/build + +# Utility rule file for videostream_generate_messages. + +# Include the progress variables for this target. +include videostream/CMakeFiles/videostream_generate_messages.dir/progress.make + +videostream/CMakeFiles/videostream_generate_messages: + +videostream_generate_messages: videostream/CMakeFiles/videostream_generate_messages +videostream_generate_messages: videostream/CMakeFiles/videostream_generate_messages.dir/build.make +.PHONY : videostream_generate_messages + +# Rule to build all files generated by this target. +videostream/CMakeFiles/videostream_generate_messages.dir/build: videostream_generate_messages +.PHONY : videostream/CMakeFiles/videostream_generate_messages.dir/build + +videostream/CMakeFiles/videostream_generate_messages.dir/clean: + cd /home/lab1_5/ws/ws_linux/build/videostream && $(CMAKE_COMMAND) -P CMakeFiles/videostream_generate_messages.dir/cmake_clean.cmake +.PHONY : videostream/CMakeFiles/videostream_generate_messages.dir/clean + +videostream/CMakeFiles/videostream_generate_messages.dir/depend: + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/lab1_5/ws/ws_linux/src /home/lab1_5/ws/ws_linux/src/videostream /home/lab1_5/ws/ws_linux/build /home/lab1_5/ws/ws_linux/build/videostream /home/lab1_5/ws/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : videostream/CMakeFiles/videostream_generate_messages.dir/depend + diff --git a/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages.dir/cmake_clean.cmake b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages.dir/cmake_clean.cmake new file mode 100644 index 0000000..cdc9fc2 --- /dev/null +++ b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages.dir/cmake_clean.cmake @@ -0,0 +1,8 @@ +FILE(REMOVE_RECURSE + "CMakeFiles/videostream_generate_messages" +) + +# Per-language clean rules from dependency scanning. +FOREACH(lang) + INCLUDE(CMakeFiles/videostream_generate_messages.dir/cmake_clean_${lang}.cmake OPTIONAL) +ENDFOREACH(lang) diff --git a/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages.dir/depend.internal b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages.dir/depend.internal new file mode 100644 index 0000000..38eae05 --- /dev/null +++ b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages.dir/depend.internal @@ -0,0 +1,3 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + diff --git a/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages.dir/depend.make b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages.dir/depend.make new file mode 100644 index 0000000..38eae05 --- /dev/null +++ b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages.dir/depend.make @@ -0,0 +1,3 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + diff --git a/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages.dir/progress.make b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages.dir/progress.make new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages.dir/progress.make @@ -0,0 +1 @@ + diff --git a/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages_cpp.dir/DependInfo.cmake b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages_cpp.dir/DependInfo.cmake new file mode 100644 index 0000000..551e629 --- /dev/null +++ b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages_cpp.dir/DependInfo.cmake @@ -0,0 +1,15 @@ +# The set of languages for which implicit dependencies are needed: +SET(CMAKE_DEPENDS_LANGUAGES + ) +# The set of files for implicit dependencies of each language: + +# Preprocessor definitions for this target. +SET(CMAKE_TARGET_DEFINITIONS + "ROS_BUILD_SHARED_LIBS=1" + "ROS_PACKAGE_NAME=\"videostream\"" + "ROSCONSOLE_BACKEND_LOG4CXX" + ) + +# Targets to which this target links. +SET(CMAKE_TARGET_LINKED_INFO_FILES + ) diff --git a/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages_cpp.dir/build.make b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages_cpp.dir/build.make new file mode 100644 index 0000000..5b2fe3f --- /dev/null +++ b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages_cpp.dir/build.make @@ -0,0 +1,71 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/lab1_5/ws/ws_linux/src + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/lab1_5/ws/ws_linux/build + +# Utility rule file for videostream_generate_messages_cpp. + +# Include the progress variables for this target. +include videostream/CMakeFiles/videostream_generate_messages_cpp.dir/progress.make + +videostream/CMakeFiles/videostream_generate_messages_cpp: /home/lab1_5/ws/ws_linux/devel/include/videostream/ip_get.h + +/home/lab1_5/ws/ws_linux/devel/include/videostream/ip_get.h: /opt/ros/hydro/share/gencpp/cmake/../../../lib/gencpp/gen_cpp.py +/home/lab1_5/ws/ws_linux/devel/include/videostream/ip_get.h: /home/lab1_5/ws/ws_linux/src/videostream/srv/ip_get.srv +/home/lab1_5/ws/ws_linux/devel/include/videostream/ip_get.h: /opt/ros/hydro/share/gencpp/cmake/../msg.h.template +/home/lab1_5/ws/ws_linux/devel/include/videostream/ip_get.h: /opt/ros/hydro/share/gencpp/cmake/../srv.h.template + $(CMAKE_COMMAND) -E cmake_progress_report /home/lab1_5/ws/ws_linux/build/CMakeFiles $(CMAKE_PROGRESS_1) + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --blue --bold "Generating C++ code from videostream/ip_get.srv" + cd /home/lab1_5/ws/ws_linux/build/videostream && ../catkin_generated/env_cached.sh /usr/bin/python /opt/ros/hydro/share/gencpp/cmake/../../../lib/gencpp/gen_cpp.py /home/lab1_5/ws/ws_linux/src/videostream/srv/ip_get.srv -Istd_msgs:/opt/ros/hydro/share/std_msgs/cmake/../msg -p videostream -o /home/lab1_5/ws/ws_linux/devel/include/videostream -e /opt/ros/hydro/share/gencpp/cmake/.. + +videostream_generate_messages_cpp: videostream/CMakeFiles/videostream_generate_messages_cpp +videostream_generate_messages_cpp: /home/lab1_5/ws/ws_linux/devel/include/videostream/ip_get.h +videostream_generate_messages_cpp: videostream/CMakeFiles/videostream_generate_messages_cpp.dir/build.make +.PHONY : videostream_generate_messages_cpp + +# Rule to build all files generated by this target. +videostream/CMakeFiles/videostream_generate_messages_cpp.dir/build: videostream_generate_messages_cpp +.PHONY : videostream/CMakeFiles/videostream_generate_messages_cpp.dir/build + +videostream/CMakeFiles/videostream_generate_messages_cpp.dir/clean: + cd /home/lab1_5/ws/ws_linux/build/videostream && $(CMAKE_COMMAND) -P CMakeFiles/videostream_generate_messages_cpp.dir/cmake_clean.cmake +.PHONY : videostream/CMakeFiles/videostream_generate_messages_cpp.dir/clean + +videostream/CMakeFiles/videostream_generate_messages_cpp.dir/depend: + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/lab1_5/ws/ws_linux/src /home/lab1_5/ws/ws_linux/src/videostream /home/lab1_5/ws/ws_linux/build /home/lab1_5/ws/ws_linux/build/videostream /home/lab1_5/ws/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages_cpp.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : videostream/CMakeFiles/videostream_generate_messages_cpp.dir/depend + diff --git a/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages_cpp.dir/cmake_clean.cmake b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages_cpp.dir/cmake_clean.cmake new file mode 100644 index 0000000..2ca2a92 --- /dev/null +++ b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages_cpp.dir/cmake_clean.cmake @@ -0,0 +1,9 @@ +FILE(REMOVE_RECURSE + "CMakeFiles/videostream_generate_messages_cpp" + "/home/lab1_5/ws/ws_linux/devel/include/videostream/ip_get.h" +) + +# Per-language clean rules from dependency scanning. +FOREACH(lang) + INCLUDE(CMakeFiles/videostream_generate_messages_cpp.dir/cmake_clean_${lang}.cmake OPTIONAL) +ENDFOREACH(lang) diff --git a/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages_cpp.dir/depend.internal b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages_cpp.dir/depend.internal new file mode 100644 index 0000000..38eae05 --- /dev/null +++ b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages_cpp.dir/depend.internal @@ -0,0 +1,3 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + diff --git a/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages_cpp.dir/depend.make b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages_cpp.dir/depend.make new file mode 100644 index 0000000..38eae05 --- /dev/null +++ b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages_cpp.dir/depend.make @@ -0,0 +1,3 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + diff --git a/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages_cpp.dir/progress.make b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages_cpp.dir/progress.make new file mode 100644 index 0000000..a7f2629 --- /dev/null +++ b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages_cpp.dir/progress.make @@ -0,0 +1,2 @@ +CMAKE_PROGRESS_1 = 19 + diff --git a/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages_lisp.dir/DependInfo.cmake b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages_lisp.dir/DependInfo.cmake new file mode 100644 index 0000000..551e629 --- /dev/null +++ b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages_lisp.dir/DependInfo.cmake @@ -0,0 +1,15 @@ +# The set of languages for which implicit dependencies are needed: +SET(CMAKE_DEPENDS_LANGUAGES + ) +# The set of files for implicit dependencies of each language: + +# Preprocessor definitions for this target. +SET(CMAKE_TARGET_DEFINITIONS + "ROS_BUILD_SHARED_LIBS=1" + "ROS_PACKAGE_NAME=\"videostream\"" + "ROSCONSOLE_BACKEND_LOG4CXX" + ) + +# Targets to which this target links. +SET(CMAKE_TARGET_LINKED_INFO_FILES + ) diff --git a/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages_lisp.dir/build.make b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages_lisp.dir/build.make new file mode 100644 index 0000000..4e72463 --- /dev/null +++ b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages_lisp.dir/build.make @@ -0,0 +1,69 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/lab1_5/ws/ws_linux/src + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/lab1_5/ws/ws_linux/build + +# Utility rule file for videostream_generate_messages_lisp. + +# Include the progress variables for this target. +include videostream/CMakeFiles/videostream_generate_messages_lisp.dir/progress.make + +videostream/CMakeFiles/videostream_generate_messages_lisp: /home/lab1_5/ws/ws_linux/devel/share/common-lisp/ros/videostream/srv/ip_get.lisp + +/home/lab1_5/ws/ws_linux/devel/share/common-lisp/ros/videostream/srv/ip_get.lisp: /opt/ros/hydro/share/genlisp/cmake/../../../lib/genlisp/gen_lisp.py +/home/lab1_5/ws/ws_linux/devel/share/common-lisp/ros/videostream/srv/ip_get.lisp: /home/lab1_5/ws/ws_linux/src/videostream/srv/ip_get.srv + $(CMAKE_COMMAND) -E cmake_progress_report /home/lab1_5/ws/ws_linux/build/CMakeFiles $(CMAKE_PROGRESS_1) + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --blue --bold "Generating Lisp code from videostream/ip_get.srv" + cd /home/lab1_5/ws/ws_linux/build/videostream && ../catkin_generated/env_cached.sh /usr/bin/python /opt/ros/hydro/share/genlisp/cmake/../../../lib/genlisp/gen_lisp.py /home/lab1_5/ws/ws_linux/src/videostream/srv/ip_get.srv -Istd_msgs:/opt/ros/hydro/share/std_msgs/cmake/../msg -p videostream -o /home/lab1_5/ws/ws_linux/devel/share/common-lisp/ros/videostream/srv + +videostream_generate_messages_lisp: videostream/CMakeFiles/videostream_generate_messages_lisp +videostream_generate_messages_lisp: /home/lab1_5/ws/ws_linux/devel/share/common-lisp/ros/videostream/srv/ip_get.lisp +videostream_generate_messages_lisp: videostream/CMakeFiles/videostream_generate_messages_lisp.dir/build.make +.PHONY : videostream_generate_messages_lisp + +# Rule to build all files generated by this target. +videostream/CMakeFiles/videostream_generate_messages_lisp.dir/build: videostream_generate_messages_lisp +.PHONY : videostream/CMakeFiles/videostream_generate_messages_lisp.dir/build + +videostream/CMakeFiles/videostream_generate_messages_lisp.dir/clean: + cd /home/lab1_5/ws/ws_linux/build/videostream && $(CMAKE_COMMAND) -P CMakeFiles/videostream_generate_messages_lisp.dir/cmake_clean.cmake +.PHONY : videostream/CMakeFiles/videostream_generate_messages_lisp.dir/clean + +videostream/CMakeFiles/videostream_generate_messages_lisp.dir/depend: + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/lab1_5/ws/ws_linux/src /home/lab1_5/ws/ws_linux/src/videostream /home/lab1_5/ws/ws_linux/build /home/lab1_5/ws/ws_linux/build/videostream /home/lab1_5/ws/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages_lisp.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : videostream/CMakeFiles/videostream_generate_messages_lisp.dir/depend + diff --git a/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages_lisp.dir/cmake_clean.cmake b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages_lisp.dir/cmake_clean.cmake new file mode 100644 index 0000000..0a69d6b --- /dev/null +++ b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages_lisp.dir/cmake_clean.cmake @@ -0,0 +1,9 @@ +FILE(REMOVE_RECURSE + "CMakeFiles/videostream_generate_messages_lisp" + "/home/lab1_5/ws/ws_linux/devel/share/common-lisp/ros/videostream/srv/ip_get.lisp" +) + +# Per-language clean rules from dependency scanning. +FOREACH(lang) + INCLUDE(CMakeFiles/videostream_generate_messages_lisp.dir/cmake_clean_${lang}.cmake OPTIONAL) +ENDFOREACH(lang) diff --git a/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages_lisp.dir/depend.internal b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages_lisp.dir/depend.internal new file mode 100644 index 0000000..38eae05 --- /dev/null +++ b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages_lisp.dir/depend.internal @@ -0,0 +1,3 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + diff --git a/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages_lisp.dir/depend.make b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages_lisp.dir/depend.make new file mode 100644 index 0000000..38eae05 --- /dev/null +++ b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages_lisp.dir/depend.make @@ -0,0 +1,3 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + diff --git a/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages_lisp.dir/progress.make b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages_lisp.dir/progress.make new file mode 100644 index 0000000..5ec04d3 --- /dev/null +++ b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages_lisp.dir/progress.make @@ -0,0 +1,2 @@ +CMAKE_PROGRESS_1 = 20 + diff --git a/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages_py.dir/DependInfo.cmake b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages_py.dir/DependInfo.cmake new file mode 100644 index 0000000..551e629 --- /dev/null +++ b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages_py.dir/DependInfo.cmake @@ -0,0 +1,15 @@ +# The set of languages for which implicit dependencies are needed: +SET(CMAKE_DEPENDS_LANGUAGES + ) +# The set of files for implicit dependencies of each language: + +# Preprocessor definitions for this target. +SET(CMAKE_TARGET_DEFINITIONS + "ROS_BUILD_SHARED_LIBS=1" + "ROS_PACKAGE_NAME=\"videostream\"" + "ROSCONSOLE_BACKEND_LOG4CXX" + ) + +# Targets to which this target links. +SET(CMAKE_TARGET_LINKED_INFO_FILES + ) diff --git a/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages_py.dir/build.make b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages_py.dir/build.make new file mode 100644 index 0000000..c52f6c1 --- /dev/null +++ b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages_py.dir/build.make @@ -0,0 +1,77 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/lab1_5/ws/ws_linux/src + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/lab1_5/ws/ws_linux/build + +# Utility rule file for videostream_generate_messages_py. + +# Include the progress variables for this target. +include videostream/CMakeFiles/videostream_generate_messages_py.dir/progress.make + +videostream/CMakeFiles/videostream_generate_messages_py: /home/lab1_5/ws/ws_linux/devel/lib/python2.7/dist-packages/videostream/srv/_ip_get.py +videostream/CMakeFiles/videostream_generate_messages_py: /home/lab1_5/ws/ws_linux/devel/lib/python2.7/dist-packages/videostream/srv/__init__.py + +/home/lab1_5/ws/ws_linux/devel/lib/python2.7/dist-packages/videostream/srv/_ip_get.py: /opt/ros/hydro/share/genpy/cmake/../../../lib/genpy/gensrv_py.py +/home/lab1_5/ws/ws_linux/devel/lib/python2.7/dist-packages/videostream/srv/_ip_get.py: /home/lab1_5/ws/ws_linux/src/videostream/srv/ip_get.srv + $(CMAKE_COMMAND) -E cmake_progress_report /home/lab1_5/ws/ws_linux/build/CMakeFiles $(CMAKE_PROGRESS_1) + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --blue --bold "Generating Python code from SRV videostream/ip_get" + cd /home/lab1_5/ws/ws_linux/build/videostream && ../catkin_generated/env_cached.sh /usr/bin/python /opt/ros/hydro/share/genpy/cmake/../../../lib/genpy/gensrv_py.py /home/lab1_5/ws/ws_linux/src/videostream/srv/ip_get.srv -Istd_msgs:/opt/ros/hydro/share/std_msgs/cmake/../msg -p videostream -o /home/lab1_5/ws/ws_linux/devel/lib/python2.7/dist-packages/videostream/srv + +/home/lab1_5/ws/ws_linux/devel/lib/python2.7/dist-packages/videostream/srv/__init__.py: /opt/ros/hydro/share/genpy/cmake/../../../lib/genpy/genmsg_py.py +/home/lab1_5/ws/ws_linux/devel/lib/python2.7/dist-packages/videostream/srv/__init__.py: /home/lab1_5/ws/ws_linux/devel/lib/python2.7/dist-packages/videostream/srv/_ip_get.py + $(CMAKE_COMMAND) -E cmake_progress_report /home/lab1_5/ws/ws_linux/build/CMakeFiles $(CMAKE_PROGRESS_2) + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --blue --bold "Generating Python srv __init__.py for videostream" + cd /home/lab1_5/ws/ws_linux/build/videostream && ../catkin_generated/env_cached.sh /usr/bin/python /opt/ros/hydro/share/genpy/cmake/../../../lib/genpy/genmsg_py.py -o /home/lab1_5/ws/ws_linux/devel/lib/python2.7/dist-packages/videostream/srv --initpy + +videostream_generate_messages_py: videostream/CMakeFiles/videostream_generate_messages_py +videostream_generate_messages_py: /home/lab1_5/ws/ws_linux/devel/lib/python2.7/dist-packages/videostream/srv/_ip_get.py +videostream_generate_messages_py: /home/lab1_5/ws/ws_linux/devel/lib/python2.7/dist-packages/videostream/srv/__init__.py +videostream_generate_messages_py: videostream/CMakeFiles/videostream_generate_messages_py.dir/build.make +.PHONY : videostream_generate_messages_py + +# Rule to build all files generated by this target. +videostream/CMakeFiles/videostream_generate_messages_py.dir/build: videostream_generate_messages_py +.PHONY : videostream/CMakeFiles/videostream_generate_messages_py.dir/build + +videostream/CMakeFiles/videostream_generate_messages_py.dir/clean: + cd /home/lab1_5/ws/ws_linux/build/videostream && $(CMAKE_COMMAND) -P CMakeFiles/videostream_generate_messages_py.dir/cmake_clean.cmake +.PHONY : videostream/CMakeFiles/videostream_generate_messages_py.dir/clean + +videostream/CMakeFiles/videostream_generate_messages_py.dir/depend: + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/lab1_5/ws/ws_linux/src /home/lab1_5/ws/ws_linux/src/videostream /home/lab1_5/ws/ws_linux/build /home/lab1_5/ws/ws_linux/build/videostream /home/lab1_5/ws/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages_py.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : videostream/CMakeFiles/videostream_generate_messages_py.dir/depend + diff --git a/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages_py.dir/cmake_clean.cmake b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages_py.dir/cmake_clean.cmake new file mode 100644 index 0000000..e5083f3 --- /dev/null +++ b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages_py.dir/cmake_clean.cmake @@ -0,0 +1,10 @@ +FILE(REMOVE_RECURSE + "CMakeFiles/videostream_generate_messages_py" + "/home/lab1_5/ws/ws_linux/devel/lib/python2.7/dist-packages/videostream/srv/_ip_get.py" + "/home/lab1_5/ws/ws_linux/devel/lib/python2.7/dist-packages/videostream/srv/__init__.py" +) + +# Per-language clean rules from dependency scanning. +FOREACH(lang) + INCLUDE(CMakeFiles/videostream_generate_messages_py.dir/cmake_clean_${lang}.cmake OPTIONAL) +ENDFOREACH(lang) diff --git a/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages_py.dir/depend.internal b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages_py.dir/depend.internal new file mode 100644 index 0000000..38eae05 --- /dev/null +++ b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages_py.dir/depend.internal @@ -0,0 +1,3 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + diff --git a/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages_py.dir/depend.make b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages_py.dir/depend.make new file mode 100644 index 0000000..38eae05 --- /dev/null +++ b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages_py.dir/depend.make @@ -0,0 +1,3 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + diff --git a/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages_py.dir/progress.make b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages_py.dir/progress.make new file mode 100644 index 0000000..6ec2abf --- /dev/null +++ b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_generate_messages_py.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = 21 +CMAKE_PROGRESS_2 = 22 + diff --git a/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_genlisp.dir/DependInfo.cmake b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_genlisp.dir/DependInfo.cmake new file mode 100644 index 0000000..551e629 --- /dev/null +++ b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_genlisp.dir/DependInfo.cmake @@ -0,0 +1,15 @@ +# The set of languages for which implicit dependencies are needed: +SET(CMAKE_DEPENDS_LANGUAGES + ) +# The set of files for implicit dependencies of each language: + +# Preprocessor definitions for this target. +SET(CMAKE_TARGET_DEFINITIONS + "ROS_BUILD_SHARED_LIBS=1" + "ROS_PACKAGE_NAME=\"videostream\"" + "ROSCONSOLE_BACKEND_LOG4CXX" + ) + +# Targets to which this target links. +SET(CMAKE_TARGET_LINKED_INFO_FILES + ) diff --git a/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_genlisp.dir/build.make b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_genlisp.dir/build.make new file mode 100644 index 0000000..ebb72f0 --- /dev/null +++ b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_genlisp.dir/build.make @@ -0,0 +1,62 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/lab1_5/ws/ws_linux/src + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/lab1_5/ws/ws_linux/build + +# Utility rule file for videostream_genlisp. + +# Include the progress variables for this target. +include videostream/CMakeFiles/videostream_genlisp.dir/progress.make + +videostream/CMakeFiles/videostream_genlisp: + +videostream_genlisp: videostream/CMakeFiles/videostream_genlisp +videostream_genlisp: videostream/CMakeFiles/videostream_genlisp.dir/build.make +.PHONY : videostream_genlisp + +# Rule to build all files generated by this target. +videostream/CMakeFiles/videostream_genlisp.dir/build: videostream_genlisp +.PHONY : videostream/CMakeFiles/videostream_genlisp.dir/build + +videostream/CMakeFiles/videostream_genlisp.dir/clean: + cd /home/lab1_5/ws/ws_linux/build/videostream && $(CMAKE_COMMAND) -P CMakeFiles/videostream_genlisp.dir/cmake_clean.cmake +.PHONY : videostream/CMakeFiles/videostream_genlisp.dir/clean + +videostream/CMakeFiles/videostream_genlisp.dir/depend: + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/lab1_5/ws/ws_linux/src /home/lab1_5/ws/ws_linux/src/videostream /home/lab1_5/ws/ws_linux/build /home/lab1_5/ws/ws_linux/build/videostream /home/lab1_5/ws/ws_linux/build/videostream/CMakeFiles/videostream_genlisp.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : videostream/CMakeFiles/videostream_genlisp.dir/depend + diff --git a/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_genlisp.dir/cmake_clean.cmake b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_genlisp.dir/cmake_clean.cmake new file mode 100644 index 0000000..2fb088f --- /dev/null +++ b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_genlisp.dir/cmake_clean.cmake @@ -0,0 +1,8 @@ +FILE(REMOVE_RECURSE + "CMakeFiles/videostream_genlisp" +) + +# Per-language clean rules from dependency scanning. +FOREACH(lang) + INCLUDE(CMakeFiles/videostream_genlisp.dir/cmake_clean_${lang}.cmake OPTIONAL) +ENDFOREACH(lang) diff --git a/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_genlisp.dir/progress.make b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_genlisp.dir/progress.make new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_genlisp.dir/progress.make @@ -0,0 +1 @@ + diff --git a/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_genpy.dir/DependInfo.cmake b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_genpy.dir/DependInfo.cmake new file mode 100644 index 0000000..551e629 --- /dev/null +++ b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_genpy.dir/DependInfo.cmake @@ -0,0 +1,15 @@ +# The set of languages for which implicit dependencies are needed: +SET(CMAKE_DEPENDS_LANGUAGES + ) +# The set of files for implicit dependencies of each language: + +# Preprocessor definitions for this target. +SET(CMAKE_TARGET_DEFINITIONS + "ROS_BUILD_SHARED_LIBS=1" + "ROS_PACKAGE_NAME=\"videostream\"" + "ROSCONSOLE_BACKEND_LOG4CXX" + ) + +# Targets to which this target links. +SET(CMAKE_TARGET_LINKED_INFO_FILES + ) diff --git a/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_genpy.dir/build.make b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_genpy.dir/build.make new file mode 100644 index 0000000..ec4e1dc --- /dev/null +++ b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_genpy.dir/build.make @@ -0,0 +1,62 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/lab1_5/ws/ws_linux/src + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/lab1_5/ws/ws_linux/build + +# Utility rule file for videostream_genpy. + +# Include the progress variables for this target. +include videostream/CMakeFiles/videostream_genpy.dir/progress.make + +videostream/CMakeFiles/videostream_genpy: + +videostream_genpy: videostream/CMakeFiles/videostream_genpy +videostream_genpy: videostream/CMakeFiles/videostream_genpy.dir/build.make +.PHONY : videostream_genpy + +# Rule to build all files generated by this target. +videostream/CMakeFiles/videostream_genpy.dir/build: videostream_genpy +.PHONY : videostream/CMakeFiles/videostream_genpy.dir/build + +videostream/CMakeFiles/videostream_genpy.dir/clean: + cd /home/lab1_5/ws/ws_linux/build/videostream && $(CMAKE_COMMAND) -P CMakeFiles/videostream_genpy.dir/cmake_clean.cmake +.PHONY : videostream/CMakeFiles/videostream_genpy.dir/clean + +videostream/CMakeFiles/videostream_genpy.dir/depend: + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/lab1_5/ws/ws_linux/src /home/lab1_5/ws/ws_linux/src/videostream /home/lab1_5/ws/ws_linux/build /home/lab1_5/ws/ws_linux/build/videostream /home/lab1_5/ws/ws_linux/build/videostream/CMakeFiles/videostream_genpy.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : videostream/CMakeFiles/videostream_genpy.dir/depend + diff --git a/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_genpy.dir/cmake_clean.cmake b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_genpy.dir/cmake_clean.cmake new file mode 100644 index 0000000..229e3df --- /dev/null +++ b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_genpy.dir/cmake_clean.cmake @@ -0,0 +1,8 @@ +FILE(REMOVE_RECURSE + "CMakeFiles/videostream_genpy" +) + +# Per-language clean rules from dependency scanning. +FOREACH(lang) + INCLUDE(CMakeFiles/videostream_genpy.dir/cmake_clean_${lang}.cmake OPTIONAL) +ENDFOREACH(lang) diff --git a/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_genpy.dir/progress.make b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_genpy.dir/progress.make new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/Legacy/ws_linux/build/videostream/CMakeFiles/videostream_genpy.dir/progress.make @@ -0,0 +1 @@ + diff --git a/Legacy/ws_linux/build/videostream/CTestTestfile.cmake b/Legacy/ws_linux/build/videostream/CTestTestfile.cmake new file mode 100644 index 0000000..f0fb532 --- /dev/null +++ b/Legacy/ws_linux/build/videostream/CTestTestfile.cmake @@ -0,0 +1,6 @@ +# CMake generated Testfile for +# Source directory: /home/lab1_5/ws/ws_linux/src/videostream +# Build directory: /home/lab1_5/ws/ws_linux/build/videostream +# +# This file includes the relevent testing commands required for +# testing this directory and lists subdirectories to be tested as well. diff --git a/Legacy/ws_linux/build/videostream/Makefile b/Legacy/ws_linux/build/videostream/Makefile new file mode 100644 index 0000000..ed90513 --- /dev/null +++ b/Legacy/ws_linux/build/videostream/Makefile @@ -0,0 +1,322 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 2.8 + +# Default target executed when no arguments are given to make. +default_target: all +.PHONY : default_target + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/lab1_5/ws/ws_linux/src + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/lab1_5/ws/ws_linux/build + +#============================================================================= +# Targets provided globally by CMake. + +# Special rule for the target edit_cache +edit_cache: + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running interactive CMake command-line interface..." + /usr/bin/cmake -i . +.PHONY : edit_cache + +# Special rule for the target edit_cache +edit_cache/fast: edit_cache +.PHONY : edit_cache/fast + +# Special rule for the target install +install: preinstall + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Install the project..." + /usr/bin/cmake -P cmake_install.cmake +.PHONY : install + +# Special rule for the target install +install/fast: preinstall/fast + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Install the project..." + /usr/bin/cmake -P cmake_install.cmake +.PHONY : install/fast + +# Special rule for the target install/local +install/local: preinstall + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Installing only the local directory..." + /usr/bin/cmake -DCMAKE_INSTALL_LOCAL_ONLY=1 -P cmake_install.cmake +.PHONY : install/local + +# Special rule for the target install/local +install/local/fast: install/local +.PHONY : install/local/fast + +# Special rule for the target install/strip +install/strip: preinstall + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Installing the project stripped..." + /usr/bin/cmake -DCMAKE_INSTALL_DO_STRIP=1 -P cmake_install.cmake +.PHONY : install/strip + +# Special rule for the target install/strip +install/strip/fast: install/strip +.PHONY : install/strip/fast + +# Special rule for the target list_install_components +list_install_components: + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Available install components are: \"Unspecified\"" +.PHONY : list_install_components + +# Special rule for the target list_install_components +list_install_components/fast: list_install_components +.PHONY : list_install_components/fast + +# Special rule for the target rebuild_cache +rebuild_cache: + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running CMake to regenerate build system..." + /usr/bin/cmake -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) +.PHONY : rebuild_cache + +# Special rule for the target rebuild_cache +rebuild_cache/fast: rebuild_cache +.PHONY : rebuild_cache/fast + +# Special rule for the target test +test: + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running tests..." + /usr/bin/ctest --force-new-ctest-process $(ARGS) +.PHONY : test + +# Special rule for the target test +test/fast: test +.PHONY : test/fast + +# The main all target +all: cmake_check_build_system + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -E cmake_progress_start /home/lab1_5/ws/ws_linux/build/CMakeFiles /home/lab1_5/ws/ws_linux/build/videostream/CMakeFiles/progress.marks + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 videostream/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/lab1_5/ws/ws_linux/build/CMakeFiles 0 +.PHONY : all + +# The main clean target +clean: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 videostream/clean +.PHONY : clean + +# The main clean target +clean/fast: clean +.PHONY : clean/fast + +# Prepare targets for installation. +preinstall: all + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 videostream/preinstall +.PHONY : preinstall + +# Prepare targets for installation. +preinstall/fast: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 videostream/preinstall +.PHONY : preinstall/fast + +# clear depends +depend: + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 1 +.PHONY : depend + +# Convenience name for target. +videostream/CMakeFiles/videostream.dir/rule: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 videostream/CMakeFiles/videostream.dir/rule +.PHONY : videostream/CMakeFiles/videostream.dir/rule + +# Convenience name for target. +videostream: videostream/CMakeFiles/videostream.dir/rule +.PHONY : videostream + +# fast build rule for target. +videostream/fast: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f videostream/CMakeFiles/videostream.dir/build.make videostream/CMakeFiles/videostream.dir/build +.PHONY : videostream/fast + +# Convenience name for target. +videostream/CMakeFiles/videostream_gencpp.dir/rule: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 videostream/CMakeFiles/videostream_gencpp.dir/rule +.PHONY : videostream/CMakeFiles/videostream_gencpp.dir/rule + +# Convenience name for target. +videostream_gencpp: videostream/CMakeFiles/videostream_gencpp.dir/rule +.PHONY : videostream_gencpp + +# fast build rule for target. +videostream_gencpp/fast: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f videostream/CMakeFiles/videostream_gencpp.dir/build.make videostream/CMakeFiles/videostream_gencpp.dir/build +.PHONY : videostream_gencpp/fast + +# Convenience name for target. +videostream/CMakeFiles/videostream_generate_messages.dir/rule: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 videostream/CMakeFiles/videostream_generate_messages.dir/rule +.PHONY : videostream/CMakeFiles/videostream_generate_messages.dir/rule + +# Convenience name for target. +videostream_generate_messages: videostream/CMakeFiles/videostream_generate_messages.dir/rule +.PHONY : videostream_generate_messages + +# fast build rule for target. +videostream_generate_messages/fast: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f videostream/CMakeFiles/videostream_generate_messages.dir/build.make videostream/CMakeFiles/videostream_generate_messages.dir/build +.PHONY : videostream_generate_messages/fast + +# Convenience name for target. +videostream/CMakeFiles/videostream_generate_messages_cpp.dir/rule: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 videostream/CMakeFiles/videostream_generate_messages_cpp.dir/rule +.PHONY : videostream/CMakeFiles/videostream_generate_messages_cpp.dir/rule + +# Convenience name for target. +videostream_generate_messages_cpp: videostream/CMakeFiles/videostream_generate_messages_cpp.dir/rule +.PHONY : videostream_generate_messages_cpp + +# fast build rule for target. +videostream_generate_messages_cpp/fast: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f videostream/CMakeFiles/videostream_generate_messages_cpp.dir/build.make videostream/CMakeFiles/videostream_generate_messages_cpp.dir/build +.PHONY : videostream_generate_messages_cpp/fast + +# Convenience name for target. +videostream/CMakeFiles/videostream_generate_messages_lisp.dir/rule: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 videostream/CMakeFiles/videostream_generate_messages_lisp.dir/rule +.PHONY : videostream/CMakeFiles/videostream_generate_messages_lisp.dir/rule + +# Convenience name for target. +videostream_generate_messages_lisp: videostream/CMakeFiles/videostream_generate_messages_lisp.dir/rule +.PHONY : videostream_generate_messages_lisp + +# fast build rule for target. +videostream_generate_messages_lisp/fast: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f videostream/CMakeFiles/videostream_generate_messages_lisp.dir/build.make videostream/CMakeFiles/videostream_generate_messages_lisp.dir/build +.PHONY : videostream_generate_messages_lisp/fast + +# Convenience name for target. +videostream/CMakeFiles/videostream_generate_messages_py.dir/rule: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 videostream/CMakeFiles/videostream_generate_messages_py.dir/rule +.PHONY : videostream/CMakeFiles/videostream_generate_messages_py.dir/rule + +# Convenience name for target. +videostream_generate_messages_py: videostream/CMakeFiles/videostream_generate_messages_py.dir/rule +.PHONY : videostream_generate_messages_py + +# fast build rule for target. +videostream_generate_messages_py/fast: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f videostream/CMakeFiles/videostream_generate_messages_py.dir/build.make videostream/CMakeFiles/videostream_generate_messages_py.dir/build +.PHONY : videostream_generate_messages_py/fast + +# Convenience name for target. +videostream/CMakeFiles/videostream_genlisp.dir/rule: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 videostream/CMakeFiles/videostream_genlisp.dir/rule +.PHONY : videostream/CMakeFiles/videostream_genlisp.dir/rule + +# Convenience name for target. +videostream_genlisp: videostream/CMakeFiles/videostream_genlisp.dir/rule +.PHONY : videostream_genlisp + +# fast build rule for target. +videostream_genlisp/fast: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f videostream/CMakeFiles/videostream_genlisp.dir/build.make videostream/CMakeFiles/videostream_genlisp.dir/build +.PHONY : videostream_genlisp/fast + +# Convenience name for target. +videostream/CMakeFiles/videostream_genpy.dir/rule: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f CMakeFiles/Makefile2 videostream/CMakeFiles/videostream_genpy.dir/rule +.PHONY : videostream/CMakeFiles/videostream_genpy.dir/rule + +# Convenience name for target. +videostream_genpy: videostream/CMakeFiles/videostream_genpy.dir/rule +.PHONY : videostream_genpy + +# fast build rule for target. +videostream_genpy/fast: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f videostream/CMakeFiles/videostream_genpy.dir/build.make videostream/CMakeFiles/videostream_genpy.dir/build +.PHONY : videostream_genpy/fast + +src/videostream.o: src/videostream.cpp.o +.PHONY : src/videostream.o + +# target to build an object file +src/videostream.cpp.o: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f videostream/CMakeFiles/videostream.dir/build.make videostream/CMakeFiles/videostream.dir/src/videostream.cpp.o +.PHONY : src/videostream.cpp.o + +src/videostream.i: src/videostream.cpp.i +.PHONY : src/videostream.i + +# target to preprocess a source file +src/videostream.cpp.i: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f videostream/CMakeFiles/videostream.dir/build.make videostream/CMakeFiles/videostream.dir/src/videostream.cpp.i +.PHONY : src/videostream.cpp.i + +src/videostream.s: src/videostream.cpp.s +.PHONY : src/videostream.s + +# target to generate assembly for a file +src/videostream.cpp.s: + cd /home/lab1_5/ws/ws_linux/build && $(MAKE) -f videostream/CMakeFiles/videostream.dir/build.make videostream/CMakeFiles/videostream.dir/src/videostream.cpp.s +.PHONY : src/videostream.cpp.s + +# Help Target +help: + @echo "The following are some of the valid targets for this Makefile:" + @echo "... all (the default if no target is provided)" + @echo "... clean" + @echo "... depend" + @echo "... edit_cache" + @echo "... install" + @echo "... install/local" + @echo "... install/strip" + @echo "... list_install_components" + @echo "... rebuild_cache" + @echo "... test" + @echo "... videostream" + @echo "... videostream_gencpp" + @echo "... videostream_generate_messages" + @echo "... videostream_generate_messages_cpp" + @echo "... videostream_generate_messages_lisp" + @echo "... videostream_generate_messages_py" + @echo "... videostream_genlisp" + @echo "... videostream_genpy" + @echo "... src/videostream.o" + @echo "... src/videostream.i" + @echo "... src/videostream.s" +.PHONY : help + + + +#============================================================================= +# Special targets to cleanup operation of make. + +# Special rule to run CMake to check the build system integrity. +# No rule that depends on this can have commands that come from listfiles +# because they might be regenerated. +cmake_check_build_system: + cd /home/lab1_5/ws/ws_linux/build && $(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 0 +.PHONY : cmake_check_build_system + diff --git a/Legacy/ws_linux/build/videostream/catkin_generated/installspace/videostream-msg-extras.cmake b/Legacy/ws_linux/build/videostream/catkin_generated/installspace/videostream-msg-extras.cmake new file mode 100644 index 0000000..9dd80d4 --- /dev/null +++ b/Legacy/ws_linux/build/videostream/catkin_generated/installspace/videostream-msg-extras.cmake @@ -0,0 +1,2 @@ +set(videostream_MESSAGE_FILES "") +set(videostream_SERVICE_FILES "srv/ip_get.srv") diff --git a/Legacy/ws_linux/build/videostream/catkin_generated/installspace/videostream-msg-paths-context.py b/Legacy/ws_linux/build/videostream/catkin_generated/installspace/videostream-msg-paths-context.py new file mode 100644 index 0000000..72bf22e --- /dev/null +++ b/Legacy/ws_linux/build/videostream/catkin_generated/installspace/videostream-msg-paths-context.py @@ -0,0 +1,8 @@ +# generated from genmsg/cmake/pkg-msg-paths.context.in + +DEVELSPACE = 'FALSE' == 'TRUE' +INSTALLSPACE = 'TRUE' == 'TRUE' + +PROJECT_NAME = 'videostream' +PKG_MSG_INCLUDE_DIRS = '' +ARG_DEPENDENCIES = 'std_msgs' diff --git a/Legacy/ws_linux/build/videostream/catkin_generated/installspace/videostream-msg-paths.cmake b/Legacy/ws_linux/build/videostream/catkin_generated/installspace/videostream-msg-paths.cmake new file mode 100644 index 0000000..a510aa0 --- /dev/null +++ b/Legacy/ws_linux/build/videostream/catkin_generated/installspace/videostream-msg-paths.cmake @@ -0,0 +1,5 @@ +# generated from genmsg/cmake/pkg-msg-paths.cmake.em + +# message include dirs in installspace +_prepend_path("${videostream_DIR}/.." "" videostream_MSG_INCLUDE_DIRS UNIQUE) +set(videostream_MSG_DEPENDENCIES std_msgs) diff --git a/Legacy/ws_linux/build/videostream/catkin_generated/installspace/videostream.pc b/Legacy/ws_linux/build/videostream/catkin_generated/installspace/videostream.pc new file mode 100644 index 0000000..b7319e7 --- /dev/null +++ b/Legacy/ws_linux/build/videostream/catkin_generated/installspace/videostream.pc @@ -0,0 +1,8 @@ +prefix=/home/lab1_5/ws/ws_linux/install + +Name: videostream +Description: Description of videostream +Version: 0.0.0 +Cflags: -I/home/lab1_5/ws/ws_linux/install/include +Libs: -L/home/lab1_5/ws/ws_linux/install/lib -lvideostream +Requires: message_runtime roscpp rospy std_msgs diff --git a/Legacy/ws_linux/build/videostream/catkin_generated/installspace/videostreamConfig-version.cmake b/Legacy/ws_linux/build/videostream/catkin_generated/installspace/videostreamConfig-version.cmake new file mode 100644 index 0000000..7fd9f99 --- /dev/null +++ b/Legacy/ws_linux/build/videostream/catkin_generated/installspace/videostreamConfig-version.cmake @@ -0,0 +1,14 @@ +# generated from catkin/cmake/template/pkgConfig-version.cmake.in +set(PACKAGE_VERSION "0.0.0") + +set(PACKAGE_VERSION_EXACT False) +set(PACKAGE_VERSION_COMPATIBLE False) + +if("${PACKAGE_FIND_VERSION}" VERSION_EQUAL "${PACKAGE_VERSION}") + set(PACKAGE_VERSION_EXACT True) + set(PACKAGE_VERSION_COMPATIBLE True) +endif() + +if("${PACKAGE_FIND_VERSION}" VERSION_LESS "${PACKAGE_VERSION}") + set(PACKAGE_VERSION_COMPATIBLE True) +endif() diff --git a/Legacy/ws_linux/build/videostream/catkin_generated/installspace/videostreamConfig.cmake b/Legacy/ws_linux/build/videostream/catkin_generated/installspace/videostreamConfig.cmake new file mode 100644 index 0000000..67cd4c1 --- /dev/null +++ b/Legacy/ws_linux/build/videostream/catkin_generated/installspace/videostreamConfig.cmake @@ -0,0 +1,191 @@ +# generated from catkin/cmake/template/pkgConfig.cmake.in + +# append elements to a list and remove existing duplicates from the list +# copied from catkin/cmake/list_append_deduplicate.cmake to keep pkgConfig +# self contained +macro(_list_append_deduplicate listname) + if(NOT "${ARGN}" STREQUAL "") + if(${listname}) + list(REMOVE_ITEM ${listname} ${ARGN}) + endif() + list(APPEND ${listname} ${ARGN}) + endif() +endmacro() + +# append elements to a list if they are not already in the list +# copied from catkin/cmake/list_append_unique.cmake to keep pkgConfig +# self contained +macro(_list_append_unique listname) + foreach(_item ${ARGN}) + list(FIND ${listname} ${_item} _index) + if(_index EQUAL -1) + list(APPEND ${listname} ${_item}) + endif() + endforeach() +endmacro() + +# pack a list of libraries with optional build configuration keywords +# copied from catkin/cmake/catkin_libraries.cmake to keep pkgConfig +# self contained +macro(_pack_libraries_with_build_configuration VAR) + set(${VAR} "") + set(_argn ${ARGN}) + list(LENGTH _argn _count) + set(_index 0) + while(${_index} LESS ${_count}) + list(GET _argn ${_index} lib) + if("${lib}" MATCHES "^debug|optimized|general$") + math(EXPR _index "${_index} + 1") + if(${_index} EQUAL ${_count}) + message(FATAL_ERROR "_pack_libraries_with_build_configuration() the list of libraries '${ARGN}' ends with '${lib}' which is a build configuration keyword and must be followed by a library") + endif() + list(GET _argn ${_index} library) + list(APPEND ${VAR} "${lib}${CATKIN_BUILD_CONFIGURATION_KEYWORD_SEPARATOR}${library}") + else() + list(APPEND ${VAR} "${lib}") + endif() + math(EXPR _index "${_index} + 1") + endwhile() +endmacro() + +# unpack a list of libraries with optional build configuration keyword prefixes +# copied from catkin/cmake/catkin_libraries.cmake to keep pkgConfig +# self contained +macro(_unpack_libraries_with_build_configuration VAR) + set(${VAR} "") + foreach(lib ${ARGN}) + string(REGEX REPLACE "^(debug|optimized|general)${CATKIN_BUILD_CONFIGURATION_KEYWORD_SEPARATOR}(.+)$" "\\1;\\2" lib "${lib}") + list(APPEND ${VAR} "${lib}") + endforeach() +endmacro() + + +if(videostream_CONFIG_INCLUDED) + return() +endif() +set(videostream_CONFIG_INCLUDED TRUE) + +# set variables for source/devel/install prefixes +if("FALSE" STREQUAL "TRUE") + set(videostream_SOURCE_PREFIX /home/lab1_5/ws/ws_linux/src/videostream) + set(videostream_DEVEL_PREFIX /home/lab1_5/ws/ws_linux/devel) + set(videostream_INSTALL_PREFIX "") + set(videostream_PREFIX ${videostream_DEVEL_PREFIX}) +else() + set(videostream_SOURCE_PREFIX "") + set(videostream_DEVEL_PREFIX "") + set(videostream_INSTALL_PREFIX /home/lab1_5/ws/ws_linux/install) + set(videostream_PREFIX ${videostream_INSTALL_PREFIX}) +endif() + +# warn when using a deprecated package +if(NOT "" STREQUAL "") + set(_msg "WARNING: package 'videostream' is deprecated") + # append custom deprecation text if available + if(NOT "" STREQUAL "TRUE") + set(_msg "${_msg} ()") + endif() + message("${_msg}") +endif() + +# flag project as catkin-based to distinguish if a find_package()-ed project is a catkin project +set(videostream_FOUND_CATKIN_PROJECT TRUE) + +if(NOT "include" STREQUAL "") + set(videostream_INCLUDE_DIRS "") + set(_include_dirs "include") + foreach(idir ${_include_dirs}) + if(IS_ABSOLUTE ${idir} AND IS_DIRECTORY ${idir}) + set(include ${idir}) + elseif("${idir}" STREQUAL "include") + get_filename_component(include "${videostream_DIR}/../../../include" ABSOLUTE) + if(NOT IS_DIRECTORY ${include}) + message(FATAL_ERROR "Project 'videostream' specifies '${idir}' as an include dir, which is not found. It does not exist in '${include}'. Ask the maintainer 'lab ' to fix it.") + endif() + else() + message(FATAL_ERROR "Project 'videostream' specifies '${idir}' as an include dir, which is not found. It does neither exist as an absolute directory nor in '/home/lab1_5/ws/ws_linux/install/${idir}'. Ask the maintainer 'lab ' to fix it.") + endif() + _list_append_unique(videostream_INCLUDE_DIRS ${include}) + endforeach() +endif() + +set(libraries "videostream") +foreach(library ${libraries}) + # keep build configuration keywords, target names and absolute libraries as-is + if("${library}" MATCHES "^debug|optimized|general$") + list(APPEND videostream_LIBRARIES ${library}) + elseif(TARGET ${library}) + list(APPEND videostream_LIBRARIES ${library}) + elseif(IS_ABSOLUTE ${library}) + list(APPEND videostream_LIBRARIES ${library}) + else() + set(lib_path "") + set(lib "${library}-NOTFOUND") + # since the path where the library is found is returned we have to iterate over the paths manually + foreach(path /home/lab1_5/ws/ws_linux/install/lib;/home/lab1_5/ws/ws_linux/devel/lib;/home/lab1_5/ws/ws_xeno/devel/lib;/home/lab1_5/ws/ws_isolated/install_isolated/lib;/opt/ros/hydro/lib) + find_library(lib ${library} + PATHS ${path} + NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH) + if(lib) + set(lib_path ${path}) + break() + endif() + endforeach() + if(lib) + _list_append_unique(videostream_LIBRARY_DIRS ${lib_path}) + list(APPEND videostream_LIBRARIES ${lib}) + else() + # as a fall back for non-catkin libraries try to search globally + find_library(lib ${library}) + if(NOT lib) + message(FATAL_ERROR "Project '${PROJECT_NAME}' tried to find library '${library}'. The library is neither a target nor built/installed properly. Did you compile project 'videostream'? Did you find_package() it before the subdirectory containing its code is included?") + endif() + list(APPEND videostream_LIBRARIES ${lib}) + endif() + endif() +endforeach() + +set(videostream_EXPORTED_TARGETS "videostream_generate_messages_cpp;videostream_generate_messages_lisp;videostream_generate_messages_py") +# create dummy targets for exported code generation targets to make life of users easier +foreach(t ${videostream_EXPORTED_TARGETS}) + if(NOT TARGET ${t}) + add_custom_target(${t}) + endif() +endforeach() + +set(depends "message_runtime;roscpp;rospy;std_msgs") +foreach(depend ${depends}) + string(REPLACE " " ";" depend_list ${depend}) + # the package name of the dependency must be kept in a unique variable so that it is not overwritten in recursive calls + list(GET depend_list 0 videostream_dep) + list(LENGTH depend_list count) + if(${count} EQUAL 1) + # simple dependencies must only be find_package()-ed once + if(NOT ${videostream_dep}_FOUND) + find_package(${videostream_dep} REQUIRED) + endif() + else() + # dependencies with components must be find_package()-ed again + list(REMOVE_AT depend_list 0) + find_package(${videostream_dep} REQUIRED ${depend_list}) + endif() + _list_append_unique(videostream_INCLUDE_DIRS ${${videostream_dep}_INCLUDE_DIRS}) + + # merge build configuration keywords with library names to correctly deduplicate + _pack_libraries_with_build_configuration(videostream_LIBRARIES ${videostream_LIBRARIES}) + _pack_libraries_with_build_configuration(_libraries ${${videostream_dep}_LIBRARIES}) + _list_append_deduplicate(videostream_LIBRARIES ${_libraries}) + # undo build configuration keyword merging after deduplication + _unpack_libraries_with_build_configuration(videostream_LIBRARIES ${videostream_LIBRARIES}) + + _list_append_unique(videostream_LIBRARY_DIRS ${${videostream_dep}_LIBRARY_DIRS}) + list(APPEND videostream_EXPORTED_TARGETS ${${videostream_dep}_EXPORTED_TARGETS}) +endforeach() + +set(pkg_cfg_extras "videostream-msg-extras.cmake") +foreach(extra ${pkg_cfg_extras}) + if(NOT IS_ABSOLUTE ${extra}) + set(extra ${videostream_DIR}/${extra}) + endif() + include(${extra}) +endforeach() diff --git a/Legacy/ws_linux/build/videostream/catkin_generated/ordered_paths.cmake b/Legacy/ws_linux/build/videostream/catkin_generated/ordered_paths.cmake new file mode 100644 index 0000000..3b5d318 --- /dev/null +++ b/Legacy/ws_linux/build/videostream/catkin_generated/ordered_paths.cmake @@ -0,0 +1 @@ +set(ORDERED_PATHS "/opt/ros/hydro/lib") \ No newline at end of file diff --git a/Legacy/ws_linux/build/videostream/catkin_generated/package.cmake b/Legacy/ws_linux/build/videostream/catkin_generated/package.cmake new file mode 100644 index 0000000..98f53c3 --- /dev/null +++ b/Legacy/ws_linux/build/videostream/catkin_generated/package.cmake @@ -0,0 +1,7 @@ +set(_CATKIN_CURRENT_PACKAGE "videostream") +set(videostream_MAINTAINER "lab ") +set(videostream_DEPRECATED "") +set(videostream_VERSION "0.0.0") +set(videostream_BUILD_DEPENDS "message_generation" "roscpp" "rospy" "std_msgs") +set(videostream_RUN_DEPENDS "message_runtime" "roscpp" "rospy" "std_msgs") +set(videostream_BUILDTOOL_DEPENDS "catkin") \ No newline at end of file diff --git a/Legacy/ws_linux/build/videostream/catkin_generated/pkg.develspace.context.pc.py b/Legacy/ws_linux/build/videostream/catkin_generated/pkg.develspace.context.pc.py new file mode 100644 index 0000000..d980cc0 --- /dev/null +++ b/Legacy/ws_linux/build/videostream/catkin_generated/pkg.develspace.context.pc.py @@ -0,0 +1,8 @@ +# generated from catkin/cmake/template/pkg.context.pc.in +CATKIN_PACKAGE_PREFIX = "" +PROJECT_PKG_CONFIG_INCLUDE_DIRS = "/home/lab1_5/ws/ws_linux/devel/include;/home/lab1_5/ws/ws_linux/src/videostream/include".split(';') if "/home/lab1_5/ws/ws_linux/devel/include;/home/lab1_5/ws/ws_linux/src/videostream/include" != "" else [] +PROJECT_CATKIN_DEPENDS = "message_runtime;roscpp;rospy;std_msgs".replace(';', ' ') +PKG_CONFIG_LIBRARIES_WITH_PREFIX = "-lvideostream".split(';') if "-lvideostream" != "" else [] +PROJECT_NAME = "videostream" +PROJECT_SPACE_DIR = "/home/lab1_5/ws/ws_linux/devel" +PROJECT_VERSION = "0.0.0" diff --git a/Legacy/ws_linux/build/videostream/catkin_generated/pkg.installspace.context.pc.py b/Legacy/ws_linux/build/videostream/catkin_generated/pkg.installspace.context.pc.py new file mode 100644 index 0000000..f13b486 --- /dev/null +++ b/Legacy/ws_linux/build/videostream/catkin_generated/pkg.installspace.context.pc.py @@ -0,0 +1,8 @@ +# generated from catkin/cmake/template/pkg.context.pc.in +CATKIN_PACKAGE_PREFIX = "" +PROJECT_PKG_CONFIG_INCLUDE_DIRS = "/home/lab1_5/ws/ws_linux/install/include".split(';') if "/home/lab1_5/ws/ws_linux/install/include" != "" else [] +PROJECT_CATKIN_DEPENDS = "message_runtime;roscpp;rospy;std_msgs".replace(';', ' ') +PKG_CONFIG_LIBRARIES_WITH_PREFIX = "-lvideostream".split(';') if "-lvideostream" != "" else [] +PROJECT_NAME = "videostream" +PROJECT_SPACE_DIR = "/home/lab1_5/ws/ws_linux/install" +PROJECT_VERSION = "0.0.0" diff --git a/Legacy/ws_linux/build/videostream/catkin_generated/stamps/videostream/package.xml.stamp b/Legacy/ws_linux/build/videostream/catkin_generated/stamps/videostream/package.xml.stamp new file mode 100644 index 0000000..fefd5f1 --- /dev/null +++ b/Legacy/ws_linux/build/videostream/catkin_generated/stamps/videostream/package.xml.stamp @@ -0,0 +1,59 @@ + + + videostream + 0.0.0 + The videostream package + + + + + lab + + + + + + TODO + + + + + + + + + + + + + + + + + + + message_generation + + + + message_runtime + + + catkin + roscpp + rospy + std_msgs + roscpp + rospy + std_msgs + + + + + + + + + + + diff --git a/Legacy/ws_linux/build/videostream/catkin_generated/stamps/videostream/pkg-genmsg.cmake.em.stamp b/Legacy/ws_linux/build/videostream/catkin_generated/stamps/videostream/pkg-genmsg.cmake.em.stamp new file mode 100644 index 0000000..5182859 --- /dev/null +++ b/Legacy/ws_linux/build/videostream/catkin_generated/stamps/videostream/pkg-genmsg.cmake.em.stamp @@ -0,0 +1,141 @@ +# generated from genmsg/cmake/pkg-genmsg.cmake.em + +@{ +import os +import sys + +import genmsg +import genmsg.base +genmsg.base.log_verbose('GENMSG_VERBOSE' in os.environ) +import genmsg.deps +import genmsg.gentools + +# split incoming variables +messages = messages_str.split(';') if messages_str != '' else [] +services = services_str.split(';') if services_str != '' else [] +dependencies = dependencies_str.split(';') if dependencies_str != '' else [] +dep_search_paths = dep_include_paths_str.split(';') if dep_include_paths_str != '' else [] + +dep_search_paths_dict = {} +dep_search_paths_tuple_list = [] +is_even = True +for val in dep_search_paths: + if is_even: + dep_search_paths_dict.setdefault(val, []) + val_prev = val + is_even = False + else: + dep_search_paths_dict[val_prev].append(val) + dep_search_paths_tuple_list.append((val_prev, val)) + is_even = True +dep_search_paths = dep_search_paths_dict + +if not messages and not services: + print('message(WARNING "Invoking generate_messages() without having added any message or service file before.\nYou should either add add_message_files() and/or add_service_files() calls or remove the invocation of generate_messages().")') + +msg_deps = {} +for m in messages: + try: + msg_deps[m] = genmsg.deps.find_msg_dependencies(pkg_name, m, dep_search_paths) + except genmsg.MsgNotFound as e: + print('message(FATAL_ERROR "Could not find messages which \'%s\' depends on. Did you forget to specify generate_messages(DEPENDENCIES ...)?\n%s")' % (m, str(e))) + +srv_deps = {} +for s in services: + try: + srv_deps[s] = genmsg.deps.find_srv_dependencies(pkg_name, s, dep_search_paths) + except genmsg.MsgNotFound as e: + print('message(FATAL_ERROR "Could not find messages which \'%s\' depends on. Did you forget to specify generate_messages(DEPENDENCIES ...)?\n%s")' % (s, str(e))) + +}@ +message(STATUS "@(pkg_name): @(len(messages)) messages, @(len(services)) services") + +set(MSG_I_FLAGS "@(';'.join(["-I%s:%s" % (dep, dir) for dep, dir in dep_search_paths_tuple_list]))") + +# Find all generators +@[if langs]@ +@[for l in langs.split(';')]@ +find_package(@l REQUIRED) +@[end for]@ +@[end if]@ + +add_custom_target(@(pkg_name)_generate_messages ALL) + +# +# langs = @langs +# + +@[if langs]@ +@[for l in langs.split(';')]@ +### Section generating for lang: @l +### Generating Messages +@[for m in msg_deps.keys()]@ +_generate_msg_@(l[3:])(@pkg_name + "@m" + "${MSG_I_FLAGS}" + "@(';'.join(msg_deps[m]).replace("\\","/"))" + ${CATKIN_DEVEL_PREFIX}/${@(l)_INSTALL_DIR}/@pkg_name +) +@[end for]@# messages + +### Generating Services +@[for s in srv_deps.keys()]@ +_generate_srv_@(l[3:])(@pkg_name + "@s" + "${MSG_I_FLAGS}" + "@(';'.join(srv_deps[s]).replace("\\","/"))" + ${CATKIN_DEVEL_PREFIX}/${@(l)_INSTALL_DIR}/@pkg_name +) +@[end for]@# services + +### Generating Module File +_generate_module_@(l[3:])(@pkg_name + ${CATKIN_DEVEL_PREFIX}/${@(l)_INSTALL_DIR}/@pkg_name + "${ALL_GEN_OUTPUT_FILES_@(l[3:])}" +) + +add_custom_target(@(pkg_name)_generate_messages_@(l[3:]) + DEPENDS ${ALL_GEN_OUTPUT_FILES_@(l[3:])} +) +add_dependencies(@(pkg_name)_generate_messages @(pkg_name)_generate_messages_@(l[3:])) + +# target for backward compatibility +add_custom_target(@(pkg_name)_@(l)) +add_dependencies(@(pkg_name)_@(l) @(pkg_name)_generate_messages_@(l[3:])) + +# register target for catkin_package(EXPORTED_TARGETS) +list(APPEND ${PROJECT_NAME}_EXPORTED_TARGETS @(pkg_name)_generate_messages_@(l[3:])) + +@[end for]@# langs +@[end if]@ + +@[if langs]@ +@[for l in langs.split(';')]@ + +if(@(l)_INSTALL_DIR AND EXISTS ${CATKIN_DEVEL_PREFIX}/${@(l)_INSTALL_DIR}/@pkg_name) +@[if l == 'genpy']@ + install(CODE "execute_process(COMMAND \"@(PYTHON_EXECUTABLE)\" -m compileall \"${CATKIN_DEVEL_PREFIX}/${@(l)_INSTALL_DIR}/@pkg_name\")") +@[end if]@ + # install generated code + install( + DIRECTORY ${CATKIN_DEVEL_PREFIX}/${@(l)_INSTALL_DIR}/@pkg_name + DESTINATION ${@(l)_INSTALL_DIR} +@[if l == 'genpy' and package_has_static_sources]@ + # skip all init files + PATTERN "__init__.py" EXCLUDE + PATTERN "__init__.pyc" EXCLUDE + ) + # install init files which are not in the root folder of the generated code + install( + DIRECTORY ${CATKIN_DEVEL_PREFIX}/${@(l)_INSTALL_DIR}/@pkg_name + DESTINATION ${@(l)_INSTALL_DIR} + FILES_MATCHING + REGEX "${CATKIN_DEVEL_PREFIX}/${@(l)_INSTALL_DIR}/@(pkg_name)/.+/__init__.pyc?$" +@[end if]@ + ) +endif() +@[for d in dependencies]@ +add_dependencies(@(pkg_name)_generate_messages_@(l[3:]) @(d)_generate_messages_@(l[3:])) +@[end for]@# dependencies +@[end for]@# langs +@[end if]@ diff --git a/Legacy/ws_linux/build/videostream/catkin_generated/stamps/videostream/pkg-msg-paths.cmake.em.stamp b/Legacy/ws_linux/build/videostream/catkin_generated/stamps/videostream/pkg-msg-paths.cmake.em.stamp new file mode 100644 index 0000000..eb6f88a --- /dev/null +++ b/Legacy/ws_linux/build/videostream/catkin_generated/stamps/videostream/pkg-msg-paths.cmake.em.stamp @@ -0,0 +1,10 @@ +# generated from genmsg/cmake/pkg-msg-paths.cmake.em + +@[if DEVELSPACE]@ +# message include dirs in develspace +set(@(PROJECT_NAME)_MSG_INCLUDE_DIRS "@(PKG_MSG_INCLUDE_DIRS)") +@[else]@ +# message include dirs in installspace +_prepend_path("${@(PROJECT_NAME)_DIR}/.." "@(PKG_MSG_INCLUDE_DIRS)" @(PROJECT_NAME)_MSG_INCLUDE_DIRS UNIQUE) +@[end if]@ +set(@(PROJECT_NAME)_MSG_DEPENDENCIES @(ARG_DEPENDENCIES)) diff --git a/Legacy/ws_linux/build/videostream/catkin_generated/stamps/videostream/pkg.pc.em.stamp b/Legacy/ws_linux/build/videostream/catkin_generated/stamps/videostream/pkg.pc.em.stamp new file mode 100644 index 0000000..a4f7257 --- /dev/null +++ b/Legacy/ws_linux/build/videostream/catkin_generated/stamps/videostream/pkg.pc.em.stamp @@ -0,0 +1,8 @@ +prefix=@PROJECT_SPACE_DIR + +Name: @(CATKIN_PACKAGE_PREFIX + PROJECT_NAME) +Description: Description of @PROJECT_NAME +Version: @PROJECT_VERSION +Cflags: @(' '.join(['-I%s' % include for include in PROJECT_PKG_CONFIG_INCLUDE_DIRS])) +Libs: -L@PROJECT_SPACE_DIR/lib @(' '.join(PKG_CONFIG_LIBRARIES_WITH_PREFIX)) +Requires: @(PROJECT_CATKIN_DEPENDS) diff --git a/Legacy/ws_linux/build/videostream/catkin_generated/videostream-msg-extras.cmake.develspace.in b/Legacy/ws_linux/build/videostream/catkin_generated/videostream-msg-extras.cmake.develspace.in new file mode 100644 index 0000000..ea194e9 --- /dev/null +++ b/Legacy/ws_linux/build/videostream/catkin_generated/videostream-msg-extras.cmake.develspace.in @@ -0,0 +1,2 @@ +set(videostream_MESSAGE_FILES "") +set(videostream_SERVICE_FILES "/home/lab1_5/ws/ws_linux/src/videostream/srv/ip_get.srv") diff --git a/Legacy/ws_linux/build/videostream/catkin_generated/videostream-msg-extras.cmake.installspace.in b/Legacy/ws_linux/build/videostream/catkin_generated/videostream-msg-extras.cmake.installspace.in new file mode 100644 index 0000000..9dd80d4 --- /dev/null +++ b/Legacy/ws_linux/build/videostream/catkin_generated/videostream-msg-extras.cmake.installspace.in @@ -0,0 +1,2 @@ +set(videostream_MESSAGE_FILES "") +set(videostream_SERVICE_FILES "srv/ip_get.srv") diff --git a/Legacy/ws_linux/build/videostream/catkin_generated/videostream-msg-paths-context.py b/Legacy/ws_linux/build/videostream/catkin_generated/videostream-msg-paths-context.py new file mode 100644 index 0000000..7f91d1d --- /dev/null +++ b/Legacy/ws_linux/build/videostream/catkin_generated/videostream-msg-paths-context.py @@ -0,0 +1,8 @@ +# generated from genmsg/cmake/pkg-msg-paths.context.in + +DEVELSPACE = 'TRUE' == 'TRUE' +INSTALLSPACE = 'FALSE' == 'TRUE' + +PROJECT_NAME = 'videostream' +PKG_MSG_INCLUDE_DIRS = '' +ARG_DEPENDENCIES = 'std_msgs' diff --git a/Legacy/ws_linux/build/videostream/cmake/videostream-genmsg-context.py b/Legacy/ws_linux/build/videostream/cmake/videostream-genmsg-context.py new file mode 100644 index 0000000..43e56d9 --- /dev/null +++ b/Legacy/ws_linux/build/videostream/cmake/videostream-genmsg-context.py @@ -0,0 +1,10 @@ +# generated from genmsg/cmake/pkg-genmsg.context.in + +messages_str = "" +services_str = "/home/lab1_5/ws/ws_linux/src/videostream/srv/ip_get.srv" +pkg_name = "videostream" +dependencies_str = "std_msgs" +langs = "gencpp;genlisp;genpy" +dep_include_paths_str = "std_msgs;/opt/ros/hydro/share/std_msgs/cmake/../msg" +PYTHON_EXECUTABLE = "/usr/bin/python" +package_has_static_sources = '' == 'TRUE' diff --git a/Legacy/ws_linux/build/videostream/cmake/videostream-genmsg.cmake b/Legacy/ws_linux/build/videostream/cmake/videostream-genmsg.cmake new file mode 100644 index 0000000..18ab996 --- /dev/null +++ b/Legacy/ws_linux/build/videostream/cmake/videostream-genmsg.cmake @@ -0,0 +1,133 @@ +# generated from genmsg/cmake/pkg-genmsg.cmake.em + +message(STATUS "videostream: 0 messages, 1 services") + +set(MSG_I_FLAGS "-Istd_msgs:/opt/ros/hydro/share/std_msgs/cmake/../msg") + +# Find all generators +find_package(gencpp REQUIRED) +find_package(genlisp REQUIRED) +find_package(genpy REQUIRED) + +add_custom_target(videostream_generate_messages ALL) + +# +# langs = gencpp;genlisp;genpy +# + +### Section generating for lang: gencpp +### Generating Messages + +### Generating Services +_generate_srv_cpp(videostream + "/home/lab1_5/ws/ws_linux/src/videostream/srv/ip_get.srv" + "${MSG_I_FLAGS}" + "" + ${CATKIN_DEVEL_PREFIX}/${gencpp_INSTALL_DIR}/videostream +) + +### Generating Module File +_generate_module_cpp(videostream + ${CATKIN_DEVEL_PREFIX}/${gencpp_INSTALL_DIR}/videostream + "${ALL_GEN_OUTPUT_FILES_cpp}" +) + +add_custom_target(videostream_generate_messages_cpp + DEPENDS ${ALL_GEN_OUTPUT_FILES_cpp} +) +add_dependencies(videostream_generate_messages videostream_generate_messages_cpp) + +# target for backward compatibility +add_custom_target(videostream_gencpp) +add_dependencies(videostream_gencpp videostream_generate_messages_cpp) + +# register target for catkin_package(EXPORTED_TARGETS) +list(APPEND ${PROJECT_NAME}_EXPORTED_TARGETS videostream_generate_messages_cpp) + +### Section generating for lang: genlisp +### Generating Messages + +### Generating Services +_generate_srv_lisp(videostream + "/home/lab1_5/ws/ws_linux/src/videostream/srv/ip_get.srv" + "${MSG_I_FLAGS}" + "" + ${CATKIN_DEVEL_PREFIX}/${genlisp_INSTALL_DIR}/videostream +) + +### Generating Module File +_generate_module_lisp(videostream + ${CATKIN_DEVEL_PREFIX}/${genlisp_INSTALL_DIR}/videostream + "${ALL_GEN_OUTPUT_FILES_lisp}" +) + +add_custom_target(videostream_generate_messages_lisp + DEPENDS ${ALL_GEN_OUTPUT_FILES_lisp} +) +add_dependencies(videostream_generate_messages videostream_generate_messages_lisp) + +# target for backward compatibility +add_custom_target(videostream_genlisp) +add_dependencies(videostream_genlisp videostream_generate_messages_lisp) + +# register target for catkin_package(EXPORTED_TARGETS) +list(APPEND ${PROJECT_NAME}_EXPORTED_TARGETS videostream_generate_messages_lisp) + +### Section generating for lang: genpy +### Generating Messages + +### Generating Services +_generate_srv_py(videostream + "/home/lab1_5/ws/ws_linux/src/videostream/srv/ip_get.srv" + "${MSG_I_FLAGS}" + "" + ${CATKIN_DEVEL_PREFIX}/${genpy_INSTALL_DIR}/videostream +) + +### Generating Module File +_generate_module_py(videostream + ${CATKIN_DEVEL_PREFIX}/${genpy_INSTALL_DIR}/videostream + "${ALL_GEN_OUTPUT_FILES_py}" +) + +add_custom_target(videostream_generate_messages_py + DEPENDS ${ALL_GEN_OUTPUT_FILES_py} +) +add_dependencies(videostream_generate_messages videostream_generate_messages_py) + +# target for backward compatibility +add_custom_target(videostream_genpy) +add_dependencies(videostream_genpy videostream_generate_messages_py) + +# register target for catkin_package(EXPORTED_TARGETS) +list(APPEND ${PROJECT_NAME}_EXPORTED_TARGETS videostream_generate_messages_py) + + + +if(gencpp_INSTALL_DIR AND EXISTS ${CATKIN_DEVEL_PREFIX}/${gencpp_INSTALL_DIR}/videostream) + # install generated code + install( + DIRECTORY ${CATKIN_DEVEL_PREFIX}/${gencpp_INSTALL_DIR}/videostream + DESTINATION ${gencpp_INSTALL_DIR} + ) +endif() +add_dependencies(videostream_generate_messages_cpp std_msgs_generate_messages_cpp) + +if(genlisp_INSTALL_DIR AND EXISTS ${CATKIN_DEVEL_PREFIX}/${genlisp_INSTALL_DIR}/videostream) + # install generated code + install( + DIRECTORY ${CATKIN_DEVEL_PREFIX}/${genlisp_INSTALL_DIR}/videostream + DESTINATION ${genlisp_INSTALL_DIR} + ) +endif() +add_dependencies(videostream_generate_messages_lisp std_msgs_generate_messages_lisp) + +if(genpy_INSTALL_DIR AND EXISTS ${CATKIN_DEVEL_PREFIX}/${genpy_INSTALL_DIR}/videostream) + install(CODE "execute_process(COMMAND \"/usr/bin/python\" -m compileall \"${CATKIN_DEVEL_PREFIX}/${genpy_INSTALL_DIR}/videostream\")") + # install generated code + install( + DIRECTORY ${CATKIN_DEVEL_PREFIX}/${genpy_INSTALL_DIR}/videostream + DESTINATION ${genpy_INSTALL_DIR} + ) +endif() +add_dependencies(videostream_generate_messages_py std_msgs_generate_messages_py) diff --git a/Legacy/ws_linux/build/videostream/cmake_install.cmake b/Legacy/ws_linux/build/videostream/cmake_install.cmake new file mode 100644 index 0000000..7b044fb --- /dev/null +++ b/Legacy/ws_linux/build/videostream/cmake_install.cmake @@ -0,0 +1,77 @@ +# Install script for directory: /home/lab1_5/ws/ws_linux/src/videostream + +# Set the install prefix +IF(NOT DEFINED CMAKE_INSTALL_PREFIX) + SET(CMAKE_INSTALL_PREFIX "/home/lab1_5/ws/ws_linux/install") +ENDIF(NOT DEFINED CMAKE_INSTALL_PREFIX) +STRING(REGEX REPLACE "/$" "" CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}") + +# Set the install configuration name. +IF(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME) + IF(BUILD_TYPE) + STRING(REGEX REPLACE "^[^A-Za-z0-9_]+" "" + CMAKE_INSTALL_CONFIG_NAME "${BUILD_TYPE}") + ELSE(BUILD_TYPE) + SET(CMAKE_INSTALL_CONFIG_NAME "") + ENDIF(BUILD_TYPE) + MESSAGE(STATUS "Install configuration: \"${CMAKE_INSTALL_CONFIG_NAME}\"") +ENDIF(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME) + +# Set the component getting installed. +IF(NOT CMAKE_INSTALL_COMPONENT) + IF(COMPONENT) + MESSAGE(STATUS "Install component: \"${COMPONENT}\"") + SET(CMAKE_INSTALL_COMPONENT "${COMPONENT}") + ELSE(COMPONENT) + SET(CMAKE_INSTALL_COMPONENT) + ENDIF(COMPONENT) +ENDIF(NOT CMAKE_INSTALL_COMPONENT) + +# Install shared libraries without execute permission? +IF(NOT DEFINED CMAKE_INSTALL_SO_NO_EXE) + SET(CMAKE_INSTALL_SO_NO_EXE "1") +ENDIF(NOT DEFINED CMAKE_INSTALL_SO_NO_EXE) + +IF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + FILE(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/share/videostream/srv" TYPE FILE FILES "/home/lab1_5/ws/ws_linux/src/videostream/srv/ip_get.srv") +ENDIF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + +IF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + FILE(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/share/videostream/cmake" TYPE FILE FILES "/home/lab1_5/ws/ws_linux/build/videostream/catkin_generated/installspace/videostream-msg-paths.cmake") +ENDIF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + +IF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + FILE(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/include" TYPE DIRECTORY FILES "/home/lab1_5/ws/ws_linux/devel/include/videostream") +ENDIF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + +IF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + FILE(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/share/common-lisp/ros" TYPE DIRECTORY FILES "/home/lab1_5/ws/ws_linux/devel/share/common-lisp/ros/videostream") +ENDIF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + +IF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + execute_process(COMMAND "/usr/bin/python" -m compileall "/home/lab1_5/ws/ws_linux/devel/lib/python2.7/dist-packages/videostream") +ENDIF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + +IF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + FILE(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/lib/python2.7/dist-packages" TYPE DIRECTORY FILES "/home/lab1_5/ws/ws_linux/devel/lib/python2.7/dist-packages/videostream") +ENDIF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + +IF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + FILE(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/lib/pkgconfig" TYPE FILE FILES "/home/lab1_5/ws/ws_linux/build/videostream/catkin_generated/installspace/videostream.pc") +ENDIF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + +IF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + FILE(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/share/videostream/cmake" TYPE FILE FILES "/home/lab1_5/ws/ws_linux/build/videostream/catkin_generated/installspace/videostream-msg-extras.cmake") +ENDIF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + +IF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + FILE(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/share/videostream/cmake" TYPE FILE FILES + "/home/lab1_5/ws/ws_linux/build/videostream/catkin_generated/installspace/videostreamConfig.cmake" + "/home/lab1_5/ws/ws_linux/build/videostream/catkin_generated/installspace/videostreamConfig-version.cmake" + ) +ENDIF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + +IF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + FILE(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/share/videostream" TYPE FILE FILES "/home/lab1_5/ws/ws_linux/src/videostream/package.xml") +ENDIF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + diff --git a/Legacy/ws_linux/devel/.catkin b/Legacy/ws_linux/devel/.catkin new file mode 100644 index 0000000..2e75d7d --- /dev/null +++ b/Legacy/ws_linux/devel/.catkin @@ -0,0 +1 @@ +/home/lab1_5/ws/ws_linux/src \ No newline at end of file diff --git a/Legacy/ws_linux/devel/.rosinstall b/Legacy/ws_linux/devel/.rosinstall new file mode 100644 index 0000000..c4dad5d --- /dev/null +++ b/Legacy/ws_linux/devel/.rosinstall @@ -0,0 +1,2 @@ +- setup-file: + local-name: /home/lab1_5/ws/ws_linux/devel/setup.sh diff --git a/Legacy/ws_linux/devel/_setup_util.py b/Legacy/ws_linux/devel/_setup_util.py new file mode 100755 index 0000000..1ba3413 --- /dev/null +++ b/Legacy/ws_linux/devel/_setup_util.py @@ -0,0 +1,280 @@ +#!/usr/bin/env python + +# Software License Agreement (BSD License) +# +# Copyright (c) 2012, Willow Garage, Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following +# disclaimer in the documentation and/or other materials provided +# with the distribution. +# * Neither the name of Willow Garage, Inc. nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + +'''This file generates shell code for the setup.SHELL scripts to set environment variables''' + +from __future__ import print_function +import argparse +import copy +import errno +import os +import platform +import sys + +CATKIN_MARKER_FILE = '.catkin' + +system = platform.system() +IS_DARWIN = (system == 'Darwin') +IS_WINDOWS = (system == 'Windows') + +# subfolder of workspace prepended to CMAKE_PREFIX_PATH +ENV_VAR_SUBFOLDERS = { + 'CMAKE_PREFIX_PATH': '', + 'CPATH': 'include', + 'LD_LIBRARY_PATH' if not IS_DARWIN else 'DYLD_LIBRARY_PATH': 'lib', + 'PATH': 'bin', + 'PKG_CONFIG_PATH': 'lib/pkgconfig', + 'PYTHONPATH': 'lib/python2.7/dist-packages', +} + + +def rollback_env_variables(environ, env_var_subfolders): + ''' + Generate shell code to reset environment variables + by unrolling modifications based on all workspaces in CMAKE_PREFIX_PATH. + This does not cover modifications performed by environment hooks. + ''' + lines = [] + unmodified_environ = copy.copy(environ) + for key in sorted(env_var_subfolders.keys()): + subfolder = env_var_subfolders[key] + value = _rollback_env_variable(unmodified_environ, key, subfolder) + if value is not None: + environ[key] = value + lines.append(assignment(key, value)) + if lines: + lines.insert(0, comment('reset environment variables by unrolling modifications based on all workspaces in CMAKE_PREFIX_PATH')) + return lines + + +def _rollback_env_variable(environ, name, subfolder): + ''' + For each catkin workspace in CMAKE_PREFIX_PATH remove the first entry from env[NAME] matching workspace + subfolder. + + :param subfolder: str '' or subfoldername that may start with '/' + :returns: the updated value of the environment variable. + ''' + value = environ[name] if name in environ else '' + env_paths = [path for path in value.split(os.pathsep) if path] + value_modified = False + if subfolder: + if subfolder.startswith(os.path.sep) or (os.path.altsep and subfolder.startswith(os.path.altsep)): + subfolder = subfolder[1:] + if subfolder.endswith(os.path.sep) or (os.path.altsep and subfolder.endswith(os.path.altsep)): + subfolder = subfolder[:-1] + for ws_path in _get_workspaces(environ, include_fuerte=True, include_non_existing=True): + path_to_find = os.path.join(ws_path, subfolder) if subfolder else ws_path + path_to_remove = None + for env_path in env_paths: + env_path_clean = env_path[:-1] if env_path and env_path[-1] in [os.path.sep, os.path.altsep] else env_path + if env_path_clean == path_to_find: + path_to_remove = env_path + break + if path_to_remove: + env_paths.remove(path_to_remove) + value_modified = True + new_value = os.pathsep.join(env_paths) + return new_value if value_modified else None + + +def _get_workspaces(environ, include_fuerte=False, include_non_existing=False): + ''' + Based on CMAKE_PREFIX_PATH return all catkin workspaces. + + :param include_fuerte: The flag if paths starting with '/opt/ros/fuerte' should be considered workspaces, ``bool`` + ''' + # get all cmake prefix paths + env_name = 'CMAKE_PREFIX_PATH' + value = environ[env_name] if env_name in environ else '' + paths = [path for path in value.split(os.pathsep) if path] + # remove non-workspace paths + workspaces = [path for path in paths if os.path.isfile(os.path.join(path, CATKIN_MARKER_FILE)) or (include_fuerte and path.startswith('/opt/ros/fuerte')) or (include_non_existing and not os.path.exists(path))] + return workspaces + + +def prepend_env_variables(environ, env_var_subfolders, workspaces): + ''' + Generate shell code to prepend environment variables + for the all workspaces. + ''' + lines = [] + lines.append(comment('prepend folders of workspaces to environment variables')) + + paths = [path for path in workspaces.split(os.pathsep) if path] + + prefix = _prefix_env_variable(environ, 'CMAKE_PREFIX_PATH', paths, '') + lines.append(prepend(environ, 'CMAKE_PREFIX_PATH', prefix)) + + for key in sorted([key for key in env_var_subfolders.keys() if key != 'CMAKE_PREFIX_PATH']): + subfolder = env_var_subfolders[key] + prefix = _prefix_env_variable(environ, key, paths, subfolder) + lines.append(prepend(environ, key, prefix)) + return lines + + +def _prefix_env_variable(environ, name, paths, subfolder): + ''' + Return the prefix to prepend to the environment variable NAME, adding any path in NEW_PATHS_STR without creating duplicate or empty items. + ''' + value = environ[name] if name in environ else '' + environ_paths = [path for path in value.split(os.pathsep) if path] + checked_paths = [] + for path in paths: + if subfolder: + path = os.path.join(path, subfolder) + # exclude any path already in env and any path we already added + if path not in environ_paths and path not in checked_paths: + checked_paths.append(path) + prefix_str = os.pathsep.join(checked_paths) + if prefix_str != '' and environ_paths: + prefix_str += os.pathsep + return prefix_str + + +def assignment(key, value): + if not IS_WINDOWS: + return 'export %s="%s"' % (key, value) + else: + return 'set %s=%s' % (key, value) + + +def comment(msg): + if not IS_WINDOWS: + return '# %s' % msg + else: + return 'REM %s' % msg + + +def prepend(environ, key, prefix): + if key not in environ or not environ[key]: + return assignment(key, prefix) + if not IS_WINDOWS: + return 'export %s="%s$%s"' % (key, prefix, key) + else: + return 'set %s=%s%%%s%%' % (key, prefix, key) + + +def find_env_hooks(environ, cmake_prefix_path): + ''' + Generate shell code with found environment hooks + for the all workspaces. + ''' + lines = [] + lines.append(comment('found environment hooks in workspaces')) + + generic_env_hooks = [] + generic_env_hooks_workspace = [] + specific_env_hooks = [] + specific_env_hooks_workspace = [] + generic_env_hooks_by_filename = {} + specific_env_hooks_by_filename = {} + generic_env_hook_ext = 'bat' if IS_WINDOWS else 'sh' + specific_env_hook_ext = environ['CATKIN_SHELL'] if not IS_WINDOWS and 'CATKIN_SHELL' in environ and environ['CATKIN_SHELL'] else None + # remove non-workspace paths + workspaces = [path for path in cmake_prefix_path.split(os.pathsep) if path and os.path.isfile(os.path.join(path, CATKIN_MARKER_FILE))] + for workspace in reversed(workspaces): + env_hook_dir = os.path.join(workspace, 'etc', 'catkin', 'profile.d') + if os.path.isdir(env_hook_dir): + for filename in sorted(os.listdir(env_hook_dir)): + if filename.endswith('.%s' % generic_env_hook_ext): + # remove previous env hook with same name if present + if filename in generic_env_hooks_by_filename: + i = generic_env_hooks.index(generic_env_hooks_by_filename[filename]) + generic_env_hooks.pop(i) + generic_env_hooks_workspace.pop(i) + # append env hook + generic_env_hooks.append(os.path.join(env_hook_dir, filename)) + generic_env_hooks_workspace.append(workspace) + generic_env_hooks_by_filename[filename] = generic_env_hooks[-1] + elif specific_env_hook_ext is not None and filename.endswith('.%s' % specific_env_hook_ext): + # remove previous env hook with same name if present + if filename in specific_env_hooks_by_filename: + i = specific_env_hooks.index(specific_env_hooks_by_filename[filename]) + specific_env_hooks.pop(i) + specific_env_hooks_workspace.pop(i) + # append env hook + specific_env_hooks.append(os.path.join(env_hook_dir, filename)) + specific_env_hooks_workspace.append(workspace) + specific_env_hooks_by_filename[filename] = specific_env_hooks[-1] + env_hooks = generic_env_hooks + specific_env_hooks + env_hooks_workspace = generic_env_hooks_workspace + specific_env_hooks_workspace + count = len(env_hooks) + lines.append(assignment('_CATKIN_ENVIRONMENT_HOOKS_COUNT', count)) + for i in range(count): + lines.append(assignment('_CATKIN_ENVIRONMENT_HOOKS_%d' % i, env_hooks[i])) + lines.append(assignment('_CATKIN_ENVIRONMENT_HOOKS_%d_WORKSPACE' % i, env_hooks_workspace[i])) + return lines + + +def _parse_arguments(args=None): + parser = argparse.ArgumentParser(description='Generates code blocks for the setup.SHELL script.') + parser.add_argument('--extend', action='store_true', help='Skip unsetting previous environment variables to extend context') + return parser.parse_known_args(args=args)[0] + + +if __name__ == '__main__': + try: + try: + args = _parse_arguments() + except Exception as e: + print(e, file=sys.stderr) + sys.exit(1) + + # environment at generation time + CMAKE_PREFIX_PATH = '/home/lab1_5/ws/ws_linux/devel;/home/lab1_5/ws/ws_xeno/devel;/home/lab1_5/ws/ws_isolated/install_isolated;/home/lab1_5/ws/install_isolated;/opt/ros/hydro'.split(';') + # prepend current workspace if not already part of CPP + base_path = os.path.dirname(__file__) + if base_path not in CMAKE_PREFIX_PATH: + CMAKE_PREFIX_PATH.insert(0, base_path) + CMAKE_PREFIX_PATH = os.pathsep.join(CMAKE_PREFIX_PATH) + + environ = dict(os.environ) + lines = [] + if not args.extend: + lines += rollback_env_variables(environ, ENV_VAR_SUBFOLDERS) + lines += prepend_env_variables(environ, ENV_VAR_SUBFOLDERS, CMAKE_PREFIX_PATH) + lines += find_env_hooks(environ, CMAKE_PREFIX_PATH) + print('\n'.join(lines)) + + # need to explicitly flush the output + sys.stdout.flush() + except IOError as e: + # and catch potantial "broken pipe" if stdout is not writable + # which can happen when piping the output to a file but the disk is full + if e.errno == errno.EPIPE: + print(e, file=sys.stderr) + sys.exit(2) + raise + + sys.exit(0) diff --git a/Legacy/ws_linux/devel/env.sh b/Legacy/ws_linux/devel/env.sh new file mode 100755 index 0000000..8aa9d24 --- /dev/null +++ b/Legacy/ws_linux/devel/env.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env sh +# generated from catkin/cmake/templates/env.sh.in + +if [ $# -eq 0 ] ; then + /bin/echo "Usage: env.sh COMMANDS" + /bin/echo "Calling env.sh without arguments is not supported anymore. Instead spawn a subshell and source a setup file manually." + exit 1 +fi + +# ensure to not use different shell type which was set before +CATKIN_SHELL=sh + +# source setup.sh from same directory as this file +_CATKIN_SETUP_DIR=$(cd "`dirname "$0"`" > /dev/null && pwd) +. "$_CATKIN_SETUP_DIR/setup.sh" +exec "$@" diff --git a/Legacy/ws_linux/devel/etc/catkin/profile.d/05.catkin-test-results.sh b/Legacy/ws_linux/devel/etc/catkin/profile.d/05.catkin-test-results.sh new file mode 100644 index 0000000..501b091 --- /dev/null +++ b/Legacy/ws_linux/devel/etc/catkin/profile.d/05.catkin-test-results.sh @@ -0,0 +1,4 @@ +# generated from catkin/cmake/env-hooks/05.catkin-test-results.sh.develspace.in + +export CATKIN_TEST_RESULTS_DIR="/home/lab1_5/ws/ws_linux/build/test_results" +export ROS_TEST_RESULTS_DIR="$CATKIN_TEST_RESULTS_DIR" diff --git a/Legacy/ws_linux/devel/etc/catkin/profile.d/05.catkin_make.bash b/Legacy/ws_linux/devel/etc/catkin/profile.d/05.catkin_make.bash new file mode 100644 index 0000000..bb6ab44 --- /dev/null +++ b/Legacy/ws_linux/devel/etc/catkin/profile.d/05.catkin_make.bash @@ -0,0 +1,64 @@ +function _catkin_make() +{ + local cur prev + cur=${COMP_WORDS[COMP_CWORD]} + prev=${COMP_WORDS[COMP_CWORD-1]} + + # autocomplete path arguments for -C, --directory, --source, --build + case $prev in + -C|--directory|--source|--build) + _filedir -d + return 0 + ;; + esac + + if [[ "$cur" == -DCMAKE_BUILD_TYPE=* ]]; then + # autocomplete CMake argument CMAKE_BUILD_TYPE with its options + COMPREPLY=( $( compgen -P "-DCMAKE_BUILD_TYPE=" -W "None Debug Release RelWithDebInfo MinSizeRel" -- "${cur:19}" ) ) + elif [[ "$cur" == -DCATKIN_ENABLE_TESTING=* ]]; then + # autocomplete catkin argument CATKIN_ENABLE_TESTING with its options + COMPREPLY=( $( compgen -P "-DCATKIN_ENABLE_TESTING=" -W "0 1" -- "${cur:24}" ) ) + elif [[ "$cur" == -DCATKIN_DEVEL_PREFIX=* || "$cur" == -DCMAKE_INSTALL_PREFIX=* ]]; then + COMPREPLY=() + elif [[ "$cur" == -* ]]; then + local opts="$( _parse_help "$1" )" + [[ $opts ]] || opts="$( _parse_usage "$1" )" + if [[ "$cur" == -* ]]; then + # suggest some common CMake arguments + opts="$opts -DCATKIN_DEVEL_PREFIX= -DCATKIN_ENABLE_TESTING= -DCMAKE_INSTALL_PREFIX= -DCMAKE_BUILD_TYPE=" + fi + COMPREPLY=( $( compgen -W "$opts" -- "$cur" ) ) + [[ $COMPREPLY == *= ]] && compopt -o nospace + else + # check if custom workspace root has been specified on the command line + local workspace_dir="." + for (( i=0; i < ${#COMP_WORDS[@]}; i++ )); do + if [[ ${COMP_WORDS[i]} == -C || ${COMP_WORDS[i]} == --directory ]]; then + # eval to expand tilde + eval workspace_dir=${COMP_WORDS[i+1]} + fi + done + # check if custom build folder has been specified on the command line + local build_dir="build" + for (( i=0; i < ${#COMP_WORDS[@]}; i++ )); do + if [[ ${COMP_WORDS[i]} == --build ]]; then + # eval to expand tilde + eval build_dir=${COMP_WORDS[i+1]} + fi + done + + # determine location of Makefile + local makefile_dir + if [[ "$build_dir" = /* ]]; then + makefile_dir="$build_dir" + else + makefile_dir="$workspace_dir/$build_dir" + fi + COMPREPLY=() + if [ -f "$makefile_dir/Makefile" ]; then + cur=${COMP_WORDS[COMP_CWORD]} + COMPREPLY=( $( compgen -W "`make -C $makefile_dir -qp 2>/dev/null | awk -F':' '/^[a-zA-Z0-9][a-zA-Z0-9_\.]*:/ { print $1 }'`" -- $cur )) + fi + fi +} && +complete -F _catkin_make catkin_make diff --git a/Legacy/ws_linux/devel/etc/catkin/profile.d/05.catkin_make_isolated.bash b/Legacy/ws_linux/devel/etc/catkin/profile.d/05.catkin_make_isolated.bash new file mode 100644 index 0000000..5cdc4dd --- /dev/null +++ b/Legacy/ws_linux/devel/etc/catkin/profile.d/05.catkin_make_isolated.bash @@ -0,0 +1,62 @@ +function _catkin_make_isolated() +{ + local cur prev + cur=${COMP_WORDS[COMP_CWORD]} + prev=${COMP_WORDS[COMP_CWORD-1]} + + # autocomplete path arguments for -C, --directory, --source, --build, --devel, --install + case $prev in + -C|--directory|--source|--build|--devel|--install) + _filedir -d + return 0 + ;; + esac + + if [[ "$cur" == -DCMAKE_BUILD_TYPE=* ]]; then + # autocomplete CMake argument CMAKE_BUILD_TYPE with its options + COMPREPLY=( $( compgen -P "-DCMAKE_BUILD_TYPE=" -W "None Debug Release RelWithDebInfo MinSizeRel" -- "${cur:19}" ) ) + elif [[ "$cur" == -DCATKIN_ENABLE_TESTING=* ]]; then + # autocomplete catkin argument CATKIN_ENABLE_TESTING with its options + COMPREPLY=( $( compgen -P "-DCATKIN_ENABLE_TESTING=" -W "0 1" -- "${cur:24}" ) ) + elif [[ "$cur" == -* ]]; then + local opts="$( _parse_help "$1" )" + [[ $opts ]] || opts="$( _parse_usage "$1" )" + if [[ "$cur" == -* ]]; then + # suggest some common CMake arguments + opts="$opts -DCATKIN_ENABLE_TESTING= -DCMAKE_BUILD_TYPE=" + fi + COMPREPLY=( $( compgen -W "$opts" -- "$cur" ) ) + [[ $COMPREPLY == *= ]] && compopt -o nospace + else + # check if custom workspace root has been specified on the command line + local workspace_dir="." + for (( i=0; i < ${#COMP_WORDS[@]}; i++ )); do + if [[ ${COMP_WORDS[i]} == -C || ${COMP_WORDS[i]} == --directory ]]; then + # eval to expand tilde + eval workspace_dir=${COMP_WORDS[i+1]} + fi + done + # check if custom build folder has been specified on the command line + local build_dir="build_isolated" + for (( i=0; i < ${#COMP_WORDS[@]}; i++ )); do + if [[ ${COMP_WORDS[i]} == --build ]]; then + # eval to expand tilde + eval build_dir=${COMP_WORDS[i+1]} + fi + done + + # determine location of Makefile + local makefile_dir + if [[ "$build_dir" = /* ]]; then + makefile_dir="$build_dir" + else + makefile_dir="$workspace_dir/$build_dir" + fi + COMPREPLY=() + if [ -f "$makefile_dir/Makefile" ]; then + cur=${COMP_WORDS[COMP_CWORD]} + COMPREPLY=( $( compgen -W "`make -C $makefile_dir -qp 2>/dev/null | awk -F':' '/^[a-zA-Z0-9][a-zA-Z0-9_\.]*:/ { print $1 }'`" -- $cur )) + fi + fi +} && +complete -F _catkin_make_isolated catkin_make_isolated diff --git a/Legacy/ws_linux/devel/include/rosaria/BumperState.h b/Legacy/ws_linux/devel/include/rosaria/BumperState.h new file mode 100644 index 0000000..da61aa9 --- /dev/null +++ b/Legacy/ws_linux/devel/include/rosaria/BumperState.h @@ -0,0 +1,265 @@ +/* Software License Agreement (BSD License) + * + * Copyright (c) 2011, Willow Garage, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of Willow Garage, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * Auto-generated by genmsg_cpp from file /home/lab1_5/ws/ws_linux/src/rosaria/msg/BumperState.msg + * + */ + + +#ifndef ROSARIA_MESSAGE_BUMPERSTATE_H +#define ROSARIA_MESSAGE_BUMPERSTATE_H + + +#include +#include +#include + +#include +#include +#include +#include + +#include + +namespace rosaria +{ +template +struct BumperState_ +{ + typedef BumperState_ Type; + + BumperState_() + : header() + , front_bumpers() + , rear_bumpers() { + } + BumperState_(const ContainerAllocator& _alloc) + : header(_alloc) + , front_bumpers(_alloc) + , rear_bumpers(_alloc) { + } + + + + typedef ::std_msgs::Header_ _header_type; + _header_type header; + + typedef std::vector::other > _front_bumpers_type; + _front_bumpers_type front_bumpers; + + typedef std::vector::other > _rear_bumpers_type; + _rear_bumpers_type rear_bumpers; + + + + + typedef boost::shared_ptr< ::rosaria::BumperState_ > Ptr; + typedef boost::shared_ptr< ::rosaria::BumperState_ const> ConstPtr; + boost::shared_ptr > __connection_header; + +}; // struct BumperState_ + +typedef ::rosaria::BumperState_ > BumperState; + +typedef boost::shared_ptr< ::rosaria::BumperState > BumperStatePtr; +typedef boost::shared_ptr< ::rosaria::BumperState const> BumperStateConstPtr; + +// constants requiring out of line definition + + + +template +std::ostream& operator<<(std::ostream& s, const ::rosaria::BumperState_ & v) +{ +ros::message_operations::Printer< ::rosaria::BumperState_ >::stream(s, "", v); +return s; +} + +} // namespace rosaria + +namespace ros +{ +namespace message_traits +{ + + + +// BOOLTRAITS {'IsFixedSize': False, 'IsMessage': True, 'HasHeader': True} +// {'rosaria': ['/home/lab1_5/ws/ws_linux/src/rosaria/msg'], 'std_msgs': ['/opt/ros/hydro/share/std_msgs/cmake/../msg'], 'geometry_msgs': ['/opt/ros/hydro/share/geometry_msgs/cmake/../msg']} + +// !!!!!!!!!!! ['__class__', '__delattr__', '__dict__', '__doc__', '__eq__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_parsed_fields', 'constants', 'fields', 'full_name', 'has_header', 'header_present', 'names', 'package', 'parsed_fields', 'short_name', 'text', 'types'] + + + + +template +struct IsFixedSize< ::rosaria::BumperState_ > + : FalseType + { }; + +template +struct IsFixedSize< ::rosaria::BumperState_ const> + : FalseType + { }; + +template +struct IsMessage< ::rosaria::BumperState_ > + : TrueType + { }; + +template +struct IsMessage< ::rosaria::BumperState_ const> + : TrueType + { }; + +template +struct HasHeader< ::rosaria::BumperState_ > + : TrueType + { }; + +template +struct HasHeader< ::rosaria::BumperState_ const> + : TrueType + { }; + + +template +struct MD5Sum< ::rosaria::BumperState_ > +{ + static const char* value() + { + return "f81947761ff7e166a3bbaf937b9869b5"; + } + + static const char* value(const ::rosaria::BumperState_&) { return value(); } + static const uint64_t static_value1 = 0xf81947761ff7e166ULL; + static const uint64_t static_value2 = 0xa3bbaf937b9869b5ULL; +}; + +template +struct DataType< ::rosaria::BumperState_ > +{ + static const char* value() + { + return "rosaria/BumperState"; + } + + static const char* value(const ::rosaria::BumperState_&) { return value(); } +}; + +template +struct Definition< ::rosaria::BumperState_ > +{ + static const char* value() + { + return "Header header\n\ +bool[] front_bumpers\n\ +bool[] rear_bumpers\n\ +\n\ +================================================================================\n\ +MSG: std_msgs/Header\n\ +# Standard metadata for higher-level stamped data types.\n\ +# This is generally used to communicate timestamped data \n\ +# in a particular coordinate frame.\n\ +# \n\ +# sequence ID: consecutively increasing ID \n\ +uint32 seq\n\ +#Two-integer timestamp that is expressed as:\n\ +# * stamp.secs: seconds (stamp_secs) since epoch\n\ +# * stamp.nsecs: nanoseconds since stamp_secs\n\ +# time-handling sugar is provided by the client library\n\ +time stamp\n\ +#Frame this data is associated with\n\ +# 0: no frame\n\ +# 1: global frame\n\ +string frame_id\n\ +"; + } + + static const char* value(const ::rosaria::BumperState_&) { return value(); } +}; + +} // namespace message_traits +} // namespace ros + +namespace ros +{ +namespace serialization +{ + + template struct Serializer< ::rosaria::BumperState_ > + { + template inline static void allInOne(Stream& stream, T m) + { + stream.next(m.header); + stream.next(m.front_bumpers); + stream.next(m.rear_bumpers); + } + + ROS_DECLARE_ALLINONE_SERIALIZER; + }; // struct BumperState_ + +} // namespace serialization +} // namespace ros + +namespace ros +{ +namespace message_operations +{ + +template +struct Printer< ::rosaria::BumperState_ > +{ + template static void stream(Stream& s, const std::string& indent, const ::rosaria::BumperState_& v) + { + s << indent << "header: "; + s << std::endl; + Printer< ::std_msgs::Header_ >::stream(s, indent + " ", v.header); + s << indent << "front_bumpers[]" << std::endl; + for (size_t i = 0; i < v.front_bumpers.size(); ++i) + { + s << indent << " front_bumpers[" << i << "]: "; + Printer::stream(s, indent + " ", v.front_bumpers[i]); + } + s << indent << "rear_bumpers[]" << std::endl; + for (size_t i = 0; i < v.rear_bumpers.size(); ++i) + { + s << indent << " rear_bumpers[" << i << "]: "; + Printer::stream(s, indent + " ", v.rear_bumpers[i]); + } + } +}; + +} // namespace message_operations +} // namespace ros + +#endif // ROSARIA_MESSAGE_BUMPERSTATE_H diff --git a/Legacy/ws_linux/devel/include/rosaria/RosAriaConfig.h b/Legacy/ws_linux/devel/include/rosaria/RosAriaConfig.h new file mode 100644 index 0000000..0cd34a9 --- /dev/null +++ b/Legacy/ws_linux/devel/include/rosaria/RosAriaConfig.h @@ -0,0 +1,621 @@ +//#line 2 "/opt/ros/hydro/share/dynamic_reconfigure/cmake/../templates/ConfigType.h.template" +// ********************************************************* +// +// File autogenerated for the rosaria package +// by the dynamic_reconfigure package. +// Please do not edit. +// +// ********************************************************/ + +/*********************************************************** + * Software License Agreement (BSD License) + * + * Copyright (c) 2008, Willow Garage, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of the Willow Garage nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ***********************************************************/ + +// Author: Blaise Gassend + + +#ifndef __rosaria__ROSARIACONFIG_H__ +#define __rosaria__ROSARIACONFIG_H__ + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace rosaria +{ + class RosAriaConfigStatics; + + class RosAriaConfig + { + public: + class AbstractParamDescription : public dynamic_reconfigure::ParamDescription + { + public: + AbstractParamDescription(std::string n, std::string t, uint32_t l, + std::string d, std::string e) + { + name = n; + type = t; + level = l; + description = d; + edit_method = e; + } + + virtual void clamp(RosAriaConfig &config, const RosAriaConfig &max, const RosAriaConfig &min) const = 0; + virtual void calcLevel(uint32_t &level, const RosAriaConfig &config1, const RosAriaConfig &config2) const = 0; + virtual void fromServer(const ros::NodeHandle &nh, RosAriaConfig &config) const = 0; + virtual void toServer(const ros::NodeHandle &nh, const RosAriaConfig &config) const = 0; + virtual bool fromMessage(const dynamic_reconfigure::Config &msg, RosAriaConfig &config) const = 0; + virtual void toMessage(dynamic_reconfigure::Config &msg, const RosAriaConfig &config) const = 0; + virtual void getValue(const RosAriaConfig &config, boost::any &val) const = 0; + }; + + typedef boost::shared_ptr AbstractParamDescriptionPtr; + typedef boost::shared_ptr AbstractParamDescriptionConstPtr; + + template + class ParamDescription : public AbstractParamDescription + { + public: + ParamDescription(std::string name, std::string type, uint32_t level, + std::string description, std::string edit_method, T RosAriaConfig::* f) : + AbstractParamDescription(name, type, level, description, edit_method), + field(f) + {} + + T (RosAriaConfig::* field); + + virtual void clamp(RosAriaConfig &config, const RosAriaConfig &max, const RosAriaConfig &min) const + { + if (config.*field > max.*field) + config.*field = max.*field; + + if (config.*field < min.*field) + config.*field = min.*field; + } + + virtual void calcLevel(uint32_t &comb_level, const RosAriaConfig &config1, const RosAriaConfig &config2) const + { + if (config1.*field != config2.*field) + comb_level |= level; + } + + virtual void fromServer(const ros::NodeHandle &nh, RosAriaConfig &config) const + { + nh.getParam(name, config.*field); + } + + virtual void toServer(const ros::NodeHandle &nh, const RosAriaConfig &config) const + { + nh.setParam(name, config.*field); + } + + virtual bool fromMessage(const dynamic_reconfigure::Config &msg, RosAriaConfig &config) const + { + return dynamic_reconfigure::ConfigTools::getParameter(msg, name, config.*field); + } + + virtual void toMessage(dynamic_reconfigure::Config &msg, const RosAriaConfig &config) const + { + dynamic_reconfigure::ConfigTools::appendParameter(msg, name, config.*field); + } + + virtual void getValue(const RosAriaConfig &config, boost::any &val) const + { + val = config.*field; + } + }; + + class AbstractGroupDescription : public dynamic_reconfigure::Group + { + public: + AbstractGroupDescription(std::string n, std::string t, int p, int i, bool s) + { + name = n; + type = t; + parent = p; + state = s; + id = i; + } + + std::vector abstract_parameters; + bool state; + + virtual void toMessage(dynamic_reconfigure::Config &msg, const boost::any &config) const = 0; + virtual bool fromMessage(const dynamic_reconfigure::Config &msg, boost::any &config) const =0; + virtual void updateParams(boost::any &cfg, RosAriaConfig &top) const= 0; + virtual void setInitialState(boost::any &cfg) const = 0; + + + void convertParams() + { + for(std::vector::const_iterator i = abstract_parameters.begin(); i != abstract_parameters.end(); ++i) + { + parameters.push_back(dynamic_reconfigure::ParamDescription(**i)); + } + } + }; + + typedef boost::shared_ptr AbstractGroupDescriptionPtr; + typedef boost::shared_ptr AbstractGroupDescriptionConstPtr; + + template + class GroupDescription : public AbstractGroupDescription + { + public: + GroupDescription(std::string name, std::string type, int parent, int id, bool s, T PT::* f) : AbstractGroupDescription(name, type, parent, id, s), field(f) + { + } + + GroupDescription(const GroupDescription& g): AbstractGroupDescription(g.name, g.type, g.parent, g.id, g.state), field(g.field), groups(g.groups) + { + parameters = g.parameters; + abstract_parameters = g.abstract_parameters; + } + + virtual bool fromMessage(const dynamic_reconfigure::Config &msg, boost::any &cfg) const + { + PT* config = boost::any_cast(cfg); + if(!dynamic_reconfigure::ConfigTools::getGroupState(msg, name, (*config).*field)) + return false; + + for(std::vector::const_iterator i = groups.begin(); i != groups.end(); ++i) + { + boost::any n = &((*config).*field); + if(!(*i)->fromMessage(msg, n)) + return false; + } + + return true; + } + + virtual void setInitialState(boost::any &cfg) const + { + PT* config = boost::any_cast(cfg); + T* group = &((*config).*field); + group->state = state; + + for(std::vector::const_iterator i = groups.begin(); i != groups.end(); ++i) + { + boost::any n = boost::any(&((*config).*field)); + (*i)->setInitialState(n); + } + + } + + virtual void updateParams(boost::any &cfg, RosAriaConfig &top) const + { + PT* config = boost::any_cast(cfg); + + T* f = &((*config).*field); + f->setParams(top, abstract_parameters); + + for(std::vector::const_iterator i = groups.begin(); i != groups.end(); ++i) + { + boost::any n = &((*config).*field); + (*i)->updateParams(n, top); + } + } + + virtual void toMessage(dynamic_reconfigure::Config &msg, const boost::any &cfg) const + { + const PT config = boost::any_cast(cfg); + dynamic_reconfigure::ConfigTools::appendGroup(msg, name, id, parent, config.*field); + + for(std::vector::const_iterator i = groups.begin(); i != groups.end(); ++i) + { + (*i)->toMessage(msg, config.*field); + } + } + + T (PT::* field); + std::vector groups; + }; + +class DEFAULT +{ + public: + DEFAULT() + { + state = true; + name = "Default"; + } + + void setParams(RosAriaConfig &config, const std::vector params) + { + for (std::vector::const_iterator _i = params.begin(); _i != params.end(); ++_i) + { + boost::any val; + (*_i)->getValue(config, val); + + if("trans_accel"==(*_i)->name){trans_accel = boost::any_cast(val);} + if("trans_decel"==(*_i)->name){trans_decel = boost::any_cast(val);} + if("lat_accel"==(*_i)->name){lat_accel = boost::any_cast(val);} + if("lat_decel"==(*_i)->name){lat_decel = boost::any_cast(val);} + if("rot_accel"==(*_i)->name){rot_accel = boost::any_cast(val);} + if("rot_decel"==(*_i)->name){rot_decel = boost::any_cast(val);} + if("TicksMM"==(*_i)->name){TicksMM = boost::any_cast(val);} + if("DriftFactor"==(*_i)->name){DriftFactor = boost::any_cast(val);} + if("RevCount"==(*_i)->name){RevCount = boost::any_cast(val);} + } + } + + double trans_accel; +double trans_decel; +double lat_accel; +double lat_decel; +double rot_accel; +double rot_decel; +int TicksMM; +int DriftFactor; +int RevCount; + + bool state; + std::string name; + + +}groups; + + + +//#line 262 "/opt/ros/hydro/lib/python2.7/dist-packages/dynamic_reconfigure/parameter_generator_catkin.py" + double trans_accel; +//#line 262 "/opt/ros/hydro/lib/python2.7/dist-packages/dynamic_reconfigure/parameter_generator_catkin.py" + double trans_decel; +//#line 262 "/opt/ros/hydro/lib/python2.7/dist-packages/dynamic_reconfigure/parameter_generator_catkin.py" + double lat_accel; +//#line 262 "/opt/ros/hydro/lib/python2.7/dist-packages/dynamic_reconfigure/parameter_generator_catkin.py" + double lat_decel; +//#line 262 "/opt/ros/hydro/lib/python2.7/dist-packages/dynamic_reconfigure/parameter_generator_catkin.py" + double rot_accel; +//#line 262 "/opt/ros/hydro/lib/python2.7/dist-packages/dynamic_reconfigure/parameter_generator_catkin.py" + double rot_decel; +//#line 262 "/opt/ros/hydro/lib/python2.7/dist-packages/dynamic_reconfigure/parameter_generator_catkin.py" + int TicksMM; +//#line 262 "/opt/ros/hydro/lib/python2.7/dist-packages/dynamic_reconfigure/parameter_generator_catkin.py" + int DriftFactor; +//#line 262 "/opt/ros/hydro/lib/python2.7/dist-packages/dynamic_reconfigure/parameter_generator_catkin.py" + int RevCount; +//#line 255 "/opt/ros/hydro/share/dynamic_reconfigure/cmake/../templates/ConfigType.h.template" + + bool __fromMessage__(dynamic_reconfigure::Config &msg) + { + const std::vector &__param_descriptions__ = __getParamDescriptions__(); + const std::vector &__group_descriptions__ = __getGroupDescriptions__(); + + int count = 0; + for (std::vector::const_iterator i = __param_descriptions__.begin(); i != __param_descriptions__.end(); ++i) + if ((*i)->fromMessage(msg, *this)) + count++; + + for (std::vector::const_iterator i = __group_descriptions__.begin(); i != __group_descriptions__.end(); i ++) + { + if ((*i)->id == 0) + { + boost::any n = boost::any(this); + (*i)->updateParams(n, *this); + (*i)->fromMessage(msg, n); + } + } + + if (count != dynamic_reconfigure::ConfigTools::size(msg)) + { + ROS_ERROR("RosAriaConfig::__fromMessage__ called with an unexpected parameter."); + ROS_ERROR("Booleans:"); + for (unsigned int i = 0; i < msg.bools.size(); i++) + ROS_ERROR(" %s", msg.bools[i].name.c_str()); + ROS_ERROR("Integers:"); + for (unsigned int i = 0; i < msg.ints.size(); i++) + ROS_ERROR(" %s", msg.ints[i].name.c_str()); + ROS_ERROR("Doubles:"); + for (unsigned int i = 0; i < msg.doubles.size(); i++) + ROS_ERROR(" %s", msg.doubles[i].name.c_str()); + ROS_ERROR("Strings:"); + for (unsigned int i = 0; i < msg.strs.size(); i++) + ROS_ERROR(" %s", msg.strs[i].name.c_str()); + // @todo Check that there are no duplicates. Make this error more + // explicit. + return false; + } + return true; + } + + // This version of __toMessage__ is used during initialization of + // statics when __getParamDescriptions__ can't be called yet. + void __toMessage__(dynamic_reconfigure::Config &msg, const std::vector &__param_descriptions__, const std::vector &__group_descriptions__) const + { + dynamic_reconfigure::ConfigTools::clear(msg); + for (std::vector::const_iterator i = __param_descriptions__.begin(); i != __param_descriptions__.end(); ++i) + (*i)->toMessage(msg, *this); + + for (std::vector::const_iterator i = __group_descriptions__.begin(); i != __group_descriptions__.end(); ++i) + { + if((*i)->id == 0) + { + (*i)->toMessage(msg, *this); + } + } + } + + void __toMessage__(dynamic_reconfigure::Config &msg) const + { + const std::vector &__param_descriptions__ = __getParamDescriptions__(); + const std::vector &__group_descriptions__ = __getGroupDescriptions__(); + __toMessage__(msg, __param_descriptions__, __group_descriptions__); + } + + void __toServer__(const ros::NodeHandle &nh) const + { + const std::vector &__param_descriptions__ = __getParamDescriptions__(); + for (std::vector::const_iterator i = __param_descriptions__.begin(); i != __param_descriptions__.end(); ++i) + (*i)->toServer(nh, *this); + } + + void __fromServer__(const ros::NodeHandle &nh) + { + static bool setup=false; + + const std::vector &__param_descriptions__ = __getParamDescriptions__(); + for (std::vector::const_iterator i = __param_descriptions__.begin(); i != __param_descriptions__.end(); ++i) + (*i)->fromServer(nh, *this); + + const std::vector &__group_descriptions__ = __getGroupDescriptions__(); + for (std::vector::const_iterator i = __group_descriptions__.begin(); i != __group_descriptions__.end(); i++){ + if (!setup && (*i)->id == 0) { + setup = true; + boost::any n = boost::any(this); + (*i)->setInitialState(n); + } + } + } + + void __clamp__() + { + const std::vector &__param_descriptions__ = __getParamDescriptions__(); + const RosAriaConfig &__max__ = __getMax__(); + const RosAriaConfig &__min__ = __getMin__(); + for (std::vector::const_iterator i = __param_descriptions__.begin(); i != __param_descriptions__.end(); ++i) + (*i)->clamp(*this, __max__, __min__); + } + + uint32_t __level__(const RosAriaConfig &config) const + { + const std::vector &__param_descriptions__ = __getParamDescriptions__(); + uint32_t level = 0; + for (std::vector::const_iterator i = __param_descriptions__.begin(); i != __param_descriptions__.end(); ++i) + (*i)->calcLevel(level, config, *this); + return level; + } + + static const dynamic_reconfigure::ConfigDescription &__getDescriptionMessage__(); + static const RosAriaConfig &__getDefault__(); + static const RosAriaConfig &__getMax__(); + static const RosAriaConfig &__getMin__(); + static const std::vector &__getParamDescriptions__(); + static const std::vector &__getGroupDescriptions__(); + + private: + static const RosAriaConfigStatics *__get_statics__(); + }; + + template <> // Max and min are ignored for strings. + inline void RosAriaConfig::ParamDescription::clamp(RosAriaConfig &config, const RosAriaConfig &max, const RosAriaConfig &min) const + { + return; + } + + class RosAriaConfigStatics + { + friend class RosAriaConfig; + + RosAriaConfigStatics() + { +RosAriaConfig::GroupDescription Default("Default", "", 0, 0, true, &RosAriaConfig::groups); +//#line 262 "/opt/ros/hydro/lib/python2.7/dist-packages/dynamic_reconfigure/parameter_generator_catkin.py" + __min__.trans_accel = -std::numeric_limits::infinity(); +//#line 262 "/opt/ros/hydro/lib/python2.7/dist-packages/dynamic_reconfigure/parameter_generator_catkin.py" + __max__.trans_accel = std::numeric_limits::infinity(); +//#line 262 "/opt/ros/hydro/lib/python2.7/dist-packages/dynamic_reconfigure/parameter_generator_catkin.py" + __default__.trans_accel = 0; +//#line 262 "/opt/ros/hydro/lib/python2.7/dist-packages/dynamic_reconfigure/parameter_generator_catkin.py" + Default.abstract_parameters.push_back(RosAriaConfig::AbstractParamDescriptionConstPtr(new RosAriaConfig::ParamDescription("trans_accel", "double", 0, "Translational acceleration (m/s^2)", "", &RosAriaConfig::trans_accel))); +//#line 262 "/opt/ros/hydro/lib/python2.7/dist-packages/dynamic_reconfigure/parameter_generator_catkin.py" + __param_descriptions__.push_back(RosAriaConfig::AbstractParamDescriptionConstPtr(new RosAriaConfig::ParamDescription("trans_accel", "double", 0, "Translational acceleration (m/s^2)", "", &RosAriaConfig::trans_accel))); +//#line 262 "/opt/ros/hydro/lib/python2.7/dist-packages/dynamic_reconfigure/parameter_generator_catkin.py" + __min__.trans_decel = -std::numeric_limits::infinity(); +//#line 262 "/opt/ros/hydro/lib/python2.7/dist-packages/dynamic_reconfigure/parameter_generator_catkin.py" + __max__.trans_decel = std::numeric_limits::infinity(); +//#line 262 "/opt/ros/hydro/lib/python2.7/dist-packages/dynamic_reconfigure/parameter_generator_catkin.py" + __default__.trans_decel = 0; +//#line 262 "/opt/ros/hydro/lib/python2.7/dist-packages/dynamic_reconfigure/parameter_generator_catkin.py" + Default.abstract_parameters.push_back(RosAriaConfig::AbstractParamDescriptionConstPtr(new RosAriaConfig::ParamDescription("trans_decel", "double", 0, "Translational deceleration (m/s^2)", "", &RosAriaConfig::trans_decel))); +//#line 262 "/opt/ros/hydro/lib/python2.7/dist-packages/dynamic_reconfigure/parameter_generator_catkin.py" + __param_descriptions__.push_back(RosAriaConfig::AbstractParamDescriptionConstPtr(new RosAriaConfig::ParamDescription("trans_decel", "double", 0, "Translational deceleration (m/s^2)", "", &RosAriaConfig::trans_decel))); +//#line 262 "/opt/ros/hydro/lib/python2.7/dist-packages/dynamic_reconfigure/parameter_generator_catkin.py" + __min__.lat_accel = -std::numeric_limits::infinity(); +//#line 262 "/opt/ros/hydro/lib/python2.7/dist-packages/dynamic_reconfigure/parameter_generator_catkin.py" + __max__.lat_accel = std::numeric_limits::infinity(); +//#line 262 "/opt/ros/hydro/lib/python2.7/dist-packages/dynamic_reconfigure/parameter_generator_catkin.py" + __default__.lat_accel = 0; +//#line 262 "/opt/ros/hydro/lib/python2.7/dist-packages/dynamic_reconfigure/parameter_generator_catkin.py" + Default.abstract_parameters.push_back(RosAriaConfig::AbstractParamDescriptionConstPtr(new RosAriaConfig::ParamDescription("lat_accel", "double", 0, "Lateral acceleration (m/s^2)", "", &RosAriaConfig::lat_accel))); +//#line 262 "/opt/ros/hydro/lib/python2.7/dist-packages/dynamic_reconfigure/parameter_generator_catkin.py" + __param_descriptions__.push_back(RosAriaConfig::AbstractParamDescriptionConstPtr(new RosAriaConfig::ParamDescription("lat_accel", "double", 0, "Lateral acceleration (m/s^2)", "", &RosAriaConfig::lat_accel))); +//#line 262 "/opt/ros/hydro/lib/python2.7/dist-packages/dynamic_reconfigure/parameter_generator_catkin.py" + __min__.lat_decel = -std::numeric_limits::infinity(); +//#line 262 "/opt/ros/hydro/lib/python2.7/dist-packages/dynamic_reconfigure/parameter_generator_catkin.py" + __max__.lat_decel = std::numeric_limits::infinity(); +//#line 262 "/opt/ros/hydro/lib/python2.7/dist-packages/dynamic_reconfigure/parameter_generator_catkin.py" + __default__.lat_decel = 0; +//#line 262 "/opt/ros/hydro/lib/python2.7/dist-packages/dynamic_reconfigure/parameter_generator_catkin.py" + Default.abstract_parameters.push_back(RosAriaConfig::AbstractParamDescriptionConstPtr(new RosAriaConfig::ParamDescription("lat_decel", "double", 0, "Lateral deceleration (m/s^2)", "", &RosAriaConfig::lat_decel))); +//#line 262 "/opt/ros/hydro/lib/python2.7/dist-packages/dynamic_reconfigure/parameter_generator_catkin.py" + __param_descriptions__.push_back(RosAriaConfig::AbstractParamDescriptionConstPtr(new RosAriaConfig::ParamDescription("lat_decel", "double", 0, "Lateral deceleration (m/s^2)", "", &RosAriaConfig::lat_decel))); +//#line 262 "/opt/ros/hydro/lib/python2.7/dist-packages/dynamic_reconfigure/parameter_generator_catkin.py" + __min__.rot_accel = -std::numeric_limits::infinity(); +//#line 262 "/opt/ros/hydro/lib/python2.7/dist-packages/dynamic_reconfigure/parameter_generator_catkin.py" + __max__.rot_accel = std::numeric_limits::infinity(); +//#line 262 "/opt/ros/hydro/lib/python2.7/dist-packages/dynamic_reconfigure/parameter_generator_catkin.py" + __default__.rot_accel = 0; +//#line 262 "/opt/ros/hydro/lib/python2.7/dist-packages/dynamic_reconfigure/parameter_generator_catkin.py" + Default.abstract_parameters.push_back(RosAriaConfig::AbstractParamDescriptionConstPtr(new RosAriaConfig::ParamDescription("rot_accel", "double", 0, "Rotational acceleration (rad/s^2)", "", &RosAriaConfig::rot_accel))); +//#line 262 "/opt/ros/hydro/lib/python2.7/dist-packages/dynamic_reconfigure/parameter_generator_catkin.py" + __param_descriptions__.push_back(RosAriaConfig::AbstractParamDescriptionConstPtr(new RosAriaConfig::ParamDescription("rot_accel", "double", 0, "Rotational acceleration (rad/s^2)", "", &RosAriaConfig::rot_accel))); +//#line 262 "/opt/ros/hydro/lib/python2.7/dist-packages/dynamic_reconfigure/parameter_generator_catkin.py" + __min__.rot_decel = -std::numeric_limits::infinity(); +//#line 262 "/opt/ros/hydro/lib/python2.7/dist-packages/dynamic_reconfigure/parameter_generator_catkin.py" + __max__.rot_decel = std::numeric_limits::infinity(); +//#line 262 "/opt/ros/hydro/lib/python2.7/dist-packages/dynamic_reconfigure/parameter_generator_catkin.py" + __default__.rot_decel = 0; +//#line 262 "/opt/ros/hydro/lib/python2.7/dist-packages/dynamic_reconfigure/parameter_generator_catkin.py" + Default.abstract_parameters.push_back(RosAriaConfig::AbstractParamDescriptionConstPtr(new RosAriaConfig::ParamDescription("rot_decel", "double", 0, "Rotational deceleration (rad/s^2)", "", &RosAriaConfig::rot_decel))); +//#line 262 "/opt/ros/hydro/lib/python2.7/dist-packages/dynamic_reconfigure/parameter_generator_catkin.py" + __param_descriptions__.push_back(RosAriaConfig::AbstractParamDescriptionConstPtr(new RosAriaConfig::ParamDescription("rot_decel", "double", 0, "Rotational deceleration (rad/s^2)", "", &RosAriaConfig::rot_decel))); +//#line 262 "/opt/ros/hydro/lib/python2.7/dist-packages/dynamic_reconfigure/parameter_generator_catkin.py" + __min__.TicksMM = -2147483648; +//#line 262 "/opt/ros/hydro/lib/python2.7/dist-packages/dynamic_reconfigure/parameter_generator_catkin.py" + __max__.TicksMM = 2147483647; +//#line 262 "/opt/ros/hydro/lib/python2.7/dist-packages/dynamic_reconfigure/parameter_generator_catkin.py" + __default__.TicksMM = 0; +//#line 262 "/opt/ros/hydro/lib/python2.7/dist-packages/dynamic_reconfigure/parameter_generator_catkin.py" + Default.abstract_parameters.push_back(RosAriaConfig::AbstractParamDescriptionConstPtr(new RosAriaConfig::ParamDescription("TicksMM", "int", 0, "Encoder ticks/mm", "", &RosAriaConfig::TicksMM))); +//#line 262 "/opt/ros/hydro/lib/python2.7/dist-packages/dynamic_reconfigure/parameter_generator_catkin.py" + __param_descriptions__.push_back(RosAriaConfig::AbstractParamDescriptionConstPtr(new RosAriaConfig::ParamDescription("TicksMM", "int", 0, "Encoder ticks/mm", "", &RosAriaConfig::TicksMM))); +//#line 262 "/opt/ros/hydro/lib/python2.7/dist-packages/dynamic_reconfigure/parameter_generator_catkin.py" + __min__.DriftFactor = -2147483648; +//#line 262 "/opt/ros/hydro/lib/python2.7/dist-packages/dynamic_reconfigure/parameter_generator_catkin.py" + __max__.DriftFactor = 2147483647; +//#line 262 "/opt/ros/hydro/lib/python2.7/dist-packages/dynamic_reconfigure/parameter_generator_catkin.py" + __default__.DriftFactor = 0; +//#line 262 "/opt/ros/hydro/lib/python2.7/dist-packages/dynamic_reconfigure/parameter_generator_catkin.py" + Default.abstract_parameters.push_back(RosAriaConfig::AbstractParamDescriptionConstPtr(new RosAriaConfig::ParamDescription("DriftFactor", "int", 0, "Value in 1/8192 increments to be added or subtracted from the left encoder ticks in order to compensate for tire differences.", "", &RosAriaConfig::DriftFactor))); +//#line 262 "/opt/ros/hydro/lib/python2.7/dist-packages/dynamic_reconfigure/parameter_generator_catkin.py" + __param_descriptions__.push_back(RosAriaConfig::AbstractParamDescriptionConstPtr(new RosAriaConfig::ParamDescription("DriftFactor", "int", 0, "Value in 1/8192 increments to be added or subtracted from the left encoder ticks in order to compensate for tire differences.", "", &RosAriaConfig::DriftFactor))); +//#line 262 "/opt/ros/hydro/lib/python2.7/dist-packages/dynamic_reconfigure/parameter_generator_catkin.py" + __min__.RevCount = -2147483648; +//#line 262 "/opt/ros/hydro/lib/python2.7/dist-packages/dynamic_reconfigure/parameter_generator_catkin.py" + __max__.RevCount = 2147483647; +//#line 262 "/opt/ros/hydro/lib/python2.7/dist-packages/dynamic_reconfigure/parameter_generator_catkin.py" + __default__.RevCount = 0; +//#line 262 "/opt/ros/hydro/lib/python2.7/dist-packages/dynamic_reconfigure/parameter_generator_catkin.py" + Default.abstract_parameters.push_back(RosAriaConfig::AbstractParamDescriptionConstPtr(new RosAriaConfig::ParamDescription("RevCount", "int", 0, "The number of differential encoder ticks for a 180-degree revolution of the robot.", "", &RosAriaConfig::RevCount))); +//#line 262 "/opt/ros/hydro/lib/python2.7/dist-packages/dynamic_reconfigure/parameter_generator_catkin.py" + __param_descriptions__.push_back(RosAriaConfig::AbstractParamDescriptionConstPtr(new RosAriaConfig::ParamDescription("RevCount", "int", 0, "The number of differential encoder ticks for a 180-degree revolution of the robot.", "", &RosAriaConfig::RevCount))); +//#line 233 "/opt/ros/hydro/lib/python2.7/dist-packages/dynamic_reconfigure/parameter_generator_catkin.py" + Default.convertParams(); +//#line 233 "/opt/ros/hydro/lib/python2.7/dist-packages/dynamic_reconfigure/parameter_generator_catkin.py" + __group_descriptions__.push_back(RosAriaConfig::AbstractGroupDescriptionConstPtr(new RosAriaConfig::GroupDescription(Default))); +//#line 390 "/opt/ros/hydro/share/dynamic_reconfigure/cmake/../templates/ConfigType.h.template" + + for (std::vector::const_iterator i = __group_descriptions__.begin(); i != __group_descriptions__.end(); ++i) + { + __description_message__.groups.push_back(**i); + } + __max__.__toMessage__(__description_message__.max, __param_descriptions__, __group_descriptions__); + __min__.__toMessage__(__description_message__.min, __param_descriptions__, __group_descriptions__); + __default__.__toMessage__(__description_message__.dflt, __param_descriptions__, __group_descriptions__); + } + std::vector __param_descriptions__; + std::vector __group_descriptions__; + RosAriaConfig __max__; + RosAriaConfig __min__; + RosAriaConfig __default__; + dynamic_reconfigure::ConfigDescription __description_message__; + + static const RosAriaConfigStatics *get_instance() + { + // Split this off in a separate function because I know that + // instance will get initialized the first time get_instance is + // called, and I am guaranteeing that get_instance gets called at + // most once. + static RosAriaConfigStatics instance; + return &instance; + } + }; + + inline const dynamic_reconfigure::ConfigDescription &RosAriaConfig::__getDescriptionMessage__() + { + return __get_statics__()->__description_message__; + } + + inline const RosAriaConfig &RosAriaConfig::__getDefault__() + { + return __get_statics__()->__default__; + } + + inline const RosAriaConfig &RosAriaConfig::__getMax__() + { + return __get_statics__()->__max__; + } + + inline const RosAriaConfig &RosAriaConfig::__getMin__() + { + return __get_statics__()->__min__; + } + + inline const std::vector &RosAriaConfig::__getParamDescriptions__() + { + return __get_statics__()->__param_descriptions__; + } + + inline const std::vector &RosAriaConfig::__getGroupDescriptions__() + { + return __get_statics__()->__group_descriptions__; + } + + inline const RosAriaConfigStatics *RosAriaConfig::__get_statics__() + { + const static RosAriaConfigStatics *statics; + + if (statics) // Common case + return statics; + + boost::mutex::scoped_lock lock(dynamic_reconfigure::__init_mutex__); + + if (statics) // In case we lost a race. + return statics; + + statics = RosAriaConfigStatics::get_instance(); + + return statics; + } + + +} + +#endif // __ROSARIARECONFIGURATOR_H__ diff --git a/Legacy/ws_linux/devel/include/rosaria_msgs/RestrictionsMsg.h b/Legacy/ws_linux/devel/include/rosaria_msgs/RestrictionsMsg.h new file mode 100644 index 0000000..0101656 --- /dev/null +++ b/Legacy/ws_linux/devel/include/rosaria_msgs/RestrictionsMsg.h @@ -0,0 +1,246 @@ +/* Software License Agreement (BSD License) + * + * Copyright (c) 2011, Willow Garage, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of Willow Garage, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * Auto-generated by genmsg_cpp from file /home/lab1_5/ws/ws_linux/src/rosaria_msgs/msg/RestrictionsMsg.msg + * + */ + + +#ifndef ROSARIA_MSGS_MESSAGE_RESTRICTIONSMSG_H +#define ROSARIA_MSGS_MESSAGE_RESTRICTIONSMSG_H + + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +namespace rosaria_msgs +{ +template +struct RestrictionsMsg_ +{ + typedef RestrictionsMsg_ Type; + + RestrictionsMsg_() + : distance() + , linear_velocity() + , angular_velocity() { + } + RestrictionsMsg_(const ContainerAllocator& _alloc) + : distance(_alloc) + , linear_velocity(_alloc) + , angular_velocity(_alloc) { + } + + + + typedef ::std_msgs::Float64_ _distance_type; + _distance_type distance; + + typedef ::std_msgs::Float64_ _linear_velocity_type; + _linear_velocity_type linear_velocity; + + typedef ::std_msgs::Float64_ _angular_velocity_type; + _angular_velocity_type angular_velocity; + + + + + typedef boost::shared_ptr< ::rosaria_msgs::RestrictionsMsg_ > Ptr; + typedef boost::shared_ptr< ::rosaria_msgs::RestrictionsMsg_ const> ConstPtr; + boost::shared_ptr > __connection_header; + +}; // struct RestrictionsMsg_ + +typedef ::rosaria_msgs::RestrictionsMsg_ > RestrictionsMsg; + +typedef boost::shared_ptr< ::rosaria_msgs::RestrictionsMsg > RestrictionsMsgPtr; +typedef boost::shared_ptr< ::rosaria_msgs::RestrictionsMsg const> RestrictionsMsgConstPtr; + +// constants requiring out of line definition + + + +template +std::ostream& operator<<(std::ostream& s, const ::rosaria_msgs::RestrictionsMsg_ & v) +{ +ros::message_operations::Printer< ::rosaria_msgs::RestrictionsMsg_ >::stream(s, "", v); +return s; +} + +} // namespace rosaria_msgs + +namespace ros +{ +namespace message_traits +{ + + + +// BOOLTRAITS {'IsFixedSize': True, 'IsMessage': True, 'HasHeader': False} +// {'std_msgs': ['/opt/ros/hydro/share/std_msgs/cmake/../msg'], 'rosaria_msgs': ['/home/lab1_5/ws/ws_linux/src/rosaria_msgs/msg'], 'geometry_msgs': ['/opt/ros/hydro/share/geometry_msgs/cmake/../msg']} + +// !!!!!!!!!!! ['__class__', '__delattr__', '__dict__', '__doc__', '__eq__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_parsed_fields', 'constants', 'fields', 'full_name', 'has_header', 'header_present', 'names', 'package', 'parsed_fields', 'short_name', 'text', 'types'] + + + + +template +struct IsFixedSize< ::rosaria_msgs::RestrictionsMsg_ > + : TrueType + { }; + +template +struct IsFixedSize< ::rosaria_msgs::RestrictionsMsg_ const> + : TrueType + { }; + +template +struct IsMessage< ::rosaria_msgs::RestrictionsMsg_ > + : TrueType + { }; + +template +struct IsMessage< ::rosaria_msgs::RestrictionsMsg_ const> + : TrueType + { }; + +template +struct HasHeader< ::rosaria_msgs::RestrictionsMsg_ > + : FalseType + { }; + +template +struct HasHeader< ::rosaria_msgs::RestrictionsMsg_ const> + : FalseType + { }; + + +template +struct MD5Sum< ::rosaria_msgs::RestrictionsMsg_ > +{ + static const char* value() + { + return "c2466ab186049d2506624976271d3b3e"; + } + + static const char* value(const ::rosaria_msgs::RestrictionsMsg_&) { return value(); } + static const uint64_t static_value1 = 0xc2466ab186049d25ULL; + static const uint64_t static_value2 = 0x06624976271d3b3eULL; +}; + +template +struct DataType< ::rosaria_msgs::RestrictionsMsg_ > +{ + static const char* value() + { + return "rosaria_msgs/RestrictionsMsg"; + } + + static const char* value(const ::rosaria_msgs::RestrictionsMsg_&) { return value(); } +}; + +template +struct Definition< ::rosaria_msgs::RestrictionsMsg_ > +{ + static const char* value() + { + return "std_msgs/Float64 distance\n\ +std_msgs/Float64 linear_velocity\n\ +std_msgs/Float64 angular_velocity\n\ +================================================================================\n\ +MSG: std_msgs/Float64\n\ +float64 data\n\ +"; + } + + static const char* value(const ::rosaria_msgs::RestrictionsMsg_&) { return value(); } +}; + +} // namespace message_traits +} // namespace ros + +namespace ros +{ +namespace serialization +{ + + template struct Serializer< ::rosaria_msgs::RestrictionsMsg_ > + { + template inline static void allInOne(Stream& stream, T m) + { + stream.next(m.distance); + stream.next(m.linear_velocity); + stream.next(m.angular_velocity); + } + + ROS_DECLARE_ALLINONE_SERIALIZER; + }; // struct RestrictionsMsg_ + +} // namespace serialization +} // namespace ros + +namespace ros +{ +namespace message_operations +{ + +template +struct Printer< ::rosaria_msgs::RestrictionsMsg_ > +{ + template static void stream(Stream& s, const std::string& indent, const ::rosaria_msgs::RestrictionsMsg_& v) + { + s << indent << "distance: "; + s << std::endl; + Printer< ::std_msgs::Float64_ >::stream(s, indent + " ", v.distance); + s << indent << "linear_velocity: "; + s << std::endl; + Printer< ::std_msgs::Float64_ >::stream(s, indent + " ", v.linear_velocity); + s << indent << "angular_velocity: "; + s << std::endl; + Printer< ::std_msgs::Float64_ >::stream(s, indent + " ", v.angular_velocity); + } +}; + +} // namespace message_operations +} // namespace ros + +#endif // ROSARIA_MSGS_MESSAGE_RESTRICTIONSMSG_H diff --git a/Legacy/ws_linux/devel/include/rosaria_msgs/RobotInfoMsg.h b/Legacy/ws_linux/devel/include/rosaria_msgs/RobotInfoMsg.h new file mode 100644 index 0000000..226332f --- /dev/null +++ b/Legacy/ws_linux/devel/include/rosaria_msgs/RobotInfoMsg.h @@ -0,0 +1,299 @@ +/* Software License Agreement (BSD License) + * + * Copyright (c) 2011, Willow Garage, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of Willow Garage, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * Auto-generated by genmsg_cpp from file /home/lab1_5/ws/ws_linux/src/rosaria_msgs/msg/RobotInfoMsg.msg + * + */ + + +#ifndef ROSARIA_MSGS_MESSAGE_ROBOTINFOMSG_H +#define ROSARIA_MSGS_MESSAGE_ROBOTINFOMSG_H + + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace rosaria_msgs +{ +template +struct RobotInfoMsg_ +{ + typedef RobotInfoMsg_ Type; + + RobotInfoMsg_() + : robot_id() + , battery_voltage() + , twist() + , state() + , clutch() + , obstacle_detected() { + } + RobotInfoMsg_(const ContainerAllocator& _alloc) + : robot_id(_alloc) + , battery_voltage(_alloc) + , twist(_alloc) + , state(_alloc) + , clutch(_alloc) + , obstacle_detected(_alloc) { + } + + + + typedef ::std_msgs::UInt8_ _robot_id_type; + _robot_id_type robot_id; + + typedef ::std_msgs::Float64_ _battery_voltage_type; + _battery_voltage_type battery_voltage; + + typedef ::geometry_msgs::Twist_ _twist_type; + _twist_type twist; + + typedef ::std_msgs::Bool_ _state_type; + _state_type state; + + typedef ::std_msgs::Bool_ _clutch_type; + _clutch_type clutch; + + typedef ::std_msgs::Bool_ _obstacle_detected_type; + _obstacle_detected_type obstacle_detected; + + + + + typedef boost::shared_ptr< ::rosaria_msgs::RobotInfoMsg_ > Ptr; + typedef boost::shared_ptr< ::rosaria_msgs::RobotInfoMsg_ const> ConstPtr; + boost::shared_ptr > __connection_header; + +}; // struct RobotInfoMsg_ + +typedef ::rosaria_msgs::RobotInfoMsg_ > RobotInfoMsg; + +typedef boost::shared_ptr< ::rosaria_msgs::RobotInfoMsg > RobotInfoMsgPtr; +typedef boost::shared_ptr< ::rosaria_msgs::RobotInfoMsg const> RobotInfoMsgConstPtr; + +// constants requiring out of line definition + + + +template +std::ostream& operator<<(std::ostream& s, const ::rosaria_msgs::RobotInfoMsg_ & v) +{ +ros::message_operations::Printer< ::rosaria_msgs::RobotInfoMsg_ >::stream(s, "", v); +return s; +} + +} // namespace rosaria_msgs + +namespace ros +{ +namespace message_traits +{ + + + +// BOOLTRAITS {'IsFixedSize': True, 'IsMessage': True, 'HasHeader': False} +// {'std_msgs': ['/opt/ros/hydro/share/std_msgs/cmake/../msg'], 'rosaria_msgs': ['/home/lab1_5/ws/ws_linux/src/rosaria_msgs/msg'], 'geometry_msgs': ['/opt/ros/hydro/share/geometry_msgs/cmake/../msg']} + +// !!!!!!!!!!! ['__class__', '__delattr__', '__dict__', '__doc__', '__eq__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_parsed_fields', 'constants', 'fields', 'full_name', 'has_header', 'header_present', 'names', 'package', 'parsed_fields', 'short_name', 'text', 'types'] + + + + +template +struct IsFixedSize< ::rosaria_msgs::RobotInfoMsg_ > + : TrueType + { }; + +template +struct IsFixedSize< ::rosaria_msgs::RobotInfoMsg_ const> + : TrueType + { }; + +template +struct IsMessage< ::rosaria_msgs::RobotInfoMsg_ > + : TrueType + { }; + +template +struct IsMessage< ::rosaria_msgs::RobotInfoMsg_ const> + : TrueType + { }; + +template +struct HasHeader< ::rosaria_msgs::RobotInfoMsg_ > + : FalseType + { }; + +template +struct HasHeader< ::rosaria_msgs::RobotInfoMsg_ const> + : FalseType + { }; + + +template +struct MD5Sum< ::rosaria_msgs::RobotInfoMsg_ > +{ + static const char* value() + { + return "fc20ec1228cc0538c3b1ee05e9614d34"; + } + + static const char* value(const ::rosaria_msgs::RobotInfoMsg_&) { return value(); } + static const uint64_t static_value1 = 0xfc20ec1228cc0538ULL; + static const uint64_t static_value2 = 0xc3b1ee05e9614d34ULL; +}; + +template +struct DataType< ::rosaria_msgs::RobotInfoMsg_ > +{ + static const char* value() + { + return "rosaria_msgs/RobotInfoMsg"; + } + + static const char* value(const ::rosaria_msgs::RobotInfoMsg_&) { return value(); } +}; + +template +struct Definition< ::rosaria_msgs::RobotInfoMsg_ > +{ + static const char* value() + { + return "std_msgs/UInt8 robot_id\n\ +std_msgs/Float64 battery_voltage\n\ +geometry_msgs/Twist twist\n\ +std_msgs/Bool state\n\ +std_msgs/Bool clutch\n\ +std_msgs/Bool obstacle_detected\n\ +================================================================================\n\ +MSG: std_msgs/UInt8\n\ +uint8 data\n\ +\n\ +================================================================================\n\ +MSG: std_msgs/Float64\n\ +float64 data\n\ +================================================================================\n\ +MSG: geometry_msgs/Twist\n\ +# This expresses velocity in free space broken into its linear and angular parts.\n\ +Vector3 linear\n\ +Vector3 angular\n\ +\n\ +================================================================================\n\ +MSG: geometry_msgs/Vector3\n\ +# This represents a vector in free space. \n\ +\n\ +float64 x\n\ +float64 y\n\ +float64 z\n\ +================================================================================\n\ +MSG: std_msgs/Bool\n\ +bool data\n\ +"; + } + + static const char* value(const ::rosaria_msgs::RobotInfoMsg_&) { return value(); } +}; + +} // namespace message_traits +} // namespace ros + +namespace ros +{ +namespace serialization +{ + + template struct Serializer< ::rosaria_msgs::RobotInfoMsg_ > + { + template inline static void allInOne(Stream& stream, T m) + { + stream.next(m.robot_id); + stream.next(m.battery_voltage); + stream.next(m.twist); + stream.next(m.state); + stream.next(m.clutch); + stream.next(m.obstacle_detected); + } + + ROS_DECLARE_ALLINONE_SERIALIZER; + }; // struct RobotInfoMsg_ + +} // namespace serialization +} // namespace ros + +namespace ros +{ +namespace message_operations +{ + +template +struct Printer< ::rosaria_msgs::RobotInfoMsg_ > +{ + template static void stream(Stream& s, const std::string& indent, const ::rosaria_msgs::RobotInfoMsg_& v) + { + s << indent << "robot_id: "; + s << std::endl; + Printer< ::std_msgs::UInt8_ >::stream(s, indent + " ", v.robot_id); + s << indent << "battery_voltage: "; + s << std::endl; + Printer< ::std_msgs::Float64_ >::stream(s, indent + " ", v.battery_voltage); + s << indent << "twist: "; + s << std::endl; + Printer< ::geometry_msgs::Twist_ >::stream(s, indent + " ", v.twist); + s << indent << "state: "; + s << std::endl; + Printer< ::std_msgs::Bool_ >::stream(s, indent + " ", v.state); + s << indent << "clutch: "; + s << std::endl; + Printer< ::std_msgs::Bool_ >::stream(s, indent + " ", v.clutch); + s << indent << "obstacle_detected: "; + s << std::endl; + Printer< ::std_msgs::Bool_ >::stream(s, indent + " ", v.obstacle_detected); + } +}; + +} // namespace message_operations +} // namespace ros + +#endif // ROSARIA_MSGS_MESSAGE_ROBOTINFOMSG_H diff --git a/Legacy/ws_linux/devel/include/videostream/ip_get.h b/Legacy/ws_linux/devel/include/videostream/ip_get.h new file mode 100644 index 0000000..5a5b0a1 --- /dev/null +++ b/Legacy/ws_linux/devel/include/videostream/ip_get.h @@ -0,0 +1,156 @@ +/* Software License Agreement (BSD License) + * + * Copyright (c) 2011, Willow Garage, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of Willow Garage, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * Auto-generated by gensrv_cpp from file /home/lab1_5/ws/ws_linux/src/videostream/srv/ip_get.srv + * + */ + + +#ifndef VIDEOSTREAM_MESSAGE_IP_GET_H +#define VIDEOSTREAM_MESSAGE_IP_GET_H + +#include + + +#include +#include + + +namespace videostream +{ + +struct ip_get +{ + +typedef ip_getRequest Request; +typedef ip_getResponse Response; +Request request; +Response response; + +typedef Request RequestType; +typedef Response ResponseType; + +}; // struct ip_get +} // namespace videostream + + +namespace ros +{ +namespace service_traits +{ + + +template<> +struct MD5Sum< ::videostream::ip_get > { + static const char* value() + { + return "994972b6e03928b2476860ce6c4c8e17"; + } + + static const char* value(const ::videostream::ip_get&) { return value(); } +}; + +template<> +struct DataType< ::videostream::ip_get > { + static const char* value() + { + return "videostream/ip_get"; + } + + static const char* value(const ::videostream::ip_get&) { return value(); } +}; + + +// service_traits::MD5Sum< ::videostream::ip_getRequest> should match +// service_traits::MD5Sum< ::videostream::ip_get > +template<> +struct MD5Sum< ::videostream::ip_getRequest> +{ + static const char* value() + { + return MD5Sum< ::videostream::ip_get >::value(); + } + static const char* value(const ::videostream::ip_getRequest&) + { + return value(); + } +}; + +// service_traits::DataType< ::videostream::ip_getRequest> should match +// service_traits::DataType< ::videostream::ip_get > +template<> +struct DataType< ::videostream::ip_getRequest> +{ + static const char* value() + { + return DataType< ::videostream::ip_get >::value(); + } + static const char* value(const ::videostream::ip_getRequest&) + { + return value(); + } +}; + +// service_traits::MD5Sum< ::videostream::ip_getResponse> should match +// service_traits::MD5Sum< ::videostream::ip_get > +template<> +struct MD5Sum< ::videostream::ip_getResponse> +{ + static const char* value() + { + return MD5Sum< ::videostream::ip_get >::value(); + } + static const char* value(const ::videostream::ip_getResponse&) + { + return value(); + } +}; + +// service_traits::DataType< ::videostream::ip_getResponse> should match +// service_traits::DataType< ::videostream::ip_get > +template<> +struct DataType< ::videostream::ip_getResponse> +{ + static const char* value() + { + return DataType< ::videostream::ip_get >::value(); + } + static const char* value(const ::videostream::ip_getResponse&) + { + return value(); + } +}; + +} // namespace service_traits +} // namespace ros + +#endif // VIDEOSTREAM_MESSAGE_IP_GET_H diff --git a/Legacy/ws_linux/devel/include/videostream/ip_getRequest.h b/Legacy/ws_linux/devel/include/videostream/ip_getRequest.h new file mode 100644 index 0000000..f0bd0bb --- /dev/null +++ b/Legacy/ws_linux/devel/include/videostream/ip_getRequest.h @@ -0,0 +1,219 @@ +/* Software License Agreement (BSD License) + * + * Copyright (c) 2011, Willow Garage, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of Willow Garage, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * Auto-generated by genmsg_cpp from file /home/lab1_5/ws/ws_linux/src/videostream/srv/ip_get.srv + * + */ + + +#ifndef VIDEOSTREAM_MESSAGE_IP_GETREQUEST_H +#define VIDEOSTREAM_MESSAGE_IP_GETREQUEST_H + + +#include +#include +#include + +#include +#include +#include +#include + + +namespace videostream +{ +template +struct ip_getRequest_ +{ + typedef ip_getRequest_ Type; + + ip_getRequest_() + : str() { + } + ip_getRequest_(const ContainerAllocator& _alloc) + : str(_alloc) { + } + + + + typedef std::basic_string, typename ContainerAllocator::template rebind::other > _str_type; + _str_type str; + + + + + typedef boost::shared_ptr< ::videostream::ip_getRequest_ > Ptr; + typedef boost::shared_ptr< ::videostream::ip_getRequest_ const> ConstPtr; + boost::shared_ptr > __connection_header; + +}; // struct ip_getRequest_ + +typedef ::videostream::ip_getRequest_ > ip_getRequest; + +typedef boost::shared_ptr< ::videostream::ip_getRequest > ip_getRequestPtr; +typedef boost::shared_ptr< ::videostream::ip_getRequest const> ip_getRequestConstPtr; + +// constants requiring out of line definition + + + +template +std::ostream& operator<<(std::ostream& s, const ::videostream::ip_getRequest_ & v) +{ +ros::message_operations::Printer< ::videostream::ip_getRequest_ >::stream(s, "", v); +return s; +} + +} // namespace videostream + +namespace ros +{ +namespace message_traits +{ + + + +// BOOLTRAITS {'IsFixedSize': False, 'IsMessage': True, 'HasHeader': False} +// {'std_msgs': ['/opt/ros/hydro/share/std_msgs/cmake/../msg']} + +// !!!!!!!!!!! ['__class__', '__delattr__', '__dict__', '__doc__', '__eq__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_parsed_fields', 'constants', 'fields', 'full_name', 'has_header', 'header_present', 'names', 'package', 'parsed_fields', 'short_name', 'text', 'types'] + + + + +template +struct IsFixedSize< ::videostream::ip_getRequest_ > + : FalseType + { }; + +template +struct IsFixedSize< ::videostream::ip_getRequest_ const> + : FalseType + { }; + +template +struct IsMessage< ::videostream::ip_getRequest_ > + : TrueType + { }; + +template +struct IsMessage< ::videostream::ip_getRequest_ const> + : TrueType + { }; + +template +struct HasHeader< ::videostream::ip_getRequest_ > + : FalseType + { }; + +template +struct HasHeader< ::videostream::ip_getRequest_ const> + : FalseType + { }; + + +template +struct MD5Sum< ::videostream::ip_getRequest_ > +{ + static const char* value() + { + return "994972b6e03928b2476860ce6c4c8e17"; + } + + static const char* value(const ::videostream::ip_getRequest_&) { return value(); } + static const uint64_t static_value1 = 0x994972b6e03928b2ULL; + static const uint64_t static_value2 = 0x476860ce6c4c8e17ULL; +}; + +template +struct DataType< ::videostream::ip_getRequest_ > +{ + static const char* value() + { + return "videostream/ip_getRequest"; + } + + static const char* value(const ::videostream::ip_getRequest_&) { return value(); } +}; + +template +struct Definition< ::videostream::ip_getRequest_ > +{ + static const char* value() + { + return "string str\n\ +"; + } + + static const char* value(const ::videostream::ip_getRequest_&) { return value(); } +}; + +} // namespace message_traits +} // namespace ros + +namespace ros +{ +namespace serialization +{ + + template struct Serializer< ::videostream::ip_getRequest_ > + { + template inline static void allInOne(Stream& stream, T m) + { + stream.next(m.str); + } + + ROS_DECLARE_ALLINONE_SERIALIZER; + }; // struct ip_getRequest_ + +} // namespace serialization +} // namespace ros + +namespace ros +{ +namespace message_operations +{ + +template +struct Printer< ::videostream::ip_getRequest_ > +{ + template static void stream(Stream& s, const std::string& indent, const ::videostream::ip_getRequest_& v) + { + s << indent << "str: "; + Printer, typename ContainerAllocator::template rebind::other > >::stream(s, indent + " ", v.str); + } +}; + +} // namespace message_operations +} // namespace ros + +#endif // VIDEOSTREAM_MESSAGE_IP_GETREQUEST_H diff --git a/Legacy/ws_linux/devel/include/videostream/ip_getResponse.h b/Legacy/ws_linux/devel/include/videostream/ip_getResponse.h new file mode 100644 index 0000000..24a5965 --- /dev/null +++ b/Legacy/ws_linux/devel/include/videostream/ip_getResponse.h @@ -0,0 +1,211 @@ +/* Software License Agreement (BSD License) + * + * Copyright (c) 2011, Willow Garage, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of Willow Garage, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * Auto-generated by genmsg_cpp from file /home/lab1_5/ws/ws_linux/src/videostream/srv/ip_get.srv + * + */ + + +#ifndef VIDEOSTREAM_MESSAGE_IP_GETRESPONSE_H +#define VIDEOSTREAM_MESSAGE_IP_GETRESPONSE_H + + +#include +#include +#include + +#include +#include +#include +#include + + +namespace videostream +{ +template +struct ip_getResponse_ +{ + typedef ip_getResponse_ Type; + + ip_getResponse_() + { + } + ip_getResponse_(const ContainerAllocator& _alloc) + { + } + + + + + + + typedef boost::shared_ptr< ::videostream::ip_getResponse_ > Ptr; + typedef boost::shared_ptr< ::videostream::ip_getResponse_ const> ConstPtr; + boost::shared_ptr > __connection_header; + +}; // struct ip_getResponse_ + +typedef ::videostream::ip_getResponse_ > ip_getResponse; + +typedef boost::shared_ptr< ::videostream::ip_getResponse > ip_getResponsePtr; +typedef boost::shared_ptr< ::videostream::ip_getResponse const> ip_getResponseConstPtr; + +// constants requiring out of line definition + + + +template +std::ostream& operator<<(std::ostream& s, const ::videostream::ip_getResponse_ & v) +{ +ros::message_operations::Printer< ::videostream::ip_getResponse_ >::stream(s, "", v); +return s; +} + +} // namespace videostream + +namespace ros +{ +namespace message_traits +{ + + + +// BOOLTRAITS {'IsFixedSize': True, 'IsMessage': True, 'HasHeader': False} +// {'std_msgs': ['/opt/ros/hydro/share/std_msgs/cmake/../msg']} + +// !!!!!!!!!!! ['__class__', '__delattr__', '__dict__', '__doc__', '__eq__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_parsed_fields', 'constants', 'fields', 'full_name', 'has_header', 'header_present', 'names', 'package', 'parsed_fields', 'short_name', 'text', 'types'] + + + + +template +struct IsFixedSize< ::videostream::ip_getResponse_ > + : TrueType + { }; + +template +struct IsFixedSize< ::videostream::ip_getResponse_ const> + : TrueType + { }; + +template +struct IsMessage< ::videostream::ip_getResponse_ > + : TrueType + { }; + +template +struct IsMessage< ::videostream::ip_getResponse_ const> + : TrueType + { }; + +template +struct HasHeader< ::videostream::ip_getResponse_ > + : FalseType + { }; + +template +struct HasHeader< ::videostream::ip_getResponse_ const> + : FalseType + { }; + + +template +struct MD5Sum< ::videostream::ip_getResponse_ > +{ + static const char* value() + { + return "d41d8cd98f00b204e9800998ecf8427e"; + } + + static const char* value(const ::videostream::ip_getResponse_&) { return value(); } + static const uint64_t static_value1 = 0xd41d8cd98f00b204ULL; + static const uint64_t static_value2 = 0xe9800998ecf8427eULL; +}; + +template +struct DataType< ::videostream::ip_getResponse_ > +{ + static const char* value() + { + return "videostream/ip_getResponse"; + } + + static const char* value(const ::videostream::ip_getResponse_&) { return value(); } +}; + +template +struct Definition< ::videostream::ip_getResponse_ > +{ + static const char* value() + { + return "\n\ +"; + } + + static const char* value(const ::videostream::ip_getResponse_&) { return value(); } +}; + +} // namespace message_traits +} // namespace ros + +namespace ros +{ +namespace serialization +{ + + template struct Serializer< ::videostream::ip_getResponse_ > + { + template inline static void allInOne(Stream&, T) + {} + + ROS_DECLARE_ALLINONE_SERIALIZER; + }; // struct ip_getResponse_ + +} // namespace serialization +} // namespace ros + +namespace ros +{ +namespace message_operations +{ + +template +struct Printer< ::videostream::ip_getResponse_ > +{ + template static void stream(Stream&, const std::string&, const ::videostream::ip_getResponse_&) + {} +}; + +} // namespace message_operations +} // namespace ros + +#endif // VIDEOSTREAM_MESSAGE_IP_GETRESPONSE_H diff --git a/Legacy/ws_linux/devel/lib/pkgconfig/rosaria.pc b/Legacy/ws_linux/devel/lib/pkgconfig/rosaria.pc new file mode 100644 index 0000000..61e1551 --- /dev/null +++ b/Legacy/ws_linux/devel/lib/pkgconfig/rosaria.pc @@ -0,0 +1,8 @@ +prefix=/home/lab1_5/ws/ws_linux/devel + +Name: rosaria +Description: Description of rosaria +Version: 0.9.0 +Cflags: -I/home/lab1_5/ws/ws_linux/devel/include +Libs: -L/home/lab1_5/ws/ws_linux/devel/lib +Requires: roscpp nav_msgs geometry_msgs sensor_msgs tf diff --git a/Legacy/ws_linux/devel/lib/pkgconfig/rosaria_msgs.pc b/Legacy/ws_linux/devel/lib/pkgconfig/rosaria_msgs.pc new file mode 100644 index 0000000..68a54f6 --- /dev/null +++ b/Legacy/ws_linux/devel/lib/pkgconfig/rosaria_msgs.pc @@ -0,0 +1,8 @@ +prefix=/home/lab1_5/ws/ws_linux/devel + +Name: rosaria_msgs +Description: Description of rosaria_msgs +Version: 0.0.0 +Cflags: -I/home/lab1_5/ws/ws_linux/devel/include +Libs: -L/home/lab1_5/ws/ws_linux/devel/lib +Requires: message_runtime diff --git a/Legacy/ws_linux/devel/lib/pkgconfig/safety.pc b/Legacy/ws_linux/devel/lib/pkgconfig/safety.pc new file mode 100644 index 0000000..f63ab1e --- /dev/null +++ b/Legacy/ws_linux/devel/lib/pkgconfig/safety.pc @@ -0,0 +1,8 @@ +prefix=/home/lab1_5/ws/ws_linux/devel + +Name: safety +Description: Description of safety +Version: 0.2.1 +Cflags: +Libs: -L/home/lab1_5/ws/ws_linux/devel/lib -lsafety +Requires: message_runtime roscpp rospy std_msgs rosaria diff --git a/Legacy/ws_linux/devel/lib/pkgconfig/videostream.pc b/Legacy/ws_linux/devel/lib/pkgconfig/videostream.pc new file mode 100644 index 0000000..4e957e2 --- /dev/null +++ b/Legacy/ws_linux/devel/lib/pkgconfig/videostream.pc @@ -0,0 +1,8 @@ +prefix=/home/lab1_5/ws/ws_linux/devel + +Name: videostream +Description: Description of videostream +Version: 0.0.0 +Cflags: -I/home/lab1_5/ws/ws_linux/devel/include -I/home/lab1_5/ws/ws_linux/src/videostream/include +Libs: -L/home/lab1_5/ws/ws_linux/devel/lib -lvideostream +Requires: message_runtime roscpp rospy std_msgs diff --git a/Legacy/ws_linux/devel/lib/python2.7/dist-packages/rosaria/__init__.py b/Legacy/ws_linux/devel/lib/python2.7/dist-packages/rosaria/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/Legacy/ws_linux/devel/lib/python2.7/dist-packages/rosaria/cfg/RosAriaConfig.py b/Legacy/ws_linux/devel/lib/python2.7/dist-packages/rosaria/cfg/RosAriaConfig.py new file mode 100644 index 0000000..206824b --- /dev/null +++ b/Legacy/ws_linux/devel/lib/python2.7/dist-packages/rosaria/cfg/RosAriaConfig.py @@ -0,0 +1,70 @@ +## ********************************************************* +## +## File autogenerated for the rosaria package +## by the dynamic_reconfigure package. +## Please do not edit. +## +## ********************************************************/ + +##********************************************************** +## Software License Agreement (BSD License) +## +## Copyright (c) 2008, Willow Garage, Inc. +## All rights reserved. +## +## Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions +## are met: +## +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above +## copyright notice, this list of conditions and the following +## disclaimer in the documentation and/or other materials provided +## with the distribution. +## * Neither the name of the Willow Garage nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +## FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +## COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +## INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +## BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +## LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +## LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +## ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +## POSSIBILITY OF SUCH DAMAGE. +##**********************************************************/ + +from dynamic_reconfigure.encoding import extract_params + +inf = float('inf') + +config_description = {'upper': 'DEFAULT', 'lower': 'groups', 'srcline': 233, 'name': 'Default', 'parent': 0, 'srcfile': '/opt/ros/hydro/lib/python2.7/dist-packages/dynamic_reconfigure/parameter_generator_catkin.py', 'cstate': 'true', 'parentname': 'Default', 'class': 'DEFAULT', 'field': 'default', 'state': True, 'parentclass': '', 'groups': [], 'parameters': [{'srcline': 262, 'description': 'Translational acceleration (m/s^2)', 'max': 'std::numeric_limits::infinity()', 'cconsttype': 'const double', 'ctype': 'double', 'srcfile': '/opt/ros/hydro/lib/python2.7/dist-packages/dynamic_reconfigure/parameter_generator_catkin.py', 'name': 'trans_accel', 'edit_method': '', 'default': 0, 'level': 0, 'min': '-std::numeric_limits::infinity()', 'type': 'double'}, {'srcline': 262, 'description': 'Translational deceleration (m/s^2)', 'max': 'std::numeric_limits::infinity()', 'cconsttype': 'const double', 'ctype': 'double', 'srcfile': '/opt/ros/hydro/lib/python2.7/dist-packages/dynamic_reconfigure/parameter_generator_catkin.py', 'name': 'trans_decel', 'edit_method': '', 'default': 0, 'level': 0, 'min': '-std::numeric_limits::infinity()', 'type': 'double'}, {'srcline': 262, 'description': 'Lateral acceleration (m/s^2)', 'max': 'std::numeric_limits::infinity()', 'cconsttype': 'const double', 'ctype': 'double', 'srcfile': '/opt/ros/hydro/lib/python2.7/dist-packages/dynamic_reconfigure/parameter_generator_catkin.py', 'name': 'lat_accel', 'edit_method': '', 'default': 0, 'level': 0, 'min': '-std::numeric_limits::infinity()', 'type': 'double'}, {'srcline': 262, 'description': 'Lateral deceleration (m/s^2)', 'max': 'std::numeric_limits::infinity()', 'cconsttype': 'const double', 'ctype': 'double', 'srcfile': '/opt/ros/hydro/lib/python2.7/dist-packages/dynamic_reconfigure/parameter_generator_catkin.py', 'name': 'lat_decel', 'edit_method': '', 'default': 0, 'level': 0, 'min': '-std::numeric_limits::infinity()', 'type': 'double'}, {'srcline': 262, 'description': 'Rotational acceleration (rad/s^2)', 'max': 'std::numeric_limits::infinity()', 'cconsttype': 'const double', 'ctype': 'double', 'srcfile': '/opt/ros/hydro/lib/python2.7/dist-packages/dynamic_reconfigure/parameter_generator_catkin.py', 'name': 'rot_accel', 'edit_method': '', 'default': 0, 'level': 0, 'min': '-std::numeric_limits::infinity()', 'type': 'double'}, {'srcline': 262, 'description': 'Rotational deceleration (rad/s^2)', 'max': 'std::numeric_limits::infinity()', 'cconsttype': 'const double', 'ctype': 'double', 'srcfile': '/opt/ros/hydro/lib/python2.7/dist-packages/dynamic_reconfigure/parameter_generator_catkin.py', 'name': 'rot_decel', 'edit_method': '', 'default': 0, 'level': 0, 'min': '-std::numeric_limits::infinity()', 'type': 'double'}, {'srcline': 262, 'description': 'Encoder ticks/mm', 'max': 2147483647, 'cconsttype': 'const int', 'ctype': 'int', 'srcfile': '/opt/ros/hydro/lib/python2.7/dist-packages/dynamic_reconfigure/parameter_generator_catkin.py', 'name': 'TicksMM', 'edit_method': '', 'default': 0, 'level': 0, 'min': -2147483648, 'type': 'int'}, {'srcline': 262, 'description': 'Value in 1/8192 increments to be added or subtracted from the left encoder ticks in order to compensate for tire differences.', 'max': 2147483647, 'cconsttype': 'const int', 'ctype': 'int', 'srcfile': '/opt/ros/hydro/lib/python2.7/dist-packages/dynamic_reconfigure/parameter_generator_catkin.py', 'name': 'DriftFactor', 'edit_method': '', 'default': 0, 'level': 0, 'min': -2147483648, 'type': 'int'}, {'srcline': 262, 'description': 'The number of differential encoder ticks for a 180-degree revolution of the robot.', 'max': 2147483647, 'cconsttype': 'const int', 'ctype': 'int', 'srcfile': '/opt/ros/hydro/lib/python2.7/dist-packages/dynamic_reconfigure/parameter_generator_catkin.py', 'name': 'RevCount', 'edit_method': '', 'default': 0, 'level': 0, 'min': -2147483648, 'type': 'int'}], 'type': '', 'id': 0} + +min = {} +max = {} +defaults = {} +level = {} +type = {} +all_level = 0 + +#def extract_params(config): +# params = [] +# params.extend(config['parameters']) +# for group in config['groups']: +# params.extend(extract_params(group)) +# return params + +for param in extract_params(config_description): + min[param['name']] = param['min'] + max[param['name']] = param['max'] + defaults[param['name']] = param['default'] + level[param['name']] = param['level'] + type[param['name']] = param['type'] + all_level = all_level | param['level'] + diff --git a/Legacy/ws_linux/devel/lib/python2.7/dist-packages/rosaria/cfg/__init__.py b/Legacy/ws_linux/devel/lib/python2.7/dist-packages/rosaria/cfg/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/Legacy/ws_linux/devel/lib/python2.7/dist-packages/rosaria/msg/_BumperState.py b/Legacy/ws_linux/devel/lib/python2.7/dist-packages/rosaria/msg/_BumperState.py new file mode 100644 index 0000000..1f92eb0 --- /dev/null +++ b/Legacy/ws_linux/devel/lib/python2.7/dist-packages/rosaria/msg/_BumperState.py @@ -0,0 +1,211 @@ +"""autogenerated by genpy from rosaria/BumperState.msg. Do not edit.""" +import sys +python3 = True if sys.hexversion > 0x03000000 else False +import genpy +import struct + +import std_msgs.msg + +class BumperState(genpy.Message): + _md5sum = "f81947761ff7e166a3bbaf937b9869b5" + _type = "rosaria/BumperState" + _has_header = True #flag to mark the presence of a Header object + _full_text = """Header header +bool[] front_bumpers +bool[] rear_bumpers + +================================================================================ +MSG: std_msgs/Header +# Standard metadata for higher-level stamped data types. +# This is generally used to communicate timestamped data +# in a particular coordinate frame. +# +# sequence ID: consecutively increasing ID +uint32 seq +#Two-integer timestamp that is expressed as: +# * stamp.secs: seconds (stamp_secs) since epoch +# * stamp.nsecs: nanoseconds since stamp_secs +# time-handling sugar is provided by the client library +time stamp +#Frame this data is associated with +# 0: no frame +# 1: global frame +string frame_id + +""" + __slots__ = ['header','front_bumpers','rear_bumpers'] + _slot_types = ['std_msgs/Header','bool[]','bool[]'] + + def __init__(self, *args, **kwds): + """ + Constructor. Any message fields that are implicitly/explicitly + set to None will be assigned a default value. The recommend + use is keyword arguments as this is more robust to future message + changes. You cannot mix in-order arguments and keyword arguments. + + The available fields are: + header,front_bumpers,rear_bumpers + + :param args: complete set of field values, in .msg order + :param kwds: use keyword arguments corresponding to message field names + to set specific fields. + """ + if args or kwds: + super(BumperState, self).__init__(*args, **kwds) + #message fields cannot be None, assign default values for those that are + if self.header is None: + self.header = std_msgs.msg.Header() + if self.front_bumpers is None: + self.front_bumpers = [] + if self.rear_bumpers is None: + self.rear_bumpers = [] + else: + self.header = std_msgs.msg.Header() + self.front_bumpers = [] + self.rear_bumpers = [] + + def _get_types(self): + """ + internal API method + """ + return self._slot_types + + def serialize(self, buff): + """ + serialize message into buffer + :param buff: buffer, ``StringIO`` + """ + try: + _x = self + buff.write(_struct_3I.pack(_x.header.seq, _x.header.stamp.secs, _x.header.stamp.nsecs)) + _x = self.header.frame_id + length = len(_x) + if python3 or type(_x) == unicode: + _x = _x.encode('utf-8') + length = len(_x) + buff.write(struct.pack('1X8Urt0S;CK<+? z>X#P-QG8BjUTKAXN@`hZj($#Nl72yDNk)F2k)FAJN@j71Zb4#lc4B&Jv3^m0abi(s nVtj6Kda-_dd}dx|NqoE>P&Eh8T$|kdl+v73JCN 0x03000000 else False +import genpy +import struct + +import std_msgs.msg + +class RestrictionsMsg(genpy.Message): + _md5sum = "c2466ab186049d2506624976271d3b3e" + _type = "rosaria_msgs/RestrictionsMsg" + _has_header = False #flag to mark the presence of a Header object + _full_text = """std_msgs/Float64 distance +std_msgs/Float64 linear_velocity +std_msgs/Float64 angular_velocity +================================================================================ +MSG: std_msgs/Float64 +float64 data +""" + __slots__ = ['distance','linear_velocity','angular_velocity'] + _slot_types = ['std_msgs/Float64','std_msgs/Float64','std_msgs/Float64'] + + def __init__(self, *args, **kwds): + """ + Constructor. Any message fields that are implicitly/explicitly + set to None will be assigned a default value. The recommend + use is keyword arguments as this is more robust to future message + changes. You cannot mix in-order arguments and keyword arguments. + + The available fields are: + distance,linear_velocity,angular_velocity + + :param args: complete set of field values, in .msg order + :param kwds: use keyword arguments corresponding to message field names + to set specific fields. + """ + if args or kwds: + super(RestrictionsMsg, self).__init__(*args, **kwds) + #message fields cannot be None, assign default values for those that are + if self.distance is None: + self.distance = std_msgs.msg.Float64() + if self.linear_velocity is None: + self.linear_velocity = std_msgs.msg.Float64() + if self.angular_velocity is None: + self.angular_velocity = std_msgs.msg.Float64() + else: + self.distance = std_msgs.msg.Float64() + self.linear_velocity = std_msgs.msg.Float64() + self.angular_velocity = std_msgs.msg.Float64() + + def _get_types(self): + """ + internal API method + """ + return self._slot_types + + def serialize(self, buff): + """ + serialize message into buffer + :param buff: buffer, ``StringIO`` + """ + try: + _x = self + buff.write(_struct_3d.pack(_x.distance.data, _x.linear_velocity.data, _x.angular_velocity.data)) + except struct.error as se: self._check_types(struct.error("%s: '%s' when writing '%s'" % (type(se), str(se), str(_x)))) + except TypeError as te: self._check_types(ValueError("%s: '%s' when writing '%s'" % (type(te), str(te), str(_x)))) + + def deserialize(self, str): + """ + unpack serialized message in str into this message instance + :param str: byte array of serialized message, ``str`` + """ + try: + if self.distance is None: + self.distance = std_msgs.msg.Float64() + if self.linear_velocity is None: + self.linear_velocity = std_msgs.msg.Float64() + if self.angular_velocity is None: + self.angular_velocity = std_msgs.msg.Float64() + end = 0 + _x = self + start = end + end += 24 + (_x.distance.data, _x.linear_velocity.data, _x.angular_velocity.data,) = _struct_3d.unpack(str[start:end]) + return self + except struct.error as e: + raise genpy.DeserializationError(e) #most likely buffer underfill + + + def serialize_numpy(self, buff, numpy): + """ + serialize message with numpy array types into buffer + :param buff: buffer, ``StringIO`` + :param numpy: numpy python module + """ + try: + _x = self + buff.write(_struct_3d.pack(_x.distance.data, _x.linear_velocity.data, _x.angular_velocity.data)) + except struct.error as se: self._check_types(struct.error("%s: '%s' when writing '%s'" % (type(se), str(se), str(_x)))) + except TypeError as te: self._check_types(ValueError("%s: '%s' when writing '%s'" % (type(te), str(te), str(_x)))) + + def deserialize_numpy(self, str, numpy): + """ + unpack serialized message in str into this message instance using numpy for array types + :param str: byte array of serialized message, ``str`` + :param numpy: numpy python module + """ + try: + if self.distance is None: + self.distance = std_msgs.msg.Float64() + if self.linear_velocity is None: + self.linear_velocity = std_msgs.msg.Float64() + if self.angular_velocity is None: + self.angular_velocity = std_msgs.msg.Float64() + end = 0 + _x = self + start = end + end += 24 + (_x.distance.data, _x.linear_velocity.data, _x.angular_velocity.data,) = _struct_3d.unpack(str[start:end]) + return self + except struct.error as e: + raise genpy.DeserializationError(e) #most likely buffer underfill + +_struct_I = genpy.struct_I +_struct_3d = struct.Struct("<3d") diff --git a/Legacy/ws_linux/devel/lib/python2.7/dist-packages/rosaria_msgs/msg/_RestrictionsMsg.pyc b/Legacy/ws_linux/devel/lib/python2.7/dist-packages/rosaria_msgs/msg/_RestrictionsMsg.pyc new file mode 100644 index 0000000000000000000000000000000000000000..dea68b17ac4c0715fdddf28ba1020d852b31aa8a GIT binary patch literal 5501 zcmc&&QF9wf5$=^_*^=cL0tpu`z#K=gsLDwfJ8=@%L2+E}s6ZumwN7!Ip=z_%j-<6$ zyJBZHwkTgwMSuq$;Dvv~(>-!kP{qICg(rB2uY0soY?0$CP(Il^>YeHBo$mSin;upF zvDWgU-=<(UcdI1EN+V7k6GHjjHY&QkNh3_9rSsC$`8 zGplqI+fMv1d>+QIS+(nE&pdD{9N**DTQnNsz`W5S1eo5;^NRRfW%uCKpek-73i8jl zD-4dE1nR(mKLE-FF4R@Y3 z-1E@M2~flJE-U;6&51{*MJE-?|3E;2_2>k!t#BS-2>rh!^3ZjF_4nv-h4TAkm*@aE zUuJk?C_tKsZ~!1Uoza5MN~r^kIGv9dbQ<)tk15?==&vsHtSt11+1+-9{aQuaRQSAw z1hIM1vsvCzZ>AG9(#C`Xt@^P}BBSguv?|QCibvxl1`Lu(S09(6m@wKZo2iFcs?|}P zBx+x)(3p6TB1c0N>3&!wRy_%mLU+`op;o!>WuuW!BYD0sux`|$o*ZR4p2!CU#;k!6 zydER?A7z+Ap6wS#-qkN`fsW~1#Y%68CDx{+)CXCidSS|`K8lZ3oW2ILI)B!18ZExA z(-b>Azwk*IC*giFivj|$Bcq5|3AO8IV0Qg1#GJjIahQiAe!1CEaC@9+s};vA>$@Pk z$e8PxsbZp1GF^Gy^x?y!2oH0d7K7Bw@?4v7mPTcf1x!5LETj3<5_@Awifa~Ta?Xn9vE>)s{LT`yHGdKW!m0cHZe z-ojGZkte4Vzu zxWPbAr?G`Q!^=sv9)Izwvxnj;6W-(wd;6i#8+-=gG1Y(Bq~*pnv!RZLI#ow`Y&i+J=VAK-#wDY;Te~%IR2ytX0)IyC zJg*{bX7jYM3{>39Ft#KIp>7+{c!Z9(MV}Y`N6fo&+vb%P z{K<3dpk)9A$MOYskR;dVj82~NY*p^^4Tp}Fs$SjO^e)mJZ=D3F91?axfckd`laHop z$@M7q-3@{V4y8}szDwnvit^Oy{BS{MsnkKW=5(?JojU6PdYlwUjVfmWV2KtGyNzB4 zaIOcW_Z6V?r_e&iAifO|mP(;60?6e3^cry9q=Qv~`riQcCGxP!2Wxb)#0dYTM=9gD z3g%%pHNQY3_$yL|4=8;K=V(U!*hYW^2W#0s%N-%cRxgzvZ~Rk~LlYpMU`q<~Je=^R zv}lsy55+0+xoD>NB{UA?0%4yS#9!ft*VAX@&C%?C9=8H%H*Nn5Jp4s&F7XJjs+97U z`|jy-3LzKp4!gYgf?c2AEO+!hfOOIcEwZKbJOzjGs@vz$5Q` zVDK6B3NV>^XTpMwQ`GxgIQbmvJ&Ns6rNszmI0rx3Ctr|}r-&AFJ5#H!RzUd}6^Z`z zyzTSpKtStXWQlpvVU|}->Y6!veJ&+@E-D0?{uP#ZcWBQs`!a3?rZPK0t$10u&(E55kq=;9Fl&{-kZ6TBE|B1r#8r;5w-P7<7%VcSZ!QxvEzg#G9+s*? zj6ZO{P0UZHC`$0tMR4CmbauzQyDLM&;h#bH1U+v!ynIKFj2xl5*YaM*)vB~AS4_kE EH&RI<5dZ)H literal 0 HcmV?d00001 diff --git a/Legacy/ws_linux/devel/lib/python2.7/dist-packages/rosaria_msgs/msg/_RobotInfoMsg.py b/Legacy/ws_linux/devel/lib/python2.7/dist-packages/rosaria_msgs/msg/_RobotInfoMsg.py new file mode 100644 index 0000000..c9fbf32 --- /dev/null +++ b/Legacy/ws_linux/devel/lib/python2.7/dist-packages/rosaria_msgs/msg/_RobotInfoMsg.py @@ -0,0 +1,176 @@ +"""autogenerated by genpy from rosaria_msgs/RobotInfoMsg.msg. Do not edit.""" +import sys +python3 = True if sys.hexversion > 0x03000000 else False +import genpy +import struct + +import geometry_msgs.msg +import std_msgs.msg + +class RobotInfoMsg(genpy.Message): + _md5sum = "fc20ec1228cc0538c3b1ee05e9614d34" + _type = "rosaria_msgs/RobotInfoMsg" + _has_header = False #flag to mark the presence of a Header object + _full_text = """std_msgs/UInt8 robot_id +std_msgs/Float64 battery_voltage +geometry_msgs/Twist twist +std_msgs/Bool state +std_msgs/Bool clutch +std_msgs/Bool obstacle_detected +================================================================================ +MSG: std_msgs/UInt8 +uint8 data + +================================================================================ +MSG: std_msgs/Float64 +float64 data +================================================================================ +MSG: geometry_msgs/Twist +# This expresses velocity in free space broken into its linear and angular parts. +Vector3 linear +Vector3 angular + +================================================================================ +MSG: geometry_msgs/Vector3 +# This represents a vector in free space. + +float64 x +float64 y +float64 z +================================================================================ +MSG: std_msgs/Bool +bool data +""" + __slots__ = ['robot_id','battery_voltage','twist','state','clutch','obstacle_detected'] + _slot_types = ['std_msgs/UInt8','std_msgs/Float64','geometry_msgs/Twist','std_msgs/Bool','std_msgs/Bool','std_msgs/Bool'] + + def __init__(self, *args, **kwds): + """ + Constructor. Any message fields that are implicitly/explicitly + set to None will be assigned a default value. The recommend + use is keyword arguments as this is more robust to future message + changes. You cannot mix in-order arguments and keyword arguments. + + The available fields are: + robot_id,battery_voltage,twist,state,clutch,obstacle_detected + + :param args: complete set of field values, in .msg order + :param kwds: use keyword arguments corresponding to message field names + to set specific fields. + """ + if args or kwds: + super(RobotInfoMsg, self).__init__(*args, **kwds) + #message fields cannot be None, assign default values for those that are + if self.robot_id is None: + self.robot_id = std_msgs.msg.UInt8() + if self.battery_voltage is None: + self.battery_voltage = std_msgs.msg.Float64() + if self.twist is None: + self.twist = geometry_msgs.msg.Twist() + if self.state is None: + self.state = std_msgs.msg.Bool() + if self.clutch is None: + self.clutch = std_msgs.msg.Bool() + if self.obstacle_detected is None: + self.obstacle_detected = std_msgs.msg.Bool() + else: + self.robot_id = std_msgs.msg.UInt8() + self.battery_voltage = std_msgs.msg.Float64() + self.twist = geometry_msgs.msg.Twist() + self.state = std_msgs.msg.Bool() + self.clutch = std_msgs.msg.Bool() + self.obstacle_detected = std_msgs.msg.Bool() + + def _get_types(self): + """ + internal API method + """ + return self._slot_types + + def serialize(self, buff): + """ + serialize message into buffer + :param buff: buffer, ``StringIO`` + """ + try: + _x = self + buff.write(_struct_B7d3B.pack(_x.robot_id.data, _x.battery_voltage.data, _x.twist.linear.x, _x.twist.linear.y, _x.twist.linear.z, _x.twist.angular.x, _x.twist.angular.y, _x.twist.angular.z, _x.state.data, _x.clutch.data, _x.obstacle_detected.data)) + except struct.error as se: self._check_types(struct.error("%s: '%s' when writing '%s'" % (type(se), str(se), str(_x)))) + except TypeError as te: self._check_types(ValueError("%s: '%s' when writing '%s'" % (type(te), str(te), str(_x)))) + + def deserialize(self, str): + """ + unpack serialized message in str into this message instance + :param str: byte array of serialized message, ``str`` + """ + try: + if self.robot_id is None: + self.robot_id = std_msgs.msg.UInt8() + if self.battery_voltage is None: + self.battery_voltage = std_msgs.msg.Float64() + if self.twist is None: + self.twist = geometry_msgs.msg.Twist() + if self.state is None: + self.state = std_msgs.msg.Bool() + if self.clutch is None: + self.clutch = std_msgs.msg.Bool() + if self.obstacle_detected is None: + self.obstacle_detected = std_msgs.msg.Bool() + end = 0 + _x = self + start = end + end += 60 + (_x.robot_id.data, _x.battery_voltage.data, _x.twist.linear.x, _x.twist.linear.y, _x.twist.linear.z, _x.twist.angular.x, _x.twist.angular.y, _x.twist.angular.z, _x.state.data, _x.clutch.data, _x.obstacle_detected.data,) = _struct_B7d3B.unpack(str[start:end]) + self.state.data = bool(self.state.data) + self.clutch.data = bool(self.clutch.data) + self.obstacle_detected.data = bool(self.obstacle_detected.data) + return self + except struct.error as e: + raise genpy.DeserializationError(e) #most likely buffer underfill + + + def serialize_numpy(self, buff, numpy): + """ + serialize message with numpy array types into buffer + :param buff: buffer, ``StringIO`` + :param numpy: numpy python module + """ + try: + _x = self + buff.write(_struct_B7d3B.pack(_x.robot_id.data, _x.battery_voltage.data, _x.twist.linear.x, _x.twist.linear.y, _x.twist.linear.z, _x.twist.angular.x, _x.twist.angular.y, _x.twist.angular.z, _x.state.data, _x.clutch.data, _x.obstacle_detected.data)) + except struct.error as se: self._check_types(struct.error("%s: '%s' when writing '%s'" % (type(se), str(se), str(_x)))) + except TypeError as te: self._check_types(ValueError("%s: '%s' when writing '%s'" % (type(te), str(te), str(_x)))) + + def deserialize_numpy(self, str, numpy): + """ + unpack serialized message in str into this message instance using numpy for array types + :param str: byte array of serialized message, ``str`` + :param numpy: numpy python module + """ + try: + if self.robot_id is None: + self.robot_id = std_msgs.msg.UInt8() + if self.battery_voltage is None: + self.battery_voltage = std_msgs.msg.Float64() + if self.twist is None: + self.twist = geometry_msgs.msg.Twist() + if self.state is None: + self.state = std_msgs.msg.Bool() + if self.clutch is None: + self.clutch = std_msgs.msg.Bool() + if self.obstacle_detected is None: + self.obstacle_detected = std_msgs.msg.Bool() + end = 0 + _x = self + start = end + end += 60 + (_x.robot_id.data, _x.battery_voltage.data, _x.twist.linear.x, _x.twist.linear.y, _x.twist.linear.z, _x.twist.angular.x, _x.twist.angular.y, _x.twist.angular.z, _x.state.data, _x.clutch.data, _x.obstacle_detected.data,) = _struct_B7d3B.unpack(str[start:end]) + self.state.data = bool(self.state.data) + self.clutch.data = bool(self.clutch.data) + self.obstacle_detected.data = bool(self.obstacle_detected.data) + return self + except struct.error as e: + raise genpy.DeserializationError(e) #most likely buffer underfill + +_struct_I = genpy.struct_I +_struct_B7d3B = struct.Struct("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 0x03000000 else False +import genpy +import struct + + +class ip_getRequest(genpy.Message): + _md5sum = "994972b6e03928b2476860ce6c4c8e17" + _type = "videostream/ip_getRequest" + _has_header = False #flag to mark the presence of a Header object + _full_text = """string str + +""" + __slots__ = ['str'] + _slot_types = ['string'] + + def __init__(self, *args, **kwds): + """ + Constructor. Any message fields that are implicitly/explicitly + set to None will be assigned a default value. The recommend + use is keyword arguments as this is more robust to future message + changes. You cannot mix in-order arguments and keyword arguments. + + The available fields are: + str + + :param args: complete set of field values, in .msg order + :param kwds: use keyword arguments corresponding to message field names + to set specific fields. + """ + if args or kwds: + super(ip_getRequest, self).__init__(*args, **kwds) + #message fields cannot be None, assign default values for those that are + if self.str is None: + self.str = '' + else: + self.str = '' + + def _get_types(self): + """ + internal API method + """ + return self._slot_types + + def serialize(self, buff): + """ + serialize message into buffer + :param buff: buffer, ``StringIO`` + """ + try: + _x = self.str + length = len(_x) + if python3 or type(_x) == unicode: + _x = _x.encode('utf-8') + length = len(_x) + buff.write(struct.pack(' 0x03000000 else False +import genpy +import struct + + +class ip_getResponse(genpy.Message): + _md5sum = "d41d8cd98f00b204e9800998ecf8427e" + _type = "videostream/ip_getResponse" + _has_header = False #flag to mark the presence of a Header object + _full_text = """ + +""" + __slots__ = [] + _slot_types = [] + + def __init__(self, *args, **kwds): + """ + Constructor. Any message fields that are implicitly/explicitly + set to None will be assigned a default value. The recommend + use is keyword arguments as this is more robust to future message + changes. You cannot mix in-order arguments and keyword arguments. + + The available fields are: + + + :param args: complete set of field values, in .msg order + :param kwds: use keyword arguments corresponding to message field names + to set specific fields. + """ + if args or kwds: + super(ip_getResponse, self).__init__(*args, **kwds) + + def _get_types(self): + """ + internal API method + """ + return self._slot_types + + def serialize(self, buff): + """ + serialize message into buffer + :param buff: buffer, ``StringIO`` + """ + try: + pass + except struct.error as se: self._check_types(struct.error("%s: '%s' when writing '%s'" % (type(se), str(se), str(_x)))) + except TypeError as te: self._check_types(ValueError("%s: '%s' when writing '%s'" % (type(te), str(te), str(_x)))) + + def deserialize(self, str): + """ + unpack serialized message in str into this message instance + :param str: byte array of serialized message, ``str`` + """ + try: + end = 0 + return self + except struct.error as e: + raise genpy.DeserializationError(e) #most likely buffer underfill + + + def serialize_numpy(self, buff, numpy): + """ + serialize message with numpy array types into buffer + :param buff: buffer, ``StringIO`` + :param numpy: numpy python module + """ + try: + pass + except struct.error as se: self._check_types(struct.error("%s: '%s' when writing '%s'" % (type(se), str(se), str(_x)))) + except TypeError as te: self._check_types(ValueError("%s: '%s' when writing '%s'" % (type(te), str(te), str(_x)))) + + def deserialize_numpy(self, str, numpy): + """ + unpack serialized message in str into this message instance using numpy for array types + :param str: byte array of serialized message, ``str`` + :param numpy: numpy python module + """ + try: + end = 0 + return self + except struct.error as e: + raise genpy.DeserializationError(e) #most likely buffer underfill + +_struct_I = genpy.struct_I +class ip_get(object): + _type = 'videostream/ip_get' + _md5sum = '994972b6e03928b2476860ce6c4c8e17' + _request_class = ip_getRequest + _response_class = ip_getResponse diff --git a/Legacy/ws_linux/devel/lib/rosaria/RosAria b/Legacy/ws_linux/devel/lib/rosaria/RosAria new file mode 100755 index 0000000000000000000000000000000000000000..38aa4bd9ef57f5877a7fbed437352a2628ff4a3f GIT binary patch literal 1830828 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

    O1!W8ma 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

    _4)cJTd8S#fTUPm7~m8=>`Jk2U; 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 Wz=C}-EJ<~K0qZH^R{sm8CjLL;8H#fN literal 0 HcmV?d00001 diff --git a/Legacy/ws_linux/devel/lib/safety/cloud_reader b/Legacy/ws_linux/devel/lib/safety/cloud_reader new file mode 100755 index 0000000000000000000000000000000000000000..352c53b5acccf84a8bf164abdf7db2bdde137592 GIT binary patch literal 421469 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%0A?)e)gg5#cU*)nC1r0Vq6B4L3C

    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

    9`L~E5(Y%FVWc6J&VvS&81 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 HK)L@9*G*t@ literal 0 HcmV?d00001 diff --git a/Legacy/ws_linux/devel/lib/videostream/videostream b/Legacy/ws_linux/devel/lib/videostream/videostream new file mode 100755 index 0000000000000000000000000000000000000000..cc2afdf29bc7b3dc71c00a952fb9764e18ca36e5 GIT binary patch literal 286160 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 literal 0 HcmV?d00001 diff --git a/Legacy/ws_linux/devel/setup.bash b/Legacy/ws_linux/devel/setup.bash new file mode 100644 index 0000000..ff47af8 --- /dev/null +++ b/Legacy/ws_linux/devel/setup.bash @@ -0,0 +1,8 @@ +#!/usr/bin/env bash +# generated from catkin/cmake/templates/setup.bash.in + +CATKIN_SHELL=bash + +# source setup.sh from same directory as this file +_CATKIN_SETUP_DIR=$(builtin cd "`dirname "${BASH_SOURCE[0]}"`" > /dev/null && pwd) +. "$_CATKIN_SETUP_DIR/setup.sh" diff --git a/Legacy/ws_linux/devel/setup.sh b/Legacy/ws_linux/devel/setup.sh new file mode 100644 index 0000000..01ce9a7 --- /dev/null +++ b/Legacy/ws_linux/devel/setup.sh @@ -0,0 +1,87 @@ +#!/usr/bin/env sh +# generated from catkin/cmake/template/setup.sh.in + +# Sets various environment variables and sources additional environment hooks. +# It tries it's best to undo changes from a previously sourced setup file before. +# Supported command line options: +# --extend: skips the undoing of changes from a previously sourced setup file + +# since this file is sourced either use the provided _CATKIN_SETUP_DIR +# or fall back to the destination set at configure time +: ${_CATKIN_SETUP_DIR:=/home/lab1_5/ws/ws_linux/devel} +_SETUP_UTIL="$_CATKIN_SETUP_DIR/_setup_util.py" +unset _CATKIN_SETUP_DIR + +if [ ! -f "$_SETUP_UTIL" ]; then + echo "Missing Python script: $_SETUP_UTIL" + return 22 +fi + +# detect if running on Darwin platform +_UNAME=`uname -s` +_IS_DARWIN=0 +if [ "$_UNAME" = "Darwin" ]; then + _IS_DARWIN=1 +fi +unset _UNAME + +# make sure to export all environment variables +export CMAKE_PREFIX_PATH +export CPATH +if [ $_IS_DARWIN -eq 0 ]; then + export LD_LIBRARY_PATH +else + export DYLD_LIBRARY_PATH +fi +unset _IS_DARWIN +export PATH +export PKG_CONFIG_PATH +export PYTHONPATH + +# remember type of shell if not already set +if [ -z "$CATKIN_SHELL" ]; then + CATKIN_SHELL=sh +fi + +# invoke Python script to generate necessary exports of environment variables +_SETUP_TMP=`mktemp /tmp/setup.sh.XXXXXXXXXX` +if [ $? -ne 0 -o ! -f "$_SETUP_TMP" ]; then + echo "Could not create temporary file: $_SETUP_TMP" + return 1 +fi +CATKIN_SHELL=$CATKIN_SHELL "$_SETUP_UTIL" $@ > $_SETUP_TMP +_RC=$? +if [ $_RC -ne 0 ]; then + if [ $_RC -eq 2 ]; then + echo "Could not write the output of '$_SETUP_UTIL' to temporary file '$_SETUP_TMP': may be the disk if full?" + else + echo "Failed to run '\"$_SETUP_UTIL\" $@': return code $_RC" + fi + unset _RC + unset _SETUP_UTIL + rm -f $_SETUP_TMP + unset _SETUP_TMP + return 1 +fi +unset _RC +unset _SETUP_UTIL +. $_SETUP_TMP +rm -f $_SETUP_TMP +unset _SETUP_TMP + +# source all environment hooks +_i=0 +while [ $_i -lt $_CATKIN_ENVIRONMENT_HOOKS_COUNT ]; do + eval _envfile=\$_CATKIN_ENVIRONMENT_HOOKS_$_i + unset _CATKIN_ENVIRONMENT_HOOKS_$_i + eval _envfile_workspace=\$_CATKIN_ENVIRONMENT_HOOKS_${_i}_WORKSPACE + unset _CATKIN_ENVIRONMENT_HOOKS_${_i}_WORKSPACE + # set workspace for environment hook + CATKIN_ENV_HOOK_WORKSPACE=$_envfile_workspace + . "$_envfile" + unset CATKIN_ENV_HOOK_WORKSPACE + _i=$((_i + 1)) +done +unset _i + +unset _CATKIN_ENVIRONMENT_HOOKS_COUNT diff --git a/Legacy/ws_linux/devel/setup.zsh b/Legacy/ws_linux/devel/setup.zsh new file mode 100644 index 0000000..b660717 --- /dev/null +++ b/Legacy/ws_linux/devel/setup.zsh @@ -0,0 +1,8 @@ +#!/usr/bin/env zsh +# generated from catkin/cmake/templates/setup.zsh.in + +CATKIN_SHELL=zsh +_CATKIN_SETUP_DIR=$(builtin cd -q "`dirname "$0"`" > /dev/null && pwd) +emulate sh # emulate POSIX +. "$_CATKIN_SETUP_DIR/setup.sh" +emulate zsh # back to zsh mode diff --git a/Legacy/ws_linux/devel/share/common-lisp/ros/rosaria/msg/BumperState.lisp b/Legacy/ws_linux/devel/share/common-lisp/ros/rosaria/msg/BumperState.lisp new file mode 100644 index 0000000..bd604e1 --- /dev/null +++ b/Legacy/ws_linux/devel/share/common-lisp/ros/rosaria/msg/BumperState.lisp @@ -0,0 +1,120 @@ +; Auto-generated. Do not edit! + + +(cl:in-package rosaria-msg) + + +;//! \htmlinclude BumperState.msg.html + +(cl:defclass (roslisp-msg-protocol:ros-message) + ((header + :reader header + :initarg :header + :type std_msgs-msg:Header + :initform (cl:make-instance 'std_msgs-msg:Header)) + (front_bumpers + :reader front_bumpers + :initarg :front_bumpers + :type (cl:vector cl:boolean) + :initform (cl:make-array 0 :element-type 'cl:boolean :initial-element cl:nil)) + (rear_bumpers + :reader rear_bumpers + :initarg :rear_bumpers + :type (cl:vector cl:boolean) + :initform (cl:make-array 0 :element-type 'cl:boolean :initial-element cl:nil))) +) + +(cl:defclass BumperState () + ()) + +(cl:defmethod cl:initialize-instance :after ((m ) cl:&rest args) + (cl:declare (cl:ignorable args)) + (cl:unless (cl:typep m 'BumperState) + (roslisp-msg-protocol:msg-deprecation-warning "using old message class name rosaria-msg: is deprecated: use rosaria-msg:BumperState instead."))) + +(cl:ensure-generic-function 'header-val :lambda-list '(m)) +(cl:defmethod header-val ((m )) + (roslisp-msg-protocol:msg-deprecation-warning "Using old-style slot reader rosaria-msg:header-val is deprecated. Use rosaria-msg:header instead.") + (header m)) + +(cl:ensure-generic-function 'front_bumpers-val :lambda-list '(m)) +(cl:defmethod front_bumpers-val ((m )) + (roslisp-msg-protocol:msg-deprecation-warning "Using old-style slot reader rosaria-msg:front_bumpers-val is deprecated. Use rosaria-msg:front_bumpers instead.") + (front_bumpers m)) + +(cl:ensure-generic-function 'rear_bumpers-val :lambda-list '(m)) +(cl:defmethod rear_bumpers-val ((m )) + (roslisp-msg-protocol:msg-deprecation-warning "Using old-style slot reader rosaria-msg:rear_bumpers-val is deprecated. Use rosaria-msg:rear_bumpers instead.") + (rear_bumpers m)) +(cl:defmethod roslisp-msg-protocol:serialize ((msg ) ostream) + "Serializes a message object of type '" + (roslisp-msg-protocol:serialize (cl:slot-value msg 'header) ostream) + (cl:let ((__ros_arr_len (cl:length (cl:slot-value msg 'front_bumpers)))) + (cl:write-byte (cl:ldb (cl:byte 8 0) __ros_arr_len) ostream) + (cl:write-byte (cl:ldb (cl:byte 8 8) __ros_arr_len) ostream) + (cl:write-byte (cl:ldb (cl:byte 8 16) __ros_arr_len) ostream) + (cl:write-byte (cl:ldb (cl:byte 8 24) __ros_arr_len) ostream)) + (cl:map cl:nil #'(cl:lambda (ele) (cl:write-byte (cl:ldb (cl:byte 8 0) (cl:if ele 1 0)) ostream)) + (cl:slot-value msg 'front_bumpers)) + (cl:let ((__ros_arr_len (cl:length (cl:slot-value msg 'rear_bumpers)))) + (cl:write-byte (cl:ldb (cl:byte 8 0) __ros_arr_len) ostream) + (cl:write-byte (cl:ldb (cl:byte 8 8) __ros_arr_len) ostream) + (cl:write-byte (cl:ldb (cl:byte 8 16) __ros_arr_len) ostream) + (cl:write-byte (cl:ldb (cl:byte 8 24) __ros_arr_len) ostream)) + (cl:map cl:nil #'(cl:lambda (ele) (cl:write-byte (cl:ldb (cl:byte 8 0) (cl:if ele 1 0)) ostream)) + (cl:slot-value msg 'rear_bumpers)) +) +(cl:defmethod roslisp-msg-protocol:deserialize ((msg ) istream) + "Deserializes a message object of type '" + (roslisp-msg-protocol:deserialize (cl:slot-value msg 'header) istream) + (cl:let ((__ros_arr_len 0)) + (cl:setf (cl:ldb (cl:byte 8 0) __ros_arr_len) (cl:read-byte istream)) + (cl:setf (cl:ldb (cl:byte 8 8) __ros_arr_len) (cl:read-byte istream)) + (cl:setf (cl:ldb (cl:byte 8 16) __ros_arr_len) (cl:read-byte istream)) + (cl:setf (cl:ldb (cl:byte 8 24) __ros_arr_len) (cl:read-byte istream)) + (cl:setf (cl:slot-value msg 'front_bumpers) (cl:make-array __ros_arr_len)) + (cl:let ((vals (cl:slot-value msg 'front_bumpers))) + (cl:dotimes (i __ros_arr_len) + (cl:setf (cl:aref vals i) (cl:not (cl:zerop (cl:read-byte istream))))))) + (cl:let ((__ros_arr_len 0)) + (cl:setf (cl:ldb (cl:byte 8 0) __ros_arr_len) (cl:read-byte istream)) + (cl:setf (cl:ldb (cl:byte 8 8) __ros_arr_len) (cl:read-byte istream)) + (cl:setf (cl:ldb (cl:byte 8 16) __ros_arr_len) (cl:read-byte istream)) + (cl:setf (cl:ldb (cl:byte 8 24) __ros_arr_len) (cl:read-byte istream)) + (cl:setf (cl:slot-value msg 'rear_bumpers) (cl:make-array __ros_arr_len)) + (cl:let ((vals (cl:slot-value msg 'rear_bumpers))) + (cl:dotimes (i __ros_arr_len) + (cl:setf (cl:aref vals i) (cl:not (cl:zerop (cl:read-byte istream))))))) + msg +) +(cl:defmethod roslisp-msg-protocol:ros-datatype ((msg (cl:eql '))) + "Returns string type for a message object of type '" + "rosaria/BumperState") +(cl:defmethod roslisp-msg-protocol:ros-datatype ((msg (cl:eql 'BumperState))) + "Returns string type for a message object of type 'BumperState" + "rosaria/BumperState") +(cl:defmethod roslisp-msg-protocol:md5sum ((type (cl:eql '))) + "Returns md5sum for a message object of type '" + "f81947761ff7e166a3bbaf937b9869b5") +(cl:defmethod roslisp-msg-protocol:md5sum ((type (cl:eql 'BumperState))) + "Returns md5sum for a message object of type 'BumperState" + "f81947761ff7e166a3bbaf937b9869b5") +(cl:defmethod roslisp-msg-protocol:message-definition ((type (cl:eql '))) + "Returns full string definition for message of type '" + (cl:format cl:nil "Header header~%bool[] front_bumpers~%bool[] rear_bumpers~%~%================================================================================~%MSG: std_msgs/Header~%# Standard metadata for higher-level stamped data types.~%# This is generally used to communicate timestamped data ~%# in a particular coordinate frame.~%# ~%# sequence ID: consecutively increasing ID ~%uint32 seq~%#Two-integer timestamp that is expressed as:~%# * stamp.secs: seconds (stamp_secs) since epoch~%# * stamp.nsecs: nanoseconds since stamp_secs~%# time-handling sugar is provided by the client library~%time stamp~%#Frame this data is associated with~%# 0: no frame~%# 1: global frame~%string frame_id~%~%~%")) +(cl:defmethod roslisp-msg-protocol:message-definition ((type (cl:eql 'BumperState))) + "Returns full string definition for message of type 'BumperState" + (cl:format cl:nil "Header header~%bool[] front_bumpers~%bool[] rear_bumpers~%~%================================================================================~%MSG: std_msgs/Header~%# Standard metadata for higher-level stamped data types.~%# This is generally used to communicate timestamped data ~%# in a particular coordinate frame.~%# ~%# sequence ID: consecutively increasing ID ~%uint32 seq~%#Two-integer timestamp that is expressed as:~%# * stamp.secs: seconds (stamp_secs) since epoch~%# * stamp.nsecs: nanoseconds since stamp_secs~%# time-handling sugar is provided by the client library~%time stamp~%#Frame this data is associated with~%# 0: no frame~%# 1: global frame~%string frame_id~%~%~%")) +(cl:defmethod roslisp-msg-protocol:serialization-length ((msg )) + (cl:+ 0 + (roslisp-msg-protocol:serialization-length (cl:slot-value msg 'header)) + 4 (cl:reduce #'cl:+ (cl:slot-value msg 'front_bumpers) :key #'(cl:lambda (ele) (cl:declare (cl:ignorable ele)) (cl:+ 1))) + 4 (cl:reduce #'cl:+ (cl:slot-value msg 'rear_bumpers) :key #'(cl:lambda (ele) (cl:declare (cl:ignorable ele)) (cl:+ 1))) +)) +(cl:defmethod roslisp-msg-protocol:ros-message-to-list ((msg )) + "Converts a ROS message object to a list" + (cl:list 'BumperState + (cl:cons ':header (header msg)) + (cl:cons ':front_bumpers (front_bumpers msg)) + (cl:cons ':rear_bumpers (rear_bumpers msg)) +)) diff --git a/Legacy/ws_linux/devel/share/common-lisp/ros/rosaria/msg/_package.lisp b/Legacy/ws_linux/devel/share/common-lisp/ros/rosaria/msg/_package.lisp new file mode 100644 index 0000000..4c84b8a --- /dev/null +++ b/Legacy/ws_linux/devel/share/common-lisp/ros/rosaria/msg/_package.lisp @@ -0,0 +1,7 @@ +(cl:defpackage rosaria-msg + (:use ) + (:export + "" + "BUMPERSTATE" + )) + diff --git a/Legacy/ws_linux/devel/share/common-lisp/ros/rosaria/msg/_package_BumperState.lisp b/Legacy/ws_linux/devel/share/common-lisp/ros/rosaria/msg/_package_BumperState.lisp new file mode 100644 index 0000000..cd55fee --- /dev/null +++ b/Legacy/ws_linux/devel/share/common-lisp/ros/rosaria/msg/_package_BumperState.lisp @@ -0,0 +1,8 @@ +(cl:in-package rosaria-msg) +(cl:export '(HEADER-VAL + HEADER + FRONT_BUMPERS-VAL + FRONT_BUMPERS + REAR_BUMPERS-VAL + REAR_BUMPERS +)) \ No newline at end of file diff --git a/Legacy/ws_linux/devel/share/common-lisp/ros/rosaria/msg/rosaria-msg.asd b/Legacy/ws_linux/devel/share/common-lisp/ros/rosaria/msg/rosaria-msg.asd new file mode 100644 index 0000000..c0aaa54 --- /dev/null +++ b/Legacy/ws_linux/devel/share/common-lisp/ros/rosaria/msg/rosaria-msg.asd @@ -0,0 +1,10 @@ + +(cl:in-package :asdf) + +(defsystem "rosaria-msg" + :depends-on (:roslisp-msg-protocol :roslisp-utils :std_msgs-msg +) + :components ((:file "_package") + (:file "BumperState" :depends-on ("_package_BumperState")) + (:file "_package_BumperState" :depends-on ("_package")) + )) \ No newline at end of file diff --git a/Legacy/ws_linux/devel/share/common-lisp/ros/rosaria_msgs/msg/RestrictionsMsg.lisp b/Legacy/ws_linux/devel/share/common-lisp/ros/rosaria_msgs/msg/RestrictionsMsg.lisp new file mode 100644 index 0000000..63c2c13 --- /dev/null +++ b/Legacy/ws_linux/devel/share/common-lisp/ros/rosaria_msgs/msg/RestrictionsMsg.lisp @@ -0,0 +1,92 @@ +; Auto-generated. Do not edit! + + +(cl:in-package rosaria_msgs-msg) + + +;//! \htmlinclude RestrictionsMsg.msg.html + +(cl:defclass (roslisp-msg-protocol:ros-message) + ((distance + :reader distance + :initarg :distance + :type std_msgs-msg:Float64 + :initform (cl:make-instance 'std_msgs-msg:Float64)) + (linear_velocity + :reader linear_velocity + :initarg :linear_velocity + :type std_msgs-msg:Float64 + :initform (cl:make-instance 'std_msgs-msg:Float64)) + (angular_velocity + :reader angular_velocity + :initarg :angular_velocity + :type std_msgs-msg:Float64 + :initform (cl:make-instance 'std_msgs-msg:Float64))) +) + +(cl:defclass RestrictionsMsg () + ()) + +(cl:defmethod cl:initialize-instance :after ((m ) cl:&rest args) + (cl:declare (cl:ignorable args)) + (cl:unless (cl:typep m 'RestrictionsMsg) + (roslisp-msg-protocol:msg-deprecation-warning "using old message class name rosaria_msgs-msg: is deprecated: use rosaria_msgs-msg:RestrictionsMsg instead."))) + +(cl:ensure-generic-function 'distance-val :lambda-list '(m)) +(cl:defmethod distance-val ((m )) + (roslisp-msg-protocol:msg-deprecation-warning "Using old-style slot reader rosaria_msgs-msg:distance-val is deprecated. Use rosaria_msgs-msg:distance instead.") + (distance m)) + +(cl:ensure-generic-function 'linear_velocity-val :lambda-list '(m)) +(cl:defmethod linear_velocity-val ((m )) + (roslisp-msg-protocol:msg-deprecation-warning "Using old-style slot reader rosaria_msgs-msg:linear_velocity-val is deprecated. Use rosaria_msgs-msg:linear_velocity instead.") + (linear_velocity m)) + +(cl:ensure-generic-function 'angular_velocity-val :lambda-list '(m)) +(cl:defmethod angular_velocity-val ((m )) + (roslisp-msg-protocol:msg-deprecation-warning "Using old-style slot reader rosaria_msgs-msg:angular_velocity-val is deprecated. Use rosaria_msgs-msg:angular_velocity instead.") + (angular_velocity m)) +(cl:defmethod roslisp-msg-protocol:serialize ((msg ) ostream) + "Serializes a message object of type '" + (roslisp-msg-protocol:serialize (cl:slot-value msg 'distance) ostream) + (roslisp-msg-protocol:serialize (cl:slot-value msg 'linear_velocity) ostream) + (roslisp-msg-protocol:serialize (cl:slot-value msg 'angular_velocity) ostream) +) +(cl:defmethod roslisp-msg-protocol:deserialize ((msg ) istream) + "Deserializes a message object of type '" + (roslisp-msg-protocol:deserialize (cl:slot-value msg 'distance) istream) + (roslisp-msg-protocol:deserialize (cl:slot-value msg 'linear_velocity) istream) + (roslisp-msg-protocol:deserialize (cl:slot-value msg 'angular_velocity) istream) + msg +) +(cl:defmethod roslisp-msg-protocol:ros-datatype ((msg (cl:eql '))) + "Returns string type for a message object of type '" + "rosaria_msgs/RestrictionsMsg") +(cl:defmethod roslisp-msg-protocol:ros-datatype ((msg (cl:eql 'RestrictionsMsg))) + "Returns string type for a message object of type 'RestrictionsMsg" + "rosaria_msgs/RestrictionsMsg") +(cl:defmethod roslisp-msg-protocol:md5sum ((type (cl:eql '))) + "Returns md5sum for a message object of type '" + "c2466ab186049d2506624976271d3b3e") +(cl:defmethod roslisp-msg-protocol:md5sum ((type (cl:eql 'RestrictionsMsg))) + "Returns md5sum for a message object of type 'RestrictionsMsg" + "c2466ab186049d2506624976271d3b3e") +(cl:defmethod roslisp-msg-protocol:message-definition ((type (cl:eql '))) + "Returns full string definition for message of type '" + (cl:format cl:nil "std_msgs/Float64 distance~%std_msgs/Float64 linear_velocity~%std_msgs/Float64 angular_velocity~%================================================================================~%MSG: std_msgs/Float64~%float64 data~%~%")) +(cl:defmethod roslisp-msg-protocol:message-definition ((type (cl:eql 'RestrictionsMsg))) + "Returns full string definition for message of type 'RestrictionsMsg" + (cl:format cl:nil "std_msgs/Float64 distance~%std_msgs/Float64 linear_velocity~%std_msgs/Float64 angular_velocity~%================================================================================~%MSG: std_msgs/Float64~%float64 data~%~%")) +(cl:defmethod roslisp-msg-protocol:serialization-length ((msg )) + (cl:+ 0 + (roslisp-msg-protocol:serialization-length (cl:slot-value msg 'distance)) + (roslisp-msg-protocol:serialization-length (cl:slot-value msg 'linear_velocity)) + (roslisp-msg-protocol:serialization-length (cl:slot-value msg 'angular_velocity)) +)) +(cl:defmethod roslisp-msg-protocol:ros-message-to-list ((msg )) + "Converts a ROS message object to a list" + (cl:list 'RestrictionsMsg + (cl:cons ':distance (distance msg)) + (cl:cons ':linear_velocity (linear_velocity msg)) + (cl:cons ':angular_velocity (angular_velocity msg)) +)) diff --git a/Legacy/ws_linux/devel/share/common-lisp/ros/rosaria_msgs/msg/RobotInfoMsg.lisp b/Legacy/ws_linux/devel/share/common-lisp/ros/rosaria_msgs/msg/RobotInfoMsg.lisp new file mode 100644 index 0000000..f28c5ed --- /dev/null +++ b/Legacy/ws_linux/devel/share/common-lisp/ros/rosaria_msgs/msg/RobotInfoMsg.lisp @@ -0,0 +1,134 @@ +; Auto-generated. Do not edit! + + +(cl:in-package rosaria_msgs-msg) + + +;//! \htmlinclude RobotInfoMsg.msg.html + +(cl:defclass (roslisp-msg-protocol:ros-message) + ((robot_id + :reader robot_id + :initarg :robot_id + :type std_msgs-msg:UInt8 + :initform (cl:make-instance 'std_msgs-msg:UInt8)) + (battery_voltage + :reader battery_voltage + :initarg :battery_voltage + :type std_msgs-msg:Float64 + :initform (cl:make-instance 'std_msgs-msg:Float64)) + (twist + :reader twist + :initarg :twist + :type geometry_msgs-msg:Twist + :initform (cl:make-instance 'geometry_msgs-msg:Twist)) + (state + :reader state + :initarg :state + :type std_msgs-msg:Bool + :initform (cl:make-instance 'std_msgs-msg:Bool)) + (clutch + :reader clutch + :initarg :clutch + :type std_msgs-msg:Bool + :initform (cl:make-instance 'std_msgs-msg:Bool)) + (obstacle_detected + :reader obstacle_detected + :initarg :obstacle_detected + :type std_msgs-msg:Bool + :initform (cl:make-instance 'std_msgs-msg:Bool))) +) + +(cl:defclass RobotInfoMsg () + ()) + +(cl:defmethod cl:initialize-instance :after ((m ) cl:&rest args) + (cl:declare (cl:ignorable args)) + (cl:unless (cl:typep m 'RobotInfoMsg) + (roslisp-msg-protocol:msg-deprecation-warning "using old message class name rosaria_msgs-msg: is deprecated: use rosaria_msgs-msg:RobotInfoMsg instead."))) + +(cl:ensure-generic-function 'robot_id-val :lambda-list '(m)) +(cl:defmethod robot_id-val ((m )) + (roslisp-msg-protocol:msg-deprecation-warning "Using old-style slot reader rosaria_msgs-msg:robot_id-val is deprecated. Use rosaria_msgs-msg:robot_id instead.") + (robot_id m)) + +(cl:ensure-generic-function 'battery_voltage-val :lambda-list '(m)) +(cl:defmethod battery_voltage-val ((m )) + (roslisp-msg-protocol:msg-deprecation-warning "Using old-style slot reader rosaria_msgs-msg:battery_voltage-val is deprecated. Use rosaria_msgs-msg:battery_voltage instead.") + (battery_voltage m)) + +(cl:ensure-generic-function 'twist-val :lambda-list '(m)) +(cl:defmethod twist-val ((m )) + (roslisp-msg-protocol:msg-deprecation-warning "Using old-style slot reader rosaria_msgs-msg:twist-val is deprecated. Use rosaria_msgs-msg:twist instead.") + (twist m)) + +(cl:ensure-generic-function 'state-val :lambda-list '(m)) +(cl:defmethod state-val ((m )) + (roslisp-msg-protocol:msg-deprecation-warning "Using old-style slot reader rosaria_msgs-msg:state-val is deprecated. Use rosaria_msgs-msg:state instead.") + (state m)) + +(cl:ensure-generic-function 'clutch-val :lambda-list '(m)) +(cl:defmethod clutch-val ((m )) + (roslisp-msg-protocol:msg-deprecation-warning "Using old-style slot reader rosaria_msgs-msg:clutch-val is deprecated. Use rosaria_msgs-msg:clutch instead.") + (clutch m)) + +(cl:ensure-generic-function 'obstacle_detected-val :lambda-list '(m)) +(cl:defmethod obstacle_detected-val ((m )) + (roslisp-msg-protocol:msg-deprecation-warning "Using old-style slot reader rosaria_msgs-msg:obstacle_detected-val is deprecated. Use rosaria_msgs-msg:obstacle_detected instead.") + (obstacle_detected m)) +(cl:defmethod roslisp-msg-protocol:serialize ((msg ) ostream) + "Serializes a message object of type '" + (roslisp-msg-protocol:serialize (cl:slot-value msg 'robot_id) ostream) + (roslisp-msg-protocol:serialize (cl:slot-value msg 'battery_voltage) ostream) + (roslisp-msg-protocol:serialize (cl:slot-value msg 'twist) ostream) + (roslisp-msg-protocol:serialize (cl:slot-value msg 'state) ostream) + (roslisp-msg-protocol:serialize (cl:slot-value msg 'clutch) ostream) + (roslisp-msg-protocol:serialize (cl:slot-value msg 'obstacle_detected) ostream) +) +(cl:defmethod roslisp-msg-protocol:deserialize ((msg ) istream) + "Deserializes a message object of type '" + (roslisp-msg-protocol:deserialize (cl:slot-value msg 'robot_id) istream) + (roslisp-msg-protocol:deserialize (cl:slot-value msg 'battery_voltage) istream) + (roslisp-msg-protocol:deserialize (cl:slot-value msg 'twist) istream) + (roslisp-msg-protocol:deserialize (cl:slot-value msg 'state) istream) + (roslisp-msg-protocol:deserialize (cl:slot-value msg 'clutch) istream) + (roslisp-msg-protocol:deserialize (cl:slot-value msg 'obstacle_detected) istream) + msg +) +(cl:defmethod roslisp-msg-protocol:ros-datatype ((msg (cl:eql '))) + "Returns string type for a message object of type '" + "rosaria_msgs/RobotInfoMsg") +(cl:defmethod roslisp-msg-protocol:ros-datatype ((msg (cl:eql 'RobotInfoMsg))) + "Returns string type for a message object of type 'RobotInfoMsg" + "rosaria_msgs/RobotInfoMsg") +(cl:defmethod roslisp-msg-protocol:md5sum ((type (cl:eql '))) + "Returns md5sum for a message object of type '" + "fc20ec1228cc0538c3b1ee05e9614d34") +(cl:defmethod roslisp-msg-protocol:md5sum ((type (cl:eql 'RobotInfoMsg))) + "Returns md5sum for a message object of type 'RobotInfoMsg" + "fc20ec1228cc0538c3b1ee05e9614d34") +(cl:defmethod roslisp-msg-protocol:message-definition ((type (cl:eql '))) + "Returns full string definition for message of type '" + (cl:format cl:nil "std_msgs/UInt8 robot_id~%std_msgs/Float64 battery_voltage~%geometry_msgs/Twist twist~%std_msgs/Bool state~%std_msgs/Bool clutch~%std_msgs/Bool obstacle_detected~%================================================================================~%MSG: std_msgs/UInt8~%uint8 data~%~%================================================================================~%MSG: std_msgs/Float64~%float64 data~%================================================================================~%MSG: geometry_msgs/Twist~%# This expresses velocity in free space broken into its linear and angular parts.~%Vector3 linear~%Vector3 angular~%~%================================================================================~%MSG: geometry_msgs/Vector3~%# This represents a vector in free space. ~%~%float64 x~%float64 y~%float64 z~%================================================================================~%MSG: std_msgs/Bool~%bool data~%~%")) +(cl:defmethod roslisp-msg-protocol:message-definition ((type (cl:eql 'RobotInfoMsg))) + "Returns full string definition for message of type 'RobotInfoMsg" + (cl:format cl:nil "std_msgs/UInt8 robot_id~%std_msgs/Float64 battery_voltage~%geometry_msgs/Twist twist~%std_msgs/Bool state~%std_msgs/Bool clutch~%std_msgs/Bool obstacle_detected~%================================================================================~%MSG: std_msgs/UInt8~%uint8 data~%~%================================================================================~%MSG: std_msgs/Float64~%float64 data~%================================================================================~%MSG: geometry_msgs/Twist~%# This expresses velocity in free space broken into its linear and angular parts.~%Vector3 linear~%Vector3 angular~%~%================================================================================~%MSG: geometry_msgs/Vector3~%# This represents a vector in free space. ~%~%float64 x~%float64 y~%float64 z~%================================================================================~%MSG: std_msgs/Bool~%bool data~%~%")) +(cl:defmethod roslisp-msg-protocol:serialization-length ((msg )) + (cl:+ 0 + (roslisp-msg-protocol:serialization-length (cl:slot-value msg 'robot_id)) + (roslisp-msg-protocol:serialization-length (cl:slot-value msg 'battery_voltage)) + (roslisp-msg-protocol:serialization-length (cl:slot-value msg 'twist)) + (roslisp-msg-protocol:serialization-length (cl:slot-value msg 'state)) + (roslisp-msg-protocol:serialization-length (cl:slot-value msg 'clutch)) + (roslisp-msg-protocol:serialization-length (cl:slot-value msg 'obstacle_detected)) +)) +(cl:defmethod roslisp-msg-protocol:ros-message-to-list ((msg )) + "Converts a ROS message object to a list" + (cl:list 'RobotInfoMsg + (cl:cons ':robot_id (robot_id msg)) + (cl:cons ':battery_voltage (battery_voltage msg)) + (cl:cons ':twist (twist msg)) + (cl:cons ':state (state msg)) + (cl:cons ':clutch (clutch msg)) + (cl:cons ':obstacle_detected (obstacle_detected msg)) +)) diff --git a/Legacy/ws_linux/devel/share/common-lisp/ros/rosaria_msgs/msg/_package.lisp b/Legacy/ws_linux/devel/share/common-lisp/ros/rosaria_msgs/msg/_package.lisp new file mode 100644 index 0000000..6cc1e9b --- /dev/null +++ b/Legacy/ws_linux/devel/share/common-lisp/ros/rosaria_msgs/msg/_package.lisp @@ -0,0 +1,9 @@ +(cl:defpackage rosaria_msgs-msg + (:use ) + (:export + "" + "ROBOTINFOMSG" + "" + "RESTRICTIONSMSG" + )) + diff --git a/Legacy/ws_linux/devel/share/common-lisp/ros/rosaria_msgs/msg/_package_RestrictionsMsg.lisp b/Legacy/ws_linux/devel/share/common-lisp/ros/rosaria_msgs/msg/_package_RestrictionsMsg.lisp new file mode 100644 index 0000000..c3ffa66 --- /dev/null +++ b/Legacy/ws_linux/devel/share/common-lisp/ros/rosaria_msgs/msg/_package_RestrictionsMsg.lisp @@ -0,0 +1,8 @@ +(cl:in-package rosaria_msgs-msg) +(cl:export '(DISTANCE-VAL + DISTANCE + LINEAR_VELOCITY-VAL + LINEAR_VELOCITY + ANGULAR_VELOCITY-VAL + ANGULAR_VELOCITY +)) \ No newline at end of file diff --git a/Legacy/ws_linux/devel/share/common-lisp/ros/rosaria_msgs/msg/_package_RobotInfoMsg.lisp b/Legacy/ws_linux/devel/share/common-lisp/ros/rosaria_msgs/msg/_package_RobotInfoMsg.lisp new file mode 100644 index 0000000..a9b974d --- /dev/null +++ b/Legacy/ws_linux/devel/share/common-lisp/ros/rosaria_msgs/msg/_package_RobotInfoMsg.lisp @@ -0,0 +1,14 @@ +(cl:in-package rosaria_msgs-msg) +(cl:export '(ROBOT_ID-VAL + ROBOT_ID + BATTERY_VOLTAGE-VAL + BATTERY_VOLTAGE + TWIST-VAL + TWIST + STATE-VAL + STATE + CLUTCH-VAL + CLUTCH + OBSTACLE_DETECTED-VAL + OBSTACLE_DETECTED +)) \ No newline at end of file diff --git a/Legacy/ws_linux/devel/share/common-lisp/ros/rosaria_msgs/msg/rosaria_msgs-msg.asd b/Legacy/ws_linux/devel/share/common-lisp/ros/rosaria_msgs/msg/rosaria_msgs-msg.asd new file mode 100644 index 0000000..ec417cf --- /dev/null +++ b/Legacy/ws_linux/devel/share/common-lisp/ros/rosaria_msgs/msg/rosaria_msgs-msg.asd @@ -0,0 +1,13 @@ + +(cl:in-package :asdf) + +(defsystem "rosaria_msgs-msg" + :depends-on (:roslisp-msg-protocol :roslisp-utils :geometry_msgs-msg + :std_msgs-msg +) + :components ((:file "_package") + (:file "RobotInfoMsg" :depends-on ("_package_RobotInfoMsg")) + (:file "_package_RobotInfoMsg" :depends-on ("_package")) + (:file "RestrictionsMsg" :depends-on ("_package_RestrictionsMsg")) + (:file "_package_RestrictionsMsg" :depends-on ("_package")) + )) \ No newline at end of file diff --git a/Legacy/ws_linux/devel/share/common-lisp/ros/videostream/srv/_package.lisp b/Legacy/ws_linux/devel/share/common-lisp/ros/videostream/srv/_package.lisp new file mode 100644 index 0000000..8a3f688 --- /dev/null +++ b/Legacy/ws_linux/devel/share/common-lisp/ros/videostream/srv/_package.lisp @@ -0,0 +1,10 @@ +(cl:defpackage videostream-srv + (:use ) + (:export + "IP_GET" + "" + "IP_GET-REQUEST" + "" + "IP_GET-RESPONSE" + )) + diff --git a/Legacy/ws_linux/devel/share/common-lisp/ros/videostream/srv/_package_ip_get.lisp b/Legacy/ws_linux/devel/share/common-lisp/ros/videostream/srv/_package_ip_get.lisp new file mode 100644 index 0000000..a5183d2 --- /dev/null +++ b/Legacy/ws_linux/devel/share/common-lisp/ros/videostream/srv/_package_ip_get.lisp @@ -0,0 +1,4 @@ +(cl:in-package videostream-srv) +(cl:export '(STR-VAL + STR +)) \ No newline at end of file diff --git a/Legacy/ws_linux/devel/share/common-lisp/ros/videostream/srv/ip_get.lisp b/Legacy/ws_linux/devel/share/common-lisp/ros/videostream/srv/ip_get.lisp new file mode 100644 index 0000000..43d99a0 --- /dev/null +++ b/Legacy/ws_linux/devel/share/common-lisp/ros/videostream/srv/ip_get.lisp @@ -0,0 +1,128 @@ +; Auto-generated. Do not edit! + + +(cl:in-package videostream-srv) + + +;//! \htmlinclude ip_get-request.msg.html + +(cl:defclass (roslisp-msg-protocol:ros-message) + ((str + :reader str + :initarg :str + :type cl:string + :initform "")) +) + +(cl:defclass ip_get-request () + ()) + +(cl:defmethod cl:initialize-instance :after ((m ) cl:&rest args) + (cl:declare (cl:ignorable args)) + (cl:unless (cl:typep m 'ip_get-request) + (roslisp-msg-protocol:msg-deprecation-warning "using old message class name videostream-srv: is deprecated: use videostream-srv:ip_get-request instead."))) + +(cl:ensure-generic-function 'str-val :lambda-list '(m)) +(cl:defmethod str-val ((m )) + (roslisp-msg-protocol:msg-deprecation-warning "Using old-style slot reader videostream-srv:str-val is deprecated. Use videostream-srv:str instead.") + (str m)) +(cl:defmethod roslisp-msg-protocol:serialize ((msg ) ostream) + "Serializes a message object of type '" + (cl:let ((__ros_str_len (cl:length (cl:slot-value msg 'str)))) + (cl:write-byte (cl:ldb (cl:byte 8 0) __ros_str_len) ostream) + (cl:write-byte (cl:ldb (cl:byte 8 8) __ros_str_len) ostream) + (cl:write-byte (cl:ldb (cl:byte 8 16) __ros_str_len) ostream) + (cl:write-byte (cl:ldb (cl:byte 8 24) __ros_str_len) ostream)) + (cl:map cl:nil #'(cl:lambda (c) (cl:write-byte (cl:char-code c) ostream)) (cl:slot-value msg 'str)) +) +(cl:defmethod roslisp-msg-protocol:deserialize ((msg ) istream) + "Deserializes a message object of type '" + (cl:let ((__ros_str_len 0)) + (cl:setf (cl:ldb (cl:byte 8 0) __ros_str_len) (cl:read-byte istream)) + (cl:setf (cl:ldb (cl:byte 8 8) __ros_str_len) (cl:read-byte istream)) + (cl:setf (cl:ldb (cl:byte 8 16) __ros_str_len) (cl:read-byte istream)) + (cl:setf (cl:ldb (cl:byte 8 24) __ros_str_len) (cl:read-byte istream)) + (cl:setf (cl:slot-value msg 'str) (cl:make-string __ros_str_len)) + (cl:dotimes (__ros_str_idx __ros_str_len msg) + (cl:setf (cl:char (cl:slot-value msg 'str) __ros_str_idx) (cl:code-char (cl:read-byte istream))))) + msg +) +(cl:defmethod roslisp-msg-protocol:ros-datatype ((msg (cl:eql '))) + "Returns string type for a service object of type '" + "videostream/ip_getRequest") +(cl:defmethod roslisp-msg-protocol:ros-datatype ((msg (cl:eql 'ip_get-request))) + "Returns string type for a service object of type 'ip_get-request" + "videostream/ip_getRequest") +(cl:defmethod roslisp-msg-protocol:md5sum ((type (cl:eql '))) + "Returns md5sum for a message object of type '" + "994972b6e03928b2476860ce6c4c8e17") +(cl:defmethod roslisp-msg-protocol:md5sum ((type (cl:eql 'ip_get-request))) + "Returns md5sum for a message object of type 'ip_get-request" + "994972b6e03928b2476860ce6c4c8e17") +(cl:defmethod roslisp-msg-protocol:message-definition ((type (cl:eql '))) + "Returns full string definition for message of type '" + (cl:format cl:nil "string str~%~%~%")) +(cl:defmethod roslisp-msg-protocol:message-definition ((type (cl:eql 'ip_get-request))) + "Returns full string definition for message of type 'ip_get-request" + (cl:format cl:nil "string str~%~%~%")) +(cl:defmethod roslisp-msg-protocol:serialization-length ((msg )) + (cl:+ 0 + 4 (cl:length (cl:slot-value msg 'str)) +)) +(cl:defmethod roslisp-msg-protocol:ros-message-to-list ((msg )) + "Converts a ROS message object to a list" + (cl:list 'ip_get-request + (cl:cons ':str (str msg)) +)) +;//! \htmlinclude ip_get-response.msg.html + +(cl:defclass (roslisp-msg-protocol:ros-message) + () +) + +(cl:defclass ip_get-response () + ()) + +(cl:defmethod cl:initialize-instance :after ((m ) cl:&rest args) + (cl:declare (cl:ignorable args)) + (cl:unless (cl:typep m 'ip_get-response) + (roslisp-msg-protocol:msg-deprecation-warning "using old message class name videostream-srv: is deprecated: use videostream-srv:ip_get-response instead."))) +(cl:defmethod roslisp-msg-protocol:serialize ((msg ) ostream) + "Serializes a message object of type '" +) +(cl:defmethod roslisp-msg-protocol:deserialize ((msg ) istream) + "Deserializes a message object of type '" + msg +) +(cl:defmethod roslisp-msg-protocol:ros-datatype ((msg (cl:eql '))) + "Returns string type for a service object of type '" + "videostream/ip_getResponse") +(cl:defmethod roslisp-msg-protocol:ros-datatype ((msg (cl:eql 'ip_get-response))) + "Returns string type for a service object of type 'ip_get-response" + "videostream/ip_getResponse") +(cl:defmethod roslisp-msg-protocol:md5sum ((type (cl:eql '))) + "Returns md5sum for a message object of type '" + "994972b6e03928b2476860ce6c4c8e17") +(cl:defmethod roslisp-msg-protocol:md5sum ((type (cl:eql 'ip_get-response))) + "Returns md5sum for a message object of type 'ip_get-response" + "994972b6e03928b2476860ce6c4c8e17") +(cl:defmethod roslisp-msg-protocol:message-definition ((type (cl:eql '))) + "Returns full string definition for message of type '" + (cl:format cl:nil "~%~%~%")) +(cl:defmethod roslisp-msg-protocol:message-definition ((type (cl:eql 'ip_get-response))) + "Returns full string definition for message of type 'ip_get-response" + (cl:format cl:nil "~%~%~%")) +(cl:defmethod roslisp-msg-protocol:serialization-length ((msg )) + (cl:+ 0 +)) +(cl:defmethod roslisp-msg-protocol:ros-message-to-list ((msg )) + "Converts a ROS message object to a list" + (cl:list 'ip_get-response +)) +(cl:defmethod roslisp-msg-protocol:service-request-type ((msg (cl:eql 'ip_get))) + 'ip_get-request) +(cl:defmethod roslisp-msg-protocol:service-response-type ((msg (cl:eql 'ip_get))) + 'ip_get-response) +(cl:defmethod roslisp-msg-protocol:ros-datatype ((msg (cl:eql 'ip_get))) + "Returns string type for a service object of type '" + "videostream/ip_get") \ No newline at end of file diff --git a/Legacy/ws_linux/devel/share/common-lisp/ros/videostream/srv/videostream-srv.asd b/Legacy/ws_linux/devel/share/common-lisp/ros/videostream/srv/videostream-srv.asd new file mode 100644 index 0000000..2040f31 --- /dev/null +++ b/Legacy/ws_linux/devel/share/common-lisp/ros/videostream/srv/videostream-srv.asd @@ -0,0 +1,9 @@ + +(cl:in-package :asdf) + +(defsystem "videostream-srv" + :depends-on (:roslisp-msg-protocol :roslisp-utils ) + :components ((:file "_package") + (:file "ip_get" :depends-on ("_package_ip_get")) + (:file "_package_ip_get" :depends-on ("_package")) + )) \ No newline at end of file diff --git a/Legacy/ws_linux/devel/share/rosaria/cmake/rosaria-msg-extras.cmake b/Legacy/ws_linux/devel/share/rosaria/cmake/rosaria-msg-extras.cmake new file mode 100644 index 0000000..01b9d0d --- /dev/null +++ b/Legacy/ws_linux/devel/share/rosaria/cmake/rosaria-msg-extras.cmake @@ -0,0 +1,2 @@ +set(rosaria_MESSAGE_FILES "/home/lab1_5/ws/ws_linux/src/rosaria/msg/BumperState.msg") +set(rosaria_SERVICE_FILES "") diff --git a/Legacy/ws_linux/devel/share/rosaria/cmake/rosaria-msg-paths.cmake b/Legacy/ws_linux/devel/share/rosaria/cmake/rosaria-msg-paths.cmake new file mode 100644 index 0000000..8a4a316 --- /dev/null +++ b/Legacy/ws_linux/devel/share/rosaria/cmake/rosaria-msg-paths.cmake @@ -0,0 +1,5 @@ +# generated from genmsg/cmake/pkg-msg-paths.cmake.em + +# message include dirs in develspace +set(rosaria_MSG_INCLUDE_DIRS "/home/lab1_5/ws/ws_linux/src/rosaria/msg") +set(rosaria_MSG_DEPENDENCIES geometry_msgs;std_msgs) diff --git a/Legacy/ws_linux/devel/share/rosaria/cmake/rosariaConfig-version.cmake b/Legacy/ws_linux/devel/share/rosaria/cmake/rosariaConfig-version.cmake new file mode 100644 index 0000000..0df8aa0 --- /dev/null +++ b/Legacy/ws_linux/devel/share/rosaria/cmake/rosariaConfig-version.cmake @@ -0,0 +1,14 @@ +# generated from catkin/cmake/template/pkgConfig-version.cmake.in +set(PACKAGE_VERSION "0.9.0") + +set(PACKAGE_VERSION_EXACT False) +set(PACKAGE_VERSION_COMPATIBLE False) + +if("${PACKAGE_FIND_VERSION}" VERSION_EQUAL "${PACKAGE_VERSION}") + set(PACKAGE_VERSION_EXACT True) + set(PACKAGE_VERSION_COMPATIBLE True) +endif() + +if("${PACKAGE_FIND_VERSION}" VERSION_LESS "${PACKAGE_VERSION}") + set(PACKAGE_VERSION_COMPATIBLE True) +endif() diff --git a/Legacy/ws_linux/devel/share/rosaria/cmake/rosariaConfig.cmake b/Legacy/ws_linux/devel/share/rosaria/cmake/rosariaConfig.cmake new file mode 100644 index 0000000..087a45c --- /dev/null +++ b/Legacy/ws_linux/devel/share/rosaria/cmake/rosariaConfig.cmake @@ -0,0 +1,191 @@ +# generated from catkin/cmake/template/pkgConfig.cmake.in + +# append elements to a list and remove existing duplicates from the list +# copied from catkin/cmake/list_append_deduplicate.cmake to keep pkgConfig +# self contained +macro(_list_append_deduplicate listname) + if(NOT "${ARGN}" STREQUAL "") + if(${listname}) + list(REMOVE_ITEM ${listname} ${ARGN}) + endif() + list(APPEND ${listname} ${ARGN}) + endif() +endmacro() + +# append elements to a list if they are not already in the list +# copied from catkin/cmake/list_append_unique.cmake to keep pkgConfig +# self contained +macro(_list_append_unique listname) + foreach(_item ${ARGN}) + list(FIND ${listname} ${_item} _index) + if(_index EQUAL -1) + list(APPEND ${listname} ${_item}) + endif() + endforeach() +endmacro() + +# pack a list of libraries with optional build configuration keywords +# copied from catkin/cmake/catkin_libraries.cmake to keep pkgConfig +# self contained +macro(_pack_libraries_with_build_configuration VAR) + set(${VAR} "") + set(_argn ${ARGN}) + list(LENGTH _argn _count) + set(_index 0) + while(${_index} LESS ${_count}) + list(GET _argn ${_index} lib) + if("${lib}" MATCHES "^debug|optimized|general$") + math(EXPR _index "${_index} + 1") + if(${_index} EQUAL ${_count}) + message(FATAL_ERROR "_pack_libraries_with_build_configuration() the list of libraries '${ARGN}' ends with '${lib}' which is a build configuration keyword and must be followed by a library") + endif() + list(GET _argn ${_index} library) + list(APPEND ${VAR} "${lib}${CATKIN_BUILD_CONFIGURATION_KEYWORD_SEPARATOR}${library}") + else() + list(APPEND ${VAR} "${lib}") + endif() + math(EXPR _index "${_index} + 1") + endwhile() +endmacro() + +# unpack a list of libraries with optional build configuration keyword prefixes +# copied from catkin/cmake/catkin_libraries.cmake to keep pkgConfig +# self contained +macro(_unpack_libraries_with_build_configuration VAR) + set(${VAR} "") + foreach(lib ${ARGN}) + string(REGEX REPLACE "^(debug|optimized|general)${CATKIN_BUILD_CONFIGURATION_KEYWORD_SEPARATOR}(.+)$" "\\1;\\2" lib "${lib}") + list(APPEND ${VAR} "${lib}") + endforeach() +endmacro() + + +if(rosaria_CONFIG_INCLUDED) + return() +endif() +set(rosaria_CONFIG_INCLUDED TRUE) + +# set variables for source/devel/install prefixes +if("TRUE" STREQUAL "TRUE") + set(rosaria_SOURCE_PREFIX /home/lab1_5/ws/ws_linux/src/rosaria) + set(rosaria_DEVEL_PREFIX /home/lab1_5/ws/ws_linux/devel) + set(rosaria_INSTALL_PREFIX "") + set(rosaria_PREFIX ${rosaria_DEVEL_PREFIX}) +else() + set(rosaria_SOURCE_PREFIX "") + set(rosaria_DEVEL_PREFIX "") + set(rosaria_INSTALL_PREFIX /home/lab1_5/ws/ws_linux/install) + set(rosaria_PREFIX ${rosaria_INSTALL_PREFIX}) +endif() + +# warn when using a deprecated package +if(NOT "" STREQUAL "") + set(_msg "WARNING: package 'rosaria' is deprecated") + # append custom deprecation text if available + if(NOT "" STREQUAL "TRUE") + set(_msg "${_msg} ()") + endif() + message("${_msg}") +endif() + +# flag project as catkin-based to distinguish if a find_package()-ed project is a catkin project +set(rosaria_FOUND_CATKIN_PROJECT TRUE) + +if(NOT "/home/lab1_5/ws/ws_linux/devel/include" STREQUAL "") + set(rosaria_INCLUDE_DIRS "") + set(_include_dirs "/home/lab1_5/ws/ws_linux/devel/include") + foreach(idir ${_include_dirs}) + if(IS_ABSOLUTE ${idir} AND IS_DIRECTORY ${idir}) + set(include ${idir}) + elseif("${idir}" STREQUAL "include") + get_filename_component(include "${rosaria_DIR}/../../../include" ABSOLUTE) + if(NOT IS_DIRECTORY ${include}) + message(FATAL_ERROR "Project 'rosaria' specifies '${idir}' as an include dir, which is not found. It does not exist in '${include}'. Ask the maintainer 'Srećko Jurić-Kavelj , Ivan Marković , Reed Hedges ' to fix it.") + endif() + else() + message(FATAL_ERROR "Project 'rosaria' specifies '${idir}' as an include dir, which is not found. It does neither exist as an absolute directory nor in '/home/lab1_5/ws/ws_linux/src/rosaria/${idir}'. Ask the maintainer 'Srećko Jurić-Kavelj , Ivan Marković , Reed Hedges ' to fix it.") + endif() + _list_append_unique(rosaria_INCLUDE_DIRS ${include}) + endforeach() +endif() + +set(libraries "") +foreach(library ${libraries}) + # keep build configuration keywords, target names and absolute libraries as-is + if("${library}" MATCHES "^debug|optimized|general$") + list(APPEND rosaria_LIBRARIES ${library}) + elseif(TARGET ${library}) + list(APPEND rosaria_LIBRARIES ${library}) + elseif(IS_ABSOLUTE ${library}) + list(APPEND rosaria_LIBRARIES ${library}) + else() + set(lib_path "") + set(lib "${library}-NOTFOUND") + # since the path where the library is found is returned we have to iterate over the paths manually + foreach(path /home/lab1_5/ws/ws_linux/devel/lib;/home/lab1_5/ws/ws_linux/devel/lib;/home/lab1_5/ws/ws_xeno/devel/lib;/home/lab1_5/ws/ws_isolated/install_isolated/lib;/opt/ros/hydro/lib) + find_library(lib ${library} + PATHS ${path} + NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH) + if(lib) + set(lib_path ${path}) + break() + endif() + endforeach() + if(lib) + _list_append_unique(rosaria_LIBRARY_DIRS ${lib_path}) + list(APPEND rosaria_LIBRARIES ${lib}) + else() + # as a fall back for non-catkin libraries try to search globally + find_library(lib ${library}) + if(NOT lib) + message(FATAL_ERROR "Project '${PROJECT_NAME}' tried to find library '${library}'. The library is neither a target nor built/installed properly. Did you compile project 'rosaria'? Did you find_package() it before the subdirectory containing its code is included?") + endif() + list(APPEND rosaria_LIBRARIES ${lib}) + endif() + endif() +endforeach() + +set(rosaria_EXPORTED_TARGETS "rosaria_gencfg;rosaria_generate_messages_cpp;rosaria_generate_messages_lisp;rosaria_generate_messages_py") +# create dummy targets for exported code generation targets to make life of users easier +foreach(t ${rosaria_EXPORTED_TARGETS}) + if(NOT TARGET ${t}) + add_custom_target(${t}) + endif() +endforeach() + +set(depends "roscpp;nav_msgs;geometry_msgs;sensor_msgs;tf") +foreach(depend ${depends}) + string(REPLACE " " ";" depend_list ${depend}) + # the package name of the dependency must be kept in a unique variable so that it is not overwritten in recursive calls + list(GET depend_list 0 rosaria_dep) + list(LENGTH depend_list count) + if(${count} EQUAL 1) + # simple dependencies must only be find_package()-ed once + if(NOT ${rosaria_dep}_FOUND) + find_package(${rosaria_dep} REQUIRED) + endif() + else() + # dependencies with components must be find_package()-ed again + list(REMOVE_AT depend_list 0) + find_package(${rosaria_dep} REQUIRED ${depend_list}) + endif() + _list_append_unique(rosaria_INCLUDE_DIRS ${${rosaria_dep}_INCLUDE_DIRS}) + + # merge build configuration keywords with library names to correctly deduplicate + _pack_libraries_with_build_configuration(rosaria_LIBRARIES ${rosaria_LIBRARIES}) + _pack_libraries_with_build_configuration(_libraries ${${rosaria_dep}_LIBRARIES}) + _list_append_deduplicate(rosaria_LIBRARIES ${_libraries}) + # undo build configuration keyword merging after deduplication + _unpack_libraries_with_build_configuration(rosaria_LIBRARIES ${rosaria_LIBRARIES}) + + _list_append_unique(rosaria_LIBRARY_DIRS ${${rosaria_dep}_LIBRARY_DIRS}) + list(APPEND rosaria_EXPORTED_TARGETS ${${rosaria_dep}_EXPORTED_TARGETS}) +endforeach() + +set(pkg_cfg_extras "rosaria-msg-extras.cmake") +foreach(extra ${pkg_cfg_extras}) + if(NOT IS_ABSOLUTE ${extra}) + set(extra ${rosaria_DIR}/${extra}) + endif() + include(${extra}) +endforeach() diff --git a/Legacy/ws_linux/devel/share/rosaria/docs/RosAriaConfig-usage.dox b/Legacy/ws_linux/devel/share/rosaria/docs/RosAriaConfig-usage.dox new file mode 100644 index 0000000..6a5810a --- /dev/null +++ b/Legacy/ws_linux/devel/share/rosaria/docs/RosAriaConfig-usage.dox @@ -0,0 +1,15 @@ +\subsubsection usage Usage +\verbatim + + + + + + + + + + + +\endverbatim + diff --git a/Legacy/ws_linux/devel/share/rosaria/docs/RosAriaConfig.dox b/Legacy/ws_linux/devel/share/rosaria/docs/RosAriaConfig.dox new file mode 100644 index 0000000..cb8723f --- /dev/null +++ b/Legacy/ws_linux/devel/share/rosaria/docs/RosAriaConfig.dox @@ -0,0 +1,14 @@ +\subsubsection parameters ROS parameters + +Reads and maintains the following parameters on the ROS server + +- \b "~trans_accel" : \b [double] Translational acceleration (m/s^2) min: -std::numeric_limits::infinity(), default: 0, max: std::numeric_limits::infinity() +- \b "~trans_decel" : \b [double] Translational deceleration (m/s^2) min: -std::numeric_limits::infinity(), default: 0, max: std::numeric_limits::infinity() +- \b "~lat_accel" : \b [double] Lateral acceleration (m/s^2) min: -std::numeric_limits::infinity(), default: 0, max: std::numeric_limits::infinity() +- \b "~lat_decel" : \b [double] Lateral deceleration (m/s^2) min: -std::numeric_limits::infinity(), default: 0, max: std::numeric_limits::infinity() +- \b "~rot_accel" : \b [double] Rotational acceleration (rad/s^2) min: -std::numeric_limits::infinity(), default: 0, max: std::numeric_limits::infinity() +- \b "~rot_decel" : \b [double] Rotational deceleration (rad/s^2) min: -std::numeric_limits::infinity(), default: 0, max: std::numeric_limits::infinity() +- \b "~TicksMM" : \b [int] Encoder ticks/mm min: -2147483648, default: 0, max: 2147483647 +- \b "~DriftFactor" : \b [int] Value in 1/8192 increments to be added or subtracted from the left encoder ticks in order to compensate for tire differences. min: -2147483648, default: 0, max: 2147483647 +- \b "~RevCount" : \b [int] The number of differential encoder ticks for a 180-degree revolution of the robot. min: -2147483648, default: 0, max: 2147483647 + diff --git a/Legacy/ws_linux/devel/share/rosaria/docs/RosAriaConfig.wikidoc b/Legacy/ws_linux/devel/share/rosaria/docs/RosAriaConfig.wikidoc new file mode 100644 index 0000000..101f246 --- /dev/null +++ b/Legacy/ws_linux/devel/share/rosaria/docs/RosAriaConfig.wikidoc @@ -0,0 +1,44 @@ +# Autogenerated param section. Do not hand edit. +param { +group.0 { +name=Dynamically Reconfigurable Parameters +desc=See the [[dynamic_reconfigure]] package for details on dynamically reconfigurable parameters. +0.name= ~trans_accel +0.default= 0 +0.type= double +0.desc=Translational acceleration (m/s^2) Range: -std::numeric_limits::infinity() to std::numeric_limits::infinity() +1.name= ~trans_decel +1.default= 0 +1.type= double +1.desc=Translational deceleration (m/s^2) Range: -std::numeric_limits::infinity() to std::numeric_limits::infinity() +2.name= ~lat_accel +2.default= 0 +2.type= double +2.desc=Lateral acceleration (m/s^2) Range: -std::numeric_limits::infinity() to std::numeric_limits::infinity() +3.name= ~lat_decel +3.default= 0 +3.type= double +3.desc=Lateral deceleration (m/s^2) Range: -std::numeric_limits::infinity() to std::numeric_limits::infinity() +4.name= ~rot_accel +4.default= 0 +4.type= double +4.desc=Rotational acceleration (rad/s^2) Range: -std::numeric_limits::infinity() to std::numeric_limits::infinity() +5.name= ~rot_decel +5.default= 0 +5.type= double +5.desc=Rotational deceleration (rad/s^2) Range: -std::numeric_limits::infinity() to std::numeric_limits::infinity() +6.name= ~TicksMM +6.default= 0 +6.type= int +6.desc=Encoder ticks/mm Range: -2147483648 to 2147483647 +7.name= ~DriftFactor +7.default= 0 +7.type= int +7.desc=Value in 1/8192 increments to be added or subtracted from the left encoder ticks in order to compensate for tire differences. Range: -2147483648 to 2147483647 +8.name= ~RevCount +8.default= 0 +8.type= int +8.desc=The number of differential encoder ticks for a 180-degree revolution of the robot. Range: -2147483648 to 2147483647 +} +} +# End of autogenerated section. You may edit below. diff --git a/Legacy/ws_linux/devel/share/rosaria_msgs/cmake/rosaria_msgs-msg-extras.cmake b/Legacy/ws_linux/devel/share/rosaria_msgs/cmake/rosaria_msgs-msg-extras.cmake new file mode 100644 index 0000000..e01c757 --- /dev/null +++ b/Legacy/ws_linux/devel/share/rosaria_msgs/cmake/rosaria_msgs-msg-extras.cmake @@ -0,0 +1,2 @@ +set(rosaria_msgs_MESSAGE_FILES "/home/lab1_5/ws/ws_linux/src/rosaria_msgs/msg/RestrictionsMsg.msg;/home/lab1_5/ws/ws_linux/src/rosaria_msgs/msg/RobotInfoMsg.msg") +set(rosaria_msgs_SERVICE_FILES "") diff --git a/Legacy/ws_linux/devel/share/rosaria_msgs/cmake/rosaria_msgs-msg-paths.cmake b/Legacy/ws_linux/devel/share/rosaria_msgs/cmake/rosaria_msgs-msg-paths.cmake new file mode 100644 index 0000000..226d244 --- /dev/null +++ b/Legacy/ws_linux/devel/share/rosaria_msgs/cmake/rosaria_msgs-msg-paths.cmake @@ -0,0 +1,5 @@ +# generated from genmsg/cmake/pkg-msg-paths.cmake.em + +# message include dirs in develspace +set(rosaria_msgs_MSG_INCLUDE_DIRS "/home/lab1_5/ws/ws_linux/src/rosaria_msgs/msg") +set(rosaria_msgs_MSG_DEPENDENCIES std_msgs;geometry_msgs) diff --git a/Legacy/ws_linux/devel/share/rosaria_msgs/cmake/rosaria_msgsConfig-version.cmake b/Legacy/ws_linux/devel/share/rosaria_msgs/cmake/rosaria_msgsConfig-version.cmake new file mode 100644 index 0000000..7fd9f99 --- /dev/null +++ b/Legacy/ws_linux/devel/share/rosaria_msgs/cmake/rosaria_msgsConfig-version.cmake @@ -0,0 +1,14 @@ +# generated from catkin/cmake/template/pkgConfig-version.cmake.in +set(PACKAGE_VERSION "0.0.0") + +set(PACKAGE_VERSION_EXACT False) +set(PACKAGE_VERSION_COMPATIBLE False) + +if("${PACKAGE_FIND_VERSION}" VERSION_EQUAL "${PACKAGE_VERSION}") + set(PACKAGE_VERSION_EXACT True) + set(PACKAGE_VERSION_COMPATIBLE True) +endif() + +if("${PACKAGE_FIND_VERSION}" VERSION_LESS "${PACKAGE_VERSION}") + set(PACKAGE_VERSION_COMPATIBLE True) +endif() diff --git a/Legacy/ws_linux/devel/share/rosaria_msgs/cmake/rosaria_msgsConfig.cmake b/Legacy/ws_linux/devel/share/rosaria_msgs/cmake/rosaria_msgsConfig.cmake new file mode 100644 index 0000000..d813638 --- /dev/null +++ b/Legacy/ws_linux/devel/share/rosaria_msgs/cmake/rosaria_msgsConfig.cmake @@ -0,0 +1,191 @@ +# generated from catkin/cmake/template/pkgConfig.cmake.in + +# append elements to a list and remove existing duplicates from the list +# copied from catkin/cmake/list_append_deduplicate.cmake to keep pkgConfig +# self contained +macro(_list_append_deduplicate listname) + if(NOT "${ARGN}" STREQUAL "") + if(${listname}) + list(REMOVE_ITEM ${listname} ${ARGN}) + endif() + list(APPEND ${listname} ${ARGN}) + endif() +endmacro() + +# append elements to a list if they are not already in the list +# copied from catkin/cmake/list_append_unique.cmake to keep pkgConfig +# self contained +macro(_list_append_unique listname) + foreach(_item ${ARGN}) + list(FIND ${listname} ${_item} _index) + if(_index EQUAL -1) + list(APPEND ${listname} ${_item}) + endif() + endforeach() +endmacro() + +# pack a list of libraries with optional build configuration keywords +# copied from catkin/cmake/catkin_libraries.cmake to keep pkgConfig +# self contained +macro(_pack_libraries_with_build_configuration VAR) + set(${VAR} "") + set(_argn ${ARGN}) + list(LENGTH _argn _count) + set(_index 0) + while(${_index} LESS ${_count}) + list(GET _argn ${_index} lib) + if("${lib}" MATCHES "^debug|optimized|general$") + math(EXPR _index "${_index} + 1") + if(${_index} EQUAL ${_count}) + message(FATAL_ERROR "_pack_libraries_with_build_configuration() the list of libraries '${ARGN}' ends with '${lib}' which is a build configuration keyword and must be followed by a library") + endif() + list(GET _argn ${_index} library) + list(APPEND ${VAR} "${lib}${CATKIN_BUILD_CONFIGURATION_KEYWORD_SEPARATOR}${library}") + else() + list(APPEND ${VAR} "${lib}") + endif() + math(EXPR _index "${_index} + 1") + endwhile() +endmacro() + +# unpack a list of libraries with optional build configuration keyword prefixes +# copied from catkin/cmake/catkin_libraries.cmake to keep pkgConfig +# self contained +macro(_unpack_libraries_with_build_configuration VAR) + set(${VAR} "") + foreach(lib ${ARGN}) + string(REGEX REPLACE "^(debug|optimized|general)${CATKIN_BUILD_CONFIGURATION_KEYWORD_SEPARATOR}(.+)$" "\\1;\\2" lib "${lib}") + list(APPEND ${VAR} "${lib}") + endforeach() +endmacro() + + +if(rosaria_msgs_CONFIG_INCLUDED) + return() +endif() +set(rosaria_msgs_CONFIG_INCLUDED TRUE) + +# set variables for source/devel/install prefixes +if("TRUE" STREQUAL "TRUE") + set(rosaria_msgs_SOURCE_PREFIX /home/lab1_5/ws/ws_linux/src/rosaria_msgs) + set(rosaria_msgs_DEVEL_PREFIX /home/lab1_5/ws/ws_linux/devel) + set(rosaria_msgs_INSTALL_PREFIX "") + set(rosaria_msgs_PREFIX ${rosaria_msgs_DEVEL_PREFIX}) +else() + set(rosaria_msgs_SOURCE_PREFIX "") + set(rosaria_msgs_DEVEL_PREFIX "") + set(rosaria_msgs_INSTALL_PREFIX /home/lab1_5/ws/ws_linux/install) + set(rosaria_msgs_PREFIX ${rosaria_msgs_INSTALL_PREFIX}) +endif() + +# warn when using a deprecated package +if(NOT "" STREQUAL "") + set(_msg "WARNING: package 'rosaria_msgs' is deprecated") + # append custom deprecation text if available + if(NOT "" STREQUAL "TRUE") + set(_msg "${_msg} ()") + endif() + message("${_msg}") +endif() + +# flag project as catkin-based to distinguish if a find_package()-ed project is a catkin project +set(rosaria_msgs_FOUND_CATKIN_PROJECT TRUE) + +if(NOT "/home/lab1_5/ws/ws_linux/devel/include" STREQUAL "") + set(rosaria_msgs_INCLUDE_DIRS "") + set(_include_dirs "/home/lab1_5/ws/ws_linux/devel/include") + foreach(idir ${_include_dirs}) + if(IS_ABSOLUTE ${idir} AND IS_DIRECTORY ${idir}) + set(include ${idir}) + elseif("${idir}" STREQUAL "include") + get_filename_component(include "${rosaria_msgs_DIR}/../../../include" ABSOLUTE) + if(NOT IS_DIRECTORY ${include}) + message(FATAL_ERROR "Project 'rosaria_msgs' specifies '${idir}' as an include dir, which is not found. It does not exist in '${include}'. Ask the maintainer 'Aleksander Bojda ' to fix it.") + endif() + else() + message(FATAL_ERROR "Project 'rosaria_msgs' specifies '${idir}' as an include dir, which is not found. It does neither exist as an absolute directory nor in '/home/lab1_5/ws/ws_linux/src/rosaria_msgs/${idir}'. Ask the maintainer 'Aleksander Bojda ' to fix it.") + endif() + _list_append_unique(rosaria_msgs_INCLUDE_DIRS ${include}) + endforeach() +endif() + +set(libraries "") +foreach(library ${libraries}) + # keep build configuration keywords, target names and absolute libraries as-is + if("${library}" MATCHES "^debug|optimized|general$") + list(APPEND rosaria_msgs_LIBRARIES ${library}) + elseif(TARGET ${library}) + list(APPEND rosaria_msgs_LIBRARIES ${library}) + elseif(IS_ABSOLUTE ${library}) + list(APPEND rosaria_msgs_LIBRARIES ${library}) + else() + set(lib_path "") + set(lib "${library}-NOTFOUND") + # since the path where the library is found is returned we have to iterate over the paths manually + foreach(path /home/lab1_5/ws/ws_linux/devel/lib;/home/lab1_5/ws/ws_linux/devel/lib;/home/lab1_5/ws/ws_xeno/devel/lib;/home/lab1_5/ws/ws_isolated/install_isolated/lib;/opt/ros/hydro/lib) + find_library(lib ${library} + PATHS ${path} + NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH) + if(lib) + set(lib_path ${path}) + break() + endif() + endforeach() + if(lib) + _list_append_unique(rosaria_msgs_LIBRARY_DIRS ${lib_path}) + list(APPEND rosaria_msgs_LIBRARIES ${lib}) + else() + # as a fall back for non-catkin libraries try to search globally + find_library(lib ${library}) + if(NOT lib) + message(FATAL_ERROR "Project '${PROJECT_NAME}' tried to find library '${library}'. The library is neither a target nor built/installed properly. Did you compile project 'rosaria_msgs'? Did you find_package() it before the subdirectory containing its code is included?") + endif() + list(APPEND rosaria_msgs_LIBRARIES ${lib}) + endif() + endif() +endforeach() + +set(rosaria_msgs_EXPORTED_TARGETS "rosaria_msgs_generate_messages_cpp;rosaria_msgs_generate_messages_lisp;rosaria_msgs_generate_messages_py") +# create dummy targets for exported code generation targets to make life of users easier +foreach(t ${rosaria_msgs_EXPORTED_TARGETS}) + if(NOT TARGET ${t}) + add_custom_target(${t}) + endif() +endforeach() + +set(depends "message_runtime") +foreach(depend ${depends}) + string(REPLACE " " ";" depend_list ${depend}) + # the package name of the dependency must be kept in a unique variable so that it is not overwritten in recursive calls + list(GET depend_list 0 rosaria_msgs_dep) + list(LENGTH depend_list count) + if(${count} EQUAL 1) + # simple dependencies must only be find_package()-ed once + if(NOT ${rosaria_msgs_dep}_FOUND) + find_package(${rosaria_msgs_dep} REQUIRED) + endif() + else() + # dependencies with components must be find_package()-ed again + list(REMOVE_AT depend_list 0) + find_package(${rosaria_msgs_dep} REQUIRED ${depend_list}) + endif() + _list_append_unique(rosaria_msgs_INCLUDE_DIRS ${${rosaria_msgs_dep}_INCLUDE_DIRS}) + + # merge build configuration keywords with library names to correctly deduplicate + _pack_libraries_with_build_configuration(rosaria_msgs_LIBRARIES ${rosaria_msgs_LIBRARIES}) + _pack_libraries_with_build_configuration(_libraries ${${rosaria_msgs_dep}_LIBRARIES}) + _list_append_deduplicate(rosaria_msgs_LIBRARIES ${_libraries}) + # undo build configuration keyword merging after deduplication + _unpack_libraries_with_build_configuration(rosaria_msgs_LIBRARIES ${rosaria_msgs_LIBRARIES}) + + _list_append_unique(rosaria_msgs_LIBRARY_DIRS ${${rosaria_msgs_dep}_LIBRARY_DIRS}) + list(APPEND rosaria_msgs_EXPORTED_TARGETS ${${rosaria_msgs_dep}_EXPORTED_TARGETS}) +endforeach() + +set(pkg_cfg_extras "rosaria_msgs-msg-extras.cmake") +foreach(extra ${pkg_cfg_extras}) + if(NOT IS_ABSOLUTE ${extra}) + set(extra ${rosaria_msgs_DIR}/${extra}) + endif() + include(${extra}) +endforeach() diff --git a/Legacy/ws_linux/devel/share/safety/cmake/safety-msg-extras.cmake b/Legacy/ws_linux/devel/share/safety/cmake/safety-msg-extras.cmake new file mode 100644 index 0000000..c1b75eb --- /dev/null +++ b/Legacy/ws_linux/devel/share/safety/cmake/safety-msg-extras.cmake @@ -0,0 +1,2 @@ +set(safety_MESSAGE_FILES "") +set(safety_SERVICE_FILES "") diff --git a/Legacy/ws_linux/devel/share/safety/cmake/safety-msg-paths.cmake b/Legacy/ws_linux/devel/share/safety/cmake/safety-msg-paths.cmake new file mode 100644 index 0000000..ad11753 --- /dev/null +++ b/Legacy/ws_linux/devel/share/safety/cmake/safety-msg-paths.cmake @@ -0,0 +1,5 @@ +# generated from genmsg/cmake/pkg-msg-paths.cmake.em + +# message include dirs in develspace +set(safety_MSG_INCLUDE_DIRS "") +set(safety_MSG_DEPENDENCIES std_msgs) diff --git a/Legacy/ws_linux/devel/share/safety/cmake/safetyConfig-version.cmake b/Legacy/ws_linux/devel/share/safety/cmake/safetyConfig-version.cmake new file mode 100644 index 0000000..40ac4c2 --- /dev/null +++ b/Legacy/ws_linux/devel/share/safety/cmake/safetyConfig-version.cmake @@ -0,0 +1,14 @@ +# generated from catkin/cmake/template/pkgConfig-version.cmake.in +set(PACKAGE_VERSION "0.2.1") + +set(PACKAGE_VERSION_EXACT False) +set(PACKAGE_VERSION_COMPATIBLE False) + +if("${PACKAGE_FIND_VERSION}" VERSION_EQUAL "${PACKAGE_VERSION}") + set(PACKAGE_VERSION_EXACT True) + set(PACKAGE_VERSION_COMPATIBLE True) +endif() + +if("${PACKAGE_FIND_VERSION}" VERSION_LESS "${PACKAGE_VERSION}") + set(PACKAGE_VERSION_COMPATIBLE True) +endif() diff --git a/Legacy/ws_linux/devel/share/safety/cmake/safetyConfig.cmake b/Legacy/ws_linux/devel/share/safety/cmake/safetyConfig.cmake new file mode 100644 index 0000000..6169f32 --- /dev/null +++ b/Legacy/ws_linux/devel/share/safety/cmake/safetyConfig.cmake @@ -0,0 +1,191 @@ +# generated from catkin/cmake/template/pkgConfig.cmake.in + +# append elements to a list and remove existing duplicates from the list +# copied from catkin/cmake/list_append_deduplicate.cmake to keep pkgConfig +# self contained +macro(_list_append_deduplicate listname) + if(NOT "${ARGN}" STREQUAL "") + if(${listname}) + list(REMOVE_ITEM ${listname} ${ARGN}) + endif() + list(APPEND ${listname} ${ARGN}) + endif() +endmacro() + +# append elements to a list if they are not already in the list +# copied from catkin/cmake/list_append_unique.cmake to keep pkgConfig +# self contained +macro(_list_append_unique listname) + foreach(_item ${ARGN}) + list(FIND ${listname} ${_item} _index) + if(_index EQUAL -1) + list(APPEND ${listname} ${_item}) + endif() + endforeach() +endmacro() + +# pack a list of libraries with optional build configuration keywords +# copied from catkin/cmake/catkin_libraries.cmake to keep pkgConfig +# self contained +macro(_pack_libraries_with_build_configuration VAR) + set(${VAR} "") + set(_argn ${ARGN}) + list(LENGTH _argn _count) + set(_index 0) + while(${_index} LESS ${_count}) + list(GET _argn ${_index} lib) + if("${lib}" MATCHES "^debug|optimized|general$") + math(EXPR _index "${_index} + 1") + if(${_index} EQUAL ${_count}) + message(FATAL_ERROR "_pack_libraries_with_build_configuration() the list of libraries '${ARGN}' ends with '${lib}' which is a build configuration keyword and must be followed by a library") + endif() + list(GET _argn ${_index} library) + list(APPEND ${VAR} "${lib}${CATKIN_BUILD_CONFIGURATION_KEYWORD_SEPARATOR}${library}") + else() + list(APPEND ${VAR} "${lib}") + endif() + math(EXPR _index "${_index} + 1") + endwhile() +endmacro() + +# unpack a list of libraries with optional build configuration keyword prefixes +# copied from catkin/cmake/catkin_libraries.cmake to keep pkgConfig +# self contained +macro(_unpack_libraries_with_build_configuration VAR) + set(${VAR} "") + foreach(lib ${ARGN}) + string(REGEX REPLACE "^(debug|optimized|general)${CATKIN_BUILD_CONFIGURATION_KEYWORD_SEPARATOR}(.+)$" "\\1;\\2" lib "${lib}") + list(APPEND ${VAR} "${lib}") + endforeach() +endmacro() + + +if(safety_CONFIG_INCLUDED) + return() +endif() +set(safety_CONFIG_INCLUDED TRUE) + +# set variables for source/devel/install prefixes +if("TRUE" STREQUAL "TRUE") + set(safety_SOURCE_PREFIX /home/lab1_5/ws/ws_linux/src/safety) + set(safety_DEVEL_PREFIX /home/lab1_5/ws/ws_linux/devel) + set(safety_INSTALL_PREFIX "") + set(safety_PREFIX ${safety_DEVEL_PREFIX}) +else() + set(safety_SOURCE_PREFIX "") + set(safety_DEVEL_PREFIX "") + set(safety_INSTALL_PREFIX /home/lab1_5/ws/ws_linux/install) + set(safety_PREFIX ${safety_INSTALL_PREFIX}) +endif() + +# warn when using a deprecated package +if(NOT "" STREQUAL "") + set(_msg "WARNING: package 'safety' is deprecated") + # append custom deprecation text if available + if(NOT "" STREQUAL "TRUE") + set(_msg "${_msg} ()") + endif() + message("${_msg}") +endif() + +# flag project as catkin-based to distinguish if a find_package()-ed project is a catkin project +set(safety_FOUND_CATKIN_PROJECT TRUE) + +if(NOT "" STREQUAL "") + set(safety_INCLUDE_DIRS "") + set(_include_dirs "") + foreach(idir ${_include_dirs}) + if(IS_ABSOLUTE ${idir} AND IS_DIRECTORY ${idir}) + set(include ${idir}) + elseif("${idir}" STREQUAL "include") + get_filename_component(include "${safety_DIR}/../../../include" ABSOLUTE) + if(NOT IS_DIRECTORY ${include}) + message(FATAL_ERROR "Project 'safety' specifies '${idir}' as an include dir, which is not found. It does not exist in '${include}'. Ask the maintainer 'Aleksandra Grzelak ' to fix it.") + endif() + else() + message(FATAL_ERROR "Project 'safety' specifies '${idir}' as an include dir, which is not found. It does neither exist as an absolute directory nor in '/home/lab1_5/ws/ws_linux/src/safety/${idir}'. Ask the maintainer 'Aleksandra Grzelak ' to fix it.") + endif() + _list_append_unique(safety_INCLUDE_DIRS ${include}) + endforeach() +endif() + +set(libraries "safety") +foreach(library ${libraries}) + # keep build configuration keywords, target names and absolute libraries as-is + if("${library}" MATCHES "^debug|optimized|general$") + list(APPEND safety_LIBRARIES ${library}) + elseif(TARGET ${library}) + list(APPEND safety_LIBRARIES ${library}) + elseif(IS_ABSOLUTE ${library}) + list(APPEND safety_LIBRARIES ${library}) + else() + set(lib_path "") + set(lib "${library}-NOTFOUND") + # since the path where the library is found is returned we have to iterate over the paths manually + foreach(path /home/lab1_5/ws/ws_linux/devel/lib;/home/lab1_5/ws/ws_linux/devel/lib;/home/lab1_5/ws/ws_xeno/devel/lib;/home/lab1_5/ws/ws_isolated/install_isolated/lib;/opt/ros/hydro/lib) + find_library(lib ${library} + PATHS ${path} + NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH) + if(lib) + set(lib_path ${path}) + break() + endif() + endforeach() + if(lib) + _list_append_unique(safety_LIBRARY_DIRS ${lib_path}) + list(APPEND safety_LIBRARIES ${lib}) + else() + # as a fall back for non-catkin libraries try to search globally + find_library(lib ${library}) + if(NOT lib) + message(FATAL_ERROR "Project '${PROJECT_NAME}' tried to find library '${library}'. The library is neither a target nor built/installed properly. Did you compile project 'safety'? Did you find_package() it before the subdirectory containing its code is included?") + endif() + list(APPEND safety_LIBRARIES ${lib}) + endif() + endif() +endforeach() + +set(safety_EXPORTED_TARGETS "safety_generate_messages_cpp;safety_generate_messages_lisp;safety_generate_messages_py") +# create dummy targets for exported code generation targets to make life of users easier +foreach(t ${safety_EXPORTED_TARGETS}) + if(NOT TARGET ${t}) + add_custom_target(${t}) + endif() +endforeach() + +set(depends "message_runtime;roscpp;rospy;std_msgs;rosaria") +foreach(depend ${depends}) + string(REPLACE " " ";" depend_list ${depend}) + # the package name of the dependency must be kept in a unique variable so that it is not overwritten in recursive calls + list(GET depend_list 0 safety_dep) + list(LENGTH depend_list count) + if(${count} EQUAL 1) + # simple dependencies must only be find_package()-ed once + if(NOT ${safety_dep}_FOUND) + find_package(${safety_dep} REQUIRED) + endif() + else() + # dependencies with components must be find_package()-ed again + list(REMOVE_AT depend_list 0) + find_package(${safety_dep} REQUIRED ${depend_list}) + endif() + _list_append_unique(safety_INCLUDE_DIRS ${${safety_dep}_INCLUDE_DIRS}) + + # merge build configuration keywords with library names to correctly deduplicate + _pack_libraries_with_build_configuration(safety_LIBRARIES ${safety_LIBRARIES}) + _pack_libraries_with_build_configuration(_libraries ${${safety_dep}_LIBRARIES}) + _list_append_deduplicate(safety_LIBRARIES ${_libraries}) + # undo build configuration keyword merging after deduplication + _unpack_libraries_with_build_configuration(safety_LIBRARIES ${safety_LIBRARIES}) + + _list_append_unique(safety_LIBRARY_DIRS ${${safety_dep}_LIBRARY_DIRS}) + list(APPEND safety_EXPORTED_TARGETS ${${safety_dep}_EXPORTED_TARGETS}) +endforeach() + +set(pkg_cfg_extras "safety-msg-extras.cmake") +foreach(extra ${pkg_cfg_extras}) + if(NOT IS_ABSOLUTE ${extra}) + set(extra ${safety_DIR}/${extra}) + endif() + include(${extra}) +endforeach() diff --git a/Legacy/ws_linux/devel/share/videostream/cmake/videostream-msg-extras.cmake b/Legacy/ws_linux/devel/share/videostream/cmake/videostream-msg-extras.cmake new file mode 100644 index 0000000..ea194e9 --- /dev/null +++ b/Legacy/ws_linux/devel/share/videostream/cmake/videostream-msg-extras.cmake @@ -0,0 +1,2 @@ +set(videostream_MESSAGE_FILES "") +set(videostream_SERVICE_FILES "/home/lab1_5/ws/ws_linux/src/videostream/srv/ip_get.srv") diff --git a/Legacy/ws_linux/devel/share/videostream/cmake/videostream-msg-paths.cmake b/Legacy/ws_linux/devel/share/videostream/cmake/videostream-msg-paths.cmake new file mode 100644 index 0000000..bd4496a --- /dev/null +++ b/Legacy/ws_linux/devel/share/videostream/cmake/videostream-msg-paths.cmake @@ -0,0 +1,5 @@ +# generated from genmsg/cmake/pkg-msg-paths.cmake.em + +# message include dirs in develspace +set(videostream_MSG_INCLUDE_DIRS "") +set(videostream_MSG_DEPENDENCIES std_msgs) diff --git a/Legacy/ws_linux/devel/share/videostream/cmake/videostreamConfig-version.cmake b/Legacy/ws_linux/devel/share/videostream/cmake/videostreamConfig-version.cmake new file mode 100644 index 0000000..7fd9f99 --- /dev/null +++ b/Legacy/ws_linux/devel/share/videostream/cmake/videostreamConfig-version.cmake @@ -0,0 +1,14 @@ +# generated from catkin/cmake/template/pkgConfig-version.cmake.in +set(PACKAGE_VERSION "0.0.0") + +set(PACKAGE_VERSION_EXACT False) +set(PACKAGE_VERSION_COMPATIBLE False) + +if("${PACKAGE_FIND_VERSION}" VERSION_EQUAL "${PACKAGE_VERSION}") + set(PACKAGE_VERSION_EXACT True) + set(PACKAGE_VERSION_COMPATIBLE True) +endif() + +if("${PACKAGE_FIND_VERSION}" VERSION_LESS "${PACKAGE_VERSION}") + set(PACKAGE_VERSION_COMPATIBLE True) +endif() diff --git a/Legacy/ws_linux/devel/share/videostream/cmake/videostreamConfig.cmake b/Legacy/ws_linux/devel/share/videostream/cmake/videostreamConfig.cmake new file mode 100644 index 0000000..bdc09a6 --- /dev/null +++ b/Legacy/ws_linux/devel/share/videostream/cmake/videostreamConfig.cmake @@ -0,0 +1,191 @@ +# generated from catkin/cmake/template/pkgConfig.cmake.in + +# append elements to a list and remove existing duplicates from the list +# copied from catkin/cmake/list_append_deduplicate.cmake to keep pkgConfig +# self contained +macro(_list_append_deduplicate listname) + if(NOT "${ARGN}" STREQUAL "") + if(${listname}) + list(REMOVE_ITEM ${listname} ${ARGN}) + endif() + list(APPEND ${listname} ${ARGN}) + endif() +endmacro() + +# append elements to a list if they are not already in the list +# copied from catkin/cmake/list_append_unique.cmake to keep pkgConfig +# self contained +macro(_list_append_unique listname) + foreach(_item ${ARGN}) + list(FIND ${listname} ${_item} _index) + if(_index EQUAL -1) + list(APPEND ${listname} ${_item}) + endif() + endforeach() +endmacro() + +# pack a list of libraries with optional build configuration keywords +# copied from catkin/cmake/catkin_libraries.cmake to keep pkgConfig +# self contained +macro(_pack_libraries_with_build_configuration VAR) + set(${VAR} "") + set(_argn ${ARGN}) + list(LENGTH _argn _count) + set(_index 0) + while(${_index} LESS ${_count}) + list(GET _argn ${_index} lib) + if("${lib}" MATCHES "^debug|optimized|general$") + math(EXPR _index "${_index} + 1") + if(${_index} EQUAL ${_count}) + message(FATAL_ERROR "_pack_libraries_with_build_configuration() the list of libraries '${ARGN}' ends with '${lib}' which is a build configuration keyword and must be followed by a library") + endif() + list(GET _argn ${_index} library) + list(APPEND ${VAR} "${lib}${CATKIN_BUILD_CONFIGURATION_KEYWORD_SEPARATOR}${library}") + else() + list(APPEND ${VAR} "${lib}") + endif() + math(EXPR _index "${_index} + 1") + endwhile() +endmacro() + +# unpack a list of libraries with optional build configuration keyword prefixes +# copied from catkin/cmake/catkin_libraries.cmake to keep pkgConfig +# self contained +macro(_unpack_libraries_with_build_configuration VAR) + set(${VAR} "") + foreach(lib ${ARGN}) + string(REGEX REPLACE "^(debug|optimized|general)${CATKIN_BUILD_CONFIGURATION_KEYWORD_SEPARATOR}(.+)$" "\\1;\\2" lib "${lib}") + list(APPEND ${VAR} "${lib}") + endforeach() +endmacro() + + +if(videostream_CONFIG_INCLUDED) + return() +endif() +set(videostream_CONFIG_INCLUDED TRUE) + +# set variables for source/devel/install prefixes +if("TRUE" STREQUAL "TRUE") + set(videostream_SOURCE_PREFIX /home/lab1_5/ws/ws_linux/src/videostream) + set(videostream_DEVEL_PREFIX /home/lab1_5/ws/ws_linux/devel) + set(videostream_INSTALL_PREFIX "") + set(videostream_PREFIX ${videostream_DEVEL_PREFIX}) +else() + set(videostream_SOURCE_PREFIX "") + set(videostream_DEVEL_PREFIX "") + set(videostream_INSTALL_PREFIX /home/lab1_5/ws/ws_linux/install) + set(videostream_PREFIX ${videostream_INSTALL_PREFIX}) +endif() + +# warn when using a deprecated package +if(NOT "" STREQUAL "") + set(_msg "WARNING: package 'videostream' is deprecated") + # append custom deprecation text if available + if(NOT "" STREQUAL "TRUE") + set(_msg "${_msg} ()") + endif() + message("${_msg}") +endif() + +# flag project as catkin-based to distinguish if a find_package()-ed project is a catkin project +set(videostream_FOUND_CATKIN_PROJECT TRUE) + +if(NOT "/home/lab1_5/ws/ws_linux/devel/include;/home/lab1_5/ws/ws_linux/src/videostream/include" STREQUAL "") + set(videostream_INCLUDE_DIRS "") + set(_include_dirs "/home/lab1_5/ws/ws_linux/devel/include;/home/lab1_5/ws/ws_linux/src/videostream/include") + foreach(idir ${_include_dirs}) + if(IS_ABSOLUTE ${idir} AND IS_DIRECTORY ${idir}) + set(include ${idir}) + elseif("${idir}" STREQUAL "include") + get_filename_component(include "${videostream_DIR}/../../../include" ABSOLUTE) + if(NOT IS_DIRECTORY ${include}) + message(FATAL_ERROR "Project 'videostream' specifies '${idir}' as an include dir, which is not found. It does not exist in '${include}'. Ask the maintainer 'lab ' to fix it.") + endif() + else() + message(FATAL_ERROR "Project 'videostream' specifies '${idir}' as an include dir, which is not found. It does neither exist as an absolute directory nor in '/home/lab1_5/ws/ws_linux/src/videostream/${idir}'. Ask the maintainer 'lab ' to fix it.") + endif() + _list_append_unique(videostream_INCLUDE_DIRS ${include}) + endforeach() +endif() + +set(libraries "videostream") +foreach(library ${libraries}) + # keep build configuration keywords, target names and absolute libraries as-is + if("${library}" MATCHES "^debug|optimized|general$") + list(APPEND videostream_LIBRARIES ${library}) + elseif(TARGET ${library}) + list(APPEND videostream_LIBRARIES ${library}) + elseif(IS_ABSOLUTE ${library}) + list(APPEND videostream_LIBRARIES ${library}) + else() + set(lib_path "") + set(lib "${library}-NOTFOUND") + # since the path where the library is found is returned we have to iterate over the paths manually + foreach(path /home/lab1_5/ws/ws_linux/devel/lib;/home/lab1_5/ws/ws_linux/devel/lib;/home/lab1_5/ws/ws_xeno/devel/lib;/home/lab1_5/ws/ws_isolated/install_isolated/lib;/opt/ros/hydro/lib) + find_library(lib ${library} + PATHS ${path} + NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH) + if(lib) + set(lib_path ${path}) + break() + endif() + endforeach() + if(lib) + _list_append_unique(videostream_LIBRARY_DIRS ${lib_path}) + list(APPEND videostream_LIBRARIES ${lib}) + else() + # as a fall back for non-catkin libraries try to search globally + find_library(lib ${library}) + if(NOT lib) + message(FATAL_ERROR "Project '${PROJECT_NAME}' tried to find library '${library}'. The library is neither a target nor built/installed properly. Did you compile project 'videostream'? Did you find_package() it before the subdirectory containing its code is included?") + endif() + list(APPEND videostream_LIBRARIES ${lib}) + endif() + endif() +endforeach() + +set(videostream_EXPORTED_TARGETS "videostream_generate_messages_cpp;videostream_generate_messages_lisp;videostream_generate_messages_py") +# create dummy targets for exported code generation targets to make life of users easier +foreach(t ${videostream_EXPORTED_TARGETS}) + if(NOT TARGET ${t}) + add_custom_target(${t}) + endif() +endforeach() + +set(depends "message_runtime;roscpp;rospy;std_msgs") +foreach(depend ${depends}) + string(REPLACE " " ";" depend_list ${depend}) + # the package name of the dependency must be kept in a unique variable so that it is not overwritten in recursive calls + list(GET depend_list 0 videostream_dep) + list(LENGTH depend_list count) + if(${count} EQUAL 1) + # simple dependencies must only be find_package()-ed once + if(NOT ${videostream_dep}_FOUND) + find_package(${videostream_dep} REQUIRED) + endif() + else() + # dependencies with components must be find_package()-ed again + list(REMOVE_AT depend_list 0) + find_package(${videostream_dep} REQUIRED ${depend_list}) + endif() + _list_append_unique(videostream_INCLUDE_DIRS ${${videostream_dep}_INCLUDE_DIRS}) + + # merge build configuration keywords with library names to correctly deduplicate + _pack_libraries_with_build_configuration(videostream_LIBRARIES ${videostream_LIBRARIES}) + _pack_libraries_with_build_configuration(_libraries ${${videostream_dep}_LIBRARIES}) + _list_append_deduplicate(videostream_LIBRARIES ${_libraries}) + # undo build configuration keyword merging after deduplication + _unpack_libraries_with_build_configuration(videostream_LIBRARIES ${videostream_LIBRARIES}) + + _list_append_unique(videostream_LIBRARY_DIRS ${${videostream_dep}_LIBRARY_DIRS}) + list(APPEND videostream_EXPORTED_TARGETS ${${videostream_dep}_EXPORTED_TARGETS}) +endforeach() + +set(pkg_cfg_extras "videostream-msg-extras.cmake") +foreach(extra ${pkg_cfg_extras}) + if(NOT IS_ABSOLUTE ${extra}) + set(extra ${videostream_DIR}/${extra}) + endif() + include(${extra}) +endforeach() diff --git a/Legacy/ws_linux/src/CMakeLists.txt b/Legacy/ws_linux/src/CMakeLists.txt new file mode 100644 index 0000000..40273ce --- /dev/null +++ b/Legacy/ws_linux/src/CMakeLists.txt @@ -0,0 +1,64 @@ +# toplevel CMakeLists.txt for a catkin workspace +# catkin/cmake/toplevel.cmake + +cmake_minimum_required(VERSION 2.8.3) + +set(CATKIN_TOPLEVEL TRUE) + +# search for catkin within the workspace +set(_cmd "catkin_find_pkg" "catkin" "${CMAKE_SOURCE_DIR}") +execute_process(COMMAND ${_cmd} + RESULT_VARIABLE _res + OUTPUT_VARIABLE _out + ERROR_VARIABLE _err + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_STRIP_TRAILING_WHITESPACE +) +if(NOT _res EQUAL 0 AND NOT _res EQUAL 2) + # searching fot catkin resulted in an error + string(REPLACE ";" " " _cmd_str "${_cmd}") + message(FATAL_ERROR "Search for 'catkin' in workspace failed (${_cmd_str}): ${_err}") +endif() + +# include catkin from workspace or via find_package() +if(_res EQUAL 0) + set(catkin_EXTRAS_DIR "${CMAKE_SOURCE_DIR}/${_out}/cmake") + # include all.cmake without add_subdirectory to let it operate in same scope + include(${catkin_EXTRAS_DIR}/all.cmake NO_POLICY_SCOPE) + add_subdirectory("${_out}") + +else() + # use either CMAKE_PREFIX_PATH explicitly passed to CMake as a command line argument + # or CMAKE_PREFIX_PATH from the environment + if(NOT DEFINED CMAKE_PREFIX_PATH) + if(NOT "$ENV{CMAKE_PREFIX_PATH}" STREQUAL "") + string(REPLACE ":" ";" CMAKE_PREFIX_PATH $ENV{CMAKE_PREFIX_PATH}) + endif() + endif() + + # list of catkin workspaces + set(catkin_search_path "") + foreach(path ${CMAKE_PREFIX_PATH}) + if(EXISTS "${path}/.catkin") + list(FIND catkin_search_path ${path} _index) + if(_index EQUAL -1) + list(APPEND catkin_search_path ${path}) + endif() + endif() + endforeach() + + # search for catkin in all workspaces + set(CATKIN_TOPLEVEL_FIND_PACKAGE TRUE) + find_package(catkin QUIET + NO_POLICY_SCOPE + PATHS ${catkin_search_path} + NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH) + unset(CATKIN_TOPLEVEL_FIND_PACKAGE) + + if(NOT catkin_FOUND) + message(FATAL_ERROR "find_package(catkin) failed. catkin was neither found in the workspace nor in the CMAKE_PREFIX_PATH. One reason may be that no ROS setup.sh was sourced before.") + endif() +endif() + +catkin_workspace() + diff --git a/Legacy/ws_linux/src/rosaria/.RosAria.cpp.swp b/Legacy/ws_linux/src/rosaria/.RosAria.cpp.swp new file mode 100644 index 0000000000000000000000000000000000000000..d2dca965296d4e7a1761cc94d52bc4418e88ba51 GIT binary patch literal 16384 zcmeI3TW};*8ONK;auERq#VWP*Fe}s~PNs7~Sb8_n?1d$;Y(kRVr4V-P={}P*+tWRE zpH5~HS$Wa23bgR@;sXk$1?8J}U3o)GeE{`E3kpFHFJ-AzQ3{F(`2S9yp6;GZ!tR

    KxYy0tXi$s#swA9!UKf| zPQwEiYGb1#!<2D*>2h}IC5KLk@0YZJA(ewGbdJ=imBY#cFkE!&(^vGXT@)?yruPR9D`LB{ECz7xC$X`+N+f@FS zd*uI7a!bh%sRkwGzuY7LVUPUZN`9Bh|DLnrFG+rtTznKBC_GSjpzuK9fx-iY2MP}q z9woL9s>7(7B~QI1UtYr;A-&91)BC0 zxEmY=2fz(rH+Ua76TFJwD!d5(0KNh401j9L3t%r`;9~H~`6v_I3nCzZ1CD@?fD+gS z{&=3I{S4d(?gXCzhrlQp0q2ABz;oxK9pC|QKe!7V1-AnOTn4^#j;2k6gJ2Mx37*)d zX>D*Bcqcd)JbkvNeHVNd*uVm3fUn>#VgmdYcNR~ApMW2O2f^pTz2G=-!7(rmc7pAo z1gLLc>wl5K@Pyn8{h-zi7ed3h!FN0{CrrWFkwwnkop2qV$zXrrv|2nEWDD_^ohp6S zuls@x2K13j+v9s4w}cILLLzMW0qT^7;5Q_OG4C`vTjH+3r%JE;zMGg_v;AeSX4T6msul)I$g!{45*@>s zY)`lbvO;NFKls+2t*!Zc;cE;4XbG*h{bZLAX^IuOSjvJPtlbEVU9|mXcfor z-4yTCc+DutD$(P?=Yks34 zNnO;m9(m|{W>9OuctmoO+-hHL;q7>*j7zoRyyGQ}i;ej6KqWzRj;U zJ=^6BYaL~xRqV**{GRLgPVe8TwE|yYIpnqxhnFSavEew=o-qTn$pwrls})6x?2czP z9jgY%`Ch|WhyuQ6cNyNGpGsoIihnDKMHVu4Wvo+S5h@)UtqJCG454g!(s59yHF-}x zR~4E`BP*8{wj3`>&~<4MhGi|80ck{3b!2qbOiQTXA(zN{vJR{IU~@HCd@M=D3Jj)F|0t%aA6;b~%BFOqU&3Zl%sl zTAxjV`wb)8)0x6nHOn=_kY)5WUB@VB_(9VYj_*~Nh_H}gTN5&j6lVKY)Z`wfF@#l8 zR(V+z@{ox|PNN^chGmxPK##djJurg~b|;*(MIl;-t}ibySD{t)g9UxrIp)x>X(*^9!k?Sd0{&@e3&Ugu(&bC1nV&q-UFe%-;)mD@O0H$%=E+!PpeAzN}xHaR;r znN(k8=*{hpXSopy-W6g`#?9tLCasj&QtIiBvbtDG^OcevmM-^TYh@JAbP8wdh^7#E z))8Gto6ND%jigs!m6Ps**RsDs#`wX!sxD5X2Jh-KBlS>jWpa8Y(a=R;dLi|D%{I}! zofZ%C)#Y^Rfp6ND8KQGGC<#+kaF0|T}LnM~Mtj-id3Y4oHhGX0x z-hDIkwV50DXH*br7W2hpo;f}x>H2o$ay*>u)T+crG&=wP2=nHL2JJOJ(nEieZRa4mQ{coygUN5RA31ULu|fNKE*FXFua4EQB@3_J=x29AOo!3a19 zyg+At@HBV|2oQi8xE{P0oC{vUdH>S(p4g0O&NE5aHk)?7PNH)UMa z=&#c#OU(^bbv7nCDYZI-Xu4_cgW%nS&XKywK<gFEA7a84~_uyVnvTbxuO4Myp2U~roZ zZoiSiZ8EsMr3SZCgJnOU+bK?TheGU3xRz3rM#hOSKa<#w6XT2LcBNBUi4)Q($Vza0 z-{@3EkQ!?YP>_;cBR?@k*37N$Qj#r|;$FX)mnk)Cr;32x7WS=#24*_i;*}_F4@pj; zc2pD($@r#ztervJW4USrUTYE^}v`{bhg!B#Dx~cC^Hm#-fMu9eo zYZ^*jgtKYby(~JFwo<8^`7USEnoF-m)@|-Igr_r#H~F>F|2u2<$#)0prkvqg?HI0T zlKxe_X!%WCGLry1R$uINmSYUmeP$I}QV#nOsQV$TTuA99Ve>i_@% literal 0 HcmV?d00001 diff --git a/CMakeLists.txt b/Legacy/ws_linux/src/rosaria/CMakeLists.txt similarity index 100% rename from CMakeLists.txt rename to Legacy/ws_linux/src/rosaria/CMakeLists.txt diff --git a/RosAria.cpp b/Legacy/ws_linux/src/rosaria/RosAria.cpp similarity index 99% rename from RosAria.cpp rename to Legacy/ws_linux/src/rosaria/RosAria.cpp index e91d75d..4f9fff5 100644 --- a/RosAria.cpp +++ b/Legacy/ws_linux/src/rosaria/RosAria.cpp @@ -602,10 +602,6 @@ bool RosAriaNode::isCloseToObstacle() range = reading->getRange(); - std_msgs::Float32 soc; - soc.data = (float)(range/1000.0); - state_of_charge_pub.publish(soc); - if ((float)(range/1000.0) < minDist) // Readings are in mm { return true; diff --git a/Legacy/ws_linux/src/rosaria/RosAria.cpp.old b/Legacy/ws_linux/src/rosaria/RosAria.cpp.old new file mode 100644 index 0000000..c1ca524 --- /dev/null +++ b/Legacy/ws_linux/src/rosaria/RosAria.cpp.old @@ -0,0 +1,899 @@ +//#define WATCHDOG 1 +#include +#include +#ifdef ADEPT_PKG +#include +#else +#include +//Aria/Aria.h> +#endif +#include "ros/ros.h" +#include "geometry_msgs/Twist.h" +#include "geometry_msgs/Pose.h" +#include "geometry_msgs/PoseStamped.h" +#include //for sonar data +#include +#include // can optionally publish sonar as new type pointcloud2 +#include "nav_msgs/Odometry.h" +#include "rosaria/BumperState.h" +#include "tf/tf.h" +#include "tf/transform_listener.h" //for tf::getPrefixParam +#include +#include "tf/transform_datatypes.h" +#include +#include +#include "std_msgs/Float64.h" +#include "std_msgs/Float32.h" +#include "std_msgs/Int8.h" +#include "std_msgs/Bool.h" +#include "std_srvs/Empty.h" + +#include + + +// Node that interfaces between ROS and mobile robot base features via ARIA library. +// +// RosAria uses the roscpp client library, see http://www.ros.org/wiki/roscpp for +// information, tutorials and documentation. +class RosAriaNode +{ +public: + RosAriaNode(ros::NodeHandle n); + virtual ~RosAriaNode(); + +public: + int Setup(); + void cmdvel_cb( const geometry_msgs::TwistConstPtr &); + void maxspeed_cb( const geometry_msgs::Vector3ConstPtr &); + + + + //void cmd_enable_motors_cb(); + //void cmd_disable_motors_cb(); + void spin(); + void publish(); + void sonarConnectCb(); + void dynamic_reconfigureCB(rosaria::RosAriaConfig &config, uint32_t level); + void readParameters(); + +protected: + int WATCHDOG; + ros::NodeHandle n; + ros::Publisher pose_pub; + ros::Publisher bumpers_pub; + ros::Publisher sonar_pub; + ros::Publisher sonar_pointcloud2_pub; + ros::Publisher voltage_pub; + + ros::Publisher recharge_state_pub; + std_msgs::Int8 recharge_state; + + ros::Publisher state_of_charge_pub; + + ros::Publisher motors_state_pub; + std_msgs::Bool motors_state; + bool published_motors_state; + + ros::Subscriber cmdvel_sub; + ros::Subscriber maxspeed_sub; + + ros::ServiceServer enable_srv; + ros::ServiceServer disable_srv; + bool enable_motors_cb(std_srvs::Empty::Request& request, std_srvs::Empty::Response& response); + bool disable_motors_cb(std_srvs::Empty::Request& request, std_srvs::Empty::Response& response); + + ros::Publisher stop_motors_pub; + ros::ServiceServer stop_motors_srv; + ros::ServiceServer start_motors_srv; + bool stop_motors_cb(std_srvs::Empty::Request& request, std_srvs::Empty::Response& response); + bool start_motors_cb(std_srvs::Empty::Request& request, std_srvs::Empty::Response& response); + + //Gripper + ros::ServiceServer gripper_open_srv; + ros::ServiceServer gripper_close_srv; + ros::ServiceServer gripper_up_srv; + ros::ServiceServer gripper_down_srv; + + bool gripper_open_cb(std_srvs::Empty::Request& request, std_srvs::Empty::Response& response); + bool gripper_close_cb(std_srvs::Empty::Request& request, std_srvs::Empty::Response& response); + bool gripper_up_cb(std_srvs::Empty::Request& request, std_srvs::Empty::Response& response); + bool gripper_down_cb(std_srvs::Empty::Request& request, std_srvs::Empty::Response& response); + + ros::Time veltime; + + std::string serial_port; + int serial_baud; + + float maxVel; + float maxRot; + + ArRobotConnector *conn; + ArRobot *robot; + ArGripper* gripper; + + nav_msgs::Odometry position; + rosaria::BumperState bumpers; + ArPose pos; + ArFunctorC myPublishCB; + //ArRobot::ChargeState batteryCharge; + + //for odom->base_link transform + tf::TransformBroadcaster odom_broadcaster; + geometry_msgs::TransformStamped odom_trans; + //for resolving tf names. + std::string tf_prefix; + std::string frame_id_odom; + std::string frame_id_base_link; + std::string frame_id_bumper; + std::string frame_id_sonar; + + // flag indicating whether sonar was enabled or disabled on the robot + bool sonar_enabled; + + // enable and publish sonar topics. set to true when first subscriber connects, set to false when last subscriber disconnects. + bool publish_sonar; + bool publish_sonar_pointcloud2; + + // Debug Aria + bool debug_aria; + std::string aria_log_filename; + + // Robot Parameters + int TicksMM, DriftFactor, RevCount; // Odometry Calibration Settings + + // dynamic_reconfigure + dynamic_reconfigure::Server *dynamic_reconfigure_server; + + //Damian zmienna mówiąca czy robot jest zatrzymany awaryjnie + bool stop_robot; + std_msgs::Bool stop_motors_msg; + + ros::Time watchdog; +}; + +void RosAriaNode::readParameters() +{ + // Robot Parameters + robot->lock(); + ros::NodeHandle n_("~"); + if (n_.hasParam("TicksMM")) + { + n_.getParam( "TicksMM", TicksMM); + ROS_INFO("Setting TicksMM from ROS Parameter: %d", TicksMM); + robot->comInt(93, TicksMM); + } + else + { + TicksMM = robot->getOrigRobotConfig()->getTicksMM(); + n_.setParam( "TicksMM", TicksMM); + ROS_INFO("Setting TicksMM from robot controller stored configuration: %d", TicksMM); + } + + if (n_.hasParam("DriftFactor")) + { + n_.getParam( "DriftFactor", DriftFactor); + ROS_INFO("Setting DriftFactor from ROS Parameter: %d", DriftFactor); + robot->comInt(89, DriftFactor); + } + else + { + DriftFactor = robot->getOrigRobotConfig()->getDriftFactor(); + n_.setParam( "DriftFactor", DriftFactor); + ROS_INFO("Setting DriftFactor from robot controller stored configuration: %d", DriftFactor); + } + + if (n_.hasParam("RevCount")) + { + n_.getParam( "RevCount", RevCount); + ROS_INFO("Setting RevCount from ROS Parameter: %d", RevCount); + robot->comInt(88, RevCount); + } + else + { + RevCount = robot->getOrigRobotConfig()->getRevCount(); + n_.setParam( "RevCount", RevCount); + ROS_INFO("Setting RevCount from robot controller stored configuration: %d", RevCount); + } + if (n_.hasParam("WatchDog")) + { + n_.getParam( "WatchDog", WATCHDOG); + ROS_INFO("Setting WatchDog from ROS Parameter: %d", WATCHDOG); + } + else + { + n_.setParam( "WatchDog", WATCHDOG); + ROS_INFO("Setting default WatchDog : %d", WATCHDOG); + } + robot->unlock(); +} + +void RosAriaNode::dynamic_reconfigureCB(rosaria::RosAriaConfig &config, uint32_t level) +{ + // + // Odometry Settings + // + robot->lock(); + if(TicksMM != config.TicksMM and config.TicksMM > 0) + { + ROS_INFO("Setting TicksMM from Dynamic Reconfigure: %d -> %d ", TicksMM, config.TicksMM); + TicksMM = config.TicksMM; + robot->comInt(93, TicksMM); + } + + if(DriftFactor != config.DriftFactor) + { + ROS_INFO("Setting DriftFactor from Dynamic Reconfigure: %d -> %d ", DriftFactor, config.DriftFactor); + DriftFactor = config.DriftFactor; + robot->comInt(89, DriftFactor); + } + + if(RevCount != config.RevCount and config.RevCount > 0) + { + ROS_INFO("Setting RevCount from Dynamic Reconfigure: %d -> %d ", RevCount, config.RevCount); + RevCount = config.RevCount; + robot->comInt(88, RevCount); + } + + // + // Acceleration Parameters + // + int value; + value = config.trans_accel * 1000; + if(value != robot->getTransAccel() and value > 0) + { + ROS_INFO("Setting TransAccel from Dynamic Reconfigure: %d", value); + robot->setTransAccel(value); + } + + value = config.trans_decel * 1000; + if(value != robot->getTransDecel() and value > 0) + { + ROS_INFO("Setting TransDecel from Dynamic Reconfigure: %d", value); + robot->setTransDecel(value); + } + + value = config.lat_accel * 1000; + if(value != robot->getLatAccel() and value > 0) + { + ROS_INFO("Setting LatAccel from Dynamic Reconfigure: %d", value); + if (robot->getAbsoluteMaxLatAccel() > 0 ) + robot->setLatAccel(value); + } + + value = config.lat_decel * 1000; + if(value != robot->getLatDecel() and value > 0) + { + ROS_INFO("Setting LatDecel from Dynamic Reconfigure: %d", value); + if (robot->getAbsoluteMaxLatDecel() > 0 ) + robot->setLatDecel(value); + } + + value = config.rot_accel * 180/M_PI; + if(value != robot->getRotAccel() and value > 0) + { + ROS_INFO("Setting RotAccel from Dynamic Reconfigure: %d", value); + robot->setRotAccel(value); + } + + value = config.rot_decel * 180/M_PI; + if(value != robot->getRotDecel() and value > 0) + { + ROS_INFO("Setting RotDecel from Dynamic Reconfigure: %d", value); + robot->setRotDecel(value); + } + robot->unlock(); +} + +void RosAriaNode::sonarConnectCb() +{ + publish_sonar = (sonar_pub.getNumSubscribers() > 0); + publish_sonar_pointcloud2 = (sonar_pointcloud2_pub.getNumSubscribers() > 0); + robot->lock(); + if (publish_sonar || publish_sonar_pointcloud2) + { + robot->enableSonar(); + sonar_enabled = false; + } + else if(!publish_sonar && !publish_sonar_pointcloud2) + { + robot->disableSonar(); + sonar_enabled = true; + } + robot->unlock(); +} + +RosAriaNode::RosAriaNode(ros::NodeHandle nh) : + myPublishCB(this, &RosAriaNode::publish), serial_port(""), serial_baud(0), + sonar_enabled(false), publish_sonar(false), publish_sonar_pointcloud2(false) +{ + // read in runtime parameters + n = nh; + + // port and baud + n.param( "port", serial_port, std::string("/dev/ttyUSB0") ); + ROS_INFO( "RosAria: using port: [%s]", serial_port.c_str() ); + + n.param("baud", serial_baud, 0); + if(serial_baud != 0) + ROS_INFO("RosAria: using serial port baud rate %d", serial_baud); + + // handle debugging more elegantly + n.param( "debug_aria", debug_aria, false ); // default not to debug + n.param( "aria_log_filename", aria_log_filename, std::string("Aria.log") ); + + // Figure out what frame_id's to use. if a tf_prefix param is specified, + // it will be added to the beginning of the frame_ids. + // + // e.g. rosrun ... _tf_prefix:=MyRobot (or equivalently using s in + // roslaunch files) + // will result in the frame_ids being set to /MyRobot/odom etc, + // rather than /odom. This is useful for Multi Robot Systems. + // See ROS Wiki for further details. + tf_prefix = tf::getPrefixParam(n); + frame_id_odom = tf::resolve(tf_prefix, "odom"); + frame_id_base_link = tf::resolve(tf_prefix, "base_link"); + frame_id_bumper = tf::resolve(tf_prefix, "bumpers_frame"); + frame_id_sonar = tf::resolve(tf_prefix, "sonar_frame"); + + // advertise services for data topics + // second argument to advertise() is queue size. + // other argmuments (optional) are callbacks, or a boolean "latch" flag (whether to send current data to new + // subscribers when they subscribe). + // See ros::NodeHandle API docs. + pose_pub = n.advertise("pose",1000); + bumpers_pub = n.advertise("bumper_state",1000); + sonar_pub = n.advertise("sonar", 50, + boost::bind(&RosAriaNode::sonarConnectCb, this), + boost::bind(&RosAriaNode::sonarConnectCb, this)); + sonar_pointcloud2_pub = n.advertise("sonar_pointcloud2", 50, + boost::bind(&RosAriaNode::sonarConnectCb, this), + boost::bind(&RosAriaNode::sonarConnectCb, this)); + + voltage_pub = n.advertise("battery_voltage", 1000); + recharge_state_pub = n.advertise("battery_recharge_state", 5, true /*latch*/ ); + recharge_state.data = -2; + state_of_charge_pub = n.advertise("battery_state_of_charge", 100); + + motors_state_pub = n.advertise("motors_state", 5, true /*latch*/ ); + stop_motors_pub = n.advertise("stop_motors_state", 5, true /*latch*/ ); + motors_state.data = false; + published_motors_state = false; + + // subscribe to services + cmdvel_sub = n.subscribe( "cmd_vel", 1, (boost::function ) + boost::bind(&RosAriaNode::cmdvel_cb, this, _1 )); + + + maxspeed_sub = n.subscribe( "/PIONIER/distance", 1, (boost::function ) + boost::bind(&RosAriaNode::maxspeed_cb, this, _1 )); + + // advertise enable/disable services + enable_srv = n.advertiseService("enable_motors", &RosAriaNode::enable_motors_cb, this); + disable_srv = n.advertiseService("disable_motors", &RosAriaNode::disable_motors_cb, this); + + //Damian Gripper + gripper_open_srv = n.advertiseService("gripper_open", &RosAriaNode::gripper_open_cb, this); + gripper_close_srv = n.advertiseService("gripper_close", &RosAriaNode::gripper_close_cb, this); + gripper_up_srv = n.advertiseService("gripper_up", &RosAriaNode::gripper_up_cb, this); + gripper_down_srv = n.advertiseService("gripper_down", &RosAriaNode::gripper_down_cb, this); + + //Damian usługi stopu awaryjnego + stop_motors_srv = n.advertiseService("stop_motors", &RosAriaNode::stop_motors_cb, this); + start_motors_srv = n.advertiseService("start_motors", &RosAriaNode::start_motors_cb, this); + stop_robot=false; + stop_motors_msg.data=false; + + maxVel=1.4; + maxRot=1; + + + veltime = ros::Time::now(); + + +} + +RosAriaNode::~RosAriaNode() +{ + // disable motors and sonar. + robot->disableMotors(); + robot->disableSonar(); + + robot->stopRunning(); + robot->waitForRunExit(); + Aria::shutdown(); +} + +int RosAriaNode::Setup() +{ + WATCHDOG=1; + // Note, various objects are allocated here which are never deleted (freed), since Setup() is only supposed to be + // called once per instance, and these objects need to persist until the process terminates. + + robot = new ArRobot(); + gripper = new ArGripper(robot); + ArArgumentBuilder *args = new ArArgumentBuilder(); // never freed + ArArgumentParser *argparser = new ArArgumentParser(args); // Warning never freed + argparser->loadDefaultArguments(); // adds any arguments given in /etc/Aria.args. Useful on robots with unusual serial port or baud rate (e.g. pioneer lx) + + // Now add any parameters given via ros params (see RosAriaNode constructor): + + // if serial port parameter contains a ':' character, then interpret it as hostname:tcpport + // for wireless serial connection. Otherwise, interpret it as a serial port name. + size_t colon_pos = serial_port.find(":"); + if (colon_pos != std::string::npos) + { + args->add("-remoteHost"); // pass robot's hostname/IP address to Aria + args->add(serial_port.substr(0, colon_pos).c_str()); + args->add("-remoteRobotTcpPort"); // pass robot's TCP port to Aria + args->add(serial_port.substr(colon_pos+1).c_str()); + } + else + { + args->add("-robotPort"); // pass robot's serial port to Aria + args->add(serial_port.c_str()); + } + + // if a baud rate was specified in baud parameter + if(serial_baud != 0) + { + args->add("-robotBaud"); + char tmp[100]; + snprintf(tmp, 100, "%d", serial_baud); + args->add(tmp); + } + + if( debug_aria ) + { + // turn on all ARIA debugging + args->add("-robotLogPacketsReceived"); // log received packets + args->add("-robotLogPacketsSent"); // log sent packets + args->add("-robotLogVelocitiesReceived"); // log received velocities + args->add("-robotLogMovementSent"); + args->add("-robotLogMovementReceived"); + ArLog::init(ArLog::File, ArLog::Verbose, aria_log_filename.c_str(), true); + } + + + // Connect to the robot + conn = new ArRobotConnector(argparser, robot); // warning never freed + if (!conn->connectRobot()) { + ROS_ERROR("RosAria: ARIA could not connect to robot! (Check ~port parameter is correct, and permissions on port device.)"); + return 1; + } + + // causes ARIA to load various robot-specific hardware parameters from the robot parameter file in /usr/local/Aria/params + if(!Aria::parseArgs()) + { + ROS_ERROR("RosAria: ARIA error parsing ARIA startup parameters!"); + return 1; + } + + readParameters(); + + // Start dynamic_reconfigure server + dynamic_reconfigure_server = new dynamic_reconfigure::Server; + + // Setup Parameter Minimums + rosaria::RosAriaConfig dynConf_min; + dynConf_min.trans_accel = robot->getAbsoluteMaxTransAccel() / 1000; + dynConf_min.trans_decel = robot->getAbsoluteMaxTransDecel() / 1000; + // TODO: Fix rqt dynamic_reconfigure gui to handle empty intervals + // Until then, set unit length interval. + dynConf_min.lat_accel = ((robot->getAbsoluteMaxLatAccel() > 0.0) ? robot->getAbsoluteMaxLatAccel() : 0.1) / 1000; + dynConf_min.lat_decel = ((robot->getAbsoluteMaxLatDecel() > 0.0) ? robot->getAbsoluteMaxLatDecel() : 0.1) / 1000; + dynConf_min.rot_accel = robot->getAbsoluteMaxRotAccel() * M_PI/180; + dynConf_min.rot_decel = robot->getAbsoluteMaxRotDecel() * M_PI/180; + + // I'm setting these upper bounds relitivly arbitrarily, feel free to increase them. + dynConf_min.TicksMM = 10; + dynConf_min.DriftFactor = -200; + dynConf_min.RevCount = -32760; + + dynamic_reconfigure_server->setConfigMin(dynConf_min); + + + rosaria::RosAriaConfig dynConf_max; + dynConf_max.trans_accel = robot->getAbsoluteMaxTransAccel() / 1000; + dynConf_max.trans_decel = robot->getAbsoluteMaxTransDecel() / 1000; + // TODO: Fix rqt dynamic_reconfigure gui to handle empty intervals + // Until then, set unit length interval. + dynConf_max.lat_accel = ((robot->getAbsoluteMaxLatAccel() > 0.0) ? robot->getAbsoluteMaxLatAccel() : 0.1) / 1000; + dynConf_max.lat_decel = ((robot->getAbsoluteMaxLatDecel() > 0.0) ? robot->getAbsoluteMaxLatDecel() : 0.1) / 1000; + dynConf_max.rot_accel = robot->getAbsoluteMaxRotAccel() * M_PI/180; + dynConf_max.rot_decel = robot->getAbsoluteMaxRotDecel() * M_PI/180; + + // I'm setting these upper bounds relitivly arbitrarily, feel free to increase them. + dynConf_max.TicksMM = 200; + dynConf_max.DriftFactor = 200; + dynConf_max.RevCount = 32760; + + dynamic_reconfigure_server->setConfigMax(dynConf_max); + + + rosaria::RosAriaConfig dynConf_default; + dynConf_default.trans_accel = robot->getTransAccel() / 1000; + dynConf_default.trans_decel = robot->getTransDecel() / 1000; + dynConf_default.lat_accel = robot->getLatAccel() / 1000; + dynConf_default.lat_decel = robot->getLatDecel() / 1000; + dynConf_default.rot_accel = robot->getRotAccel() * M_PI/180; + dynConf_default.rot_decel = robot->getRotDecel() * M_PI/180; + + dynConf_default.TicksMM = TicksMM; + dynConf_default.DriftFactor = DriftFactor; + dynConf_default.RevCount = RevCount; + + dynamic_reconfigure_server->setConfigDefault(dynConf_max); + + dynamic_reconfigure_server->setCallback(boost::bind(&RosAriaNode::dynamic_reconfigureCB, this, _1, _2)); + + // Enable the motors + robot->enableMotors(); + + // disable sonars on startup + robot->disableSonar(); + + // callback will be called by ArRobot background processing thread for every SIP data packet received from robot + robot->addSensorInterpTask("ROSPublishingTask", 100, &myPublishCB); + + // Initialize bumpers with robot number of bumpers + bumpers.front_bumpers.resize(robot->getNumFrontBumpers()); + bumpers.rear_bumpers.resize(robot->getNumRearBumpers()); + + // Run ArRobot background processing thread + robot->runAsync(true); + return 0; +} + +void RosAriaNode::spin() +{ + ros::spin(); +} + +void RosAriaNode::publish() +{ + // Note, this is called via SensorInterpTask callback (myPublishCB, named "ROSPublishingTask"). ArRobot object 'robot' sholud not be locked or unlocked. + pos = robot->getPose(); + tf::poseTFToMsg(tf::Transform(tf::createQuaternionFromYaw(pos.getTh()*M_PI/180), tf::Vector3(pos.getX()/1000, + pos.getY()/1000, 0)), position.pose.pose); //Aria returns pose in mm. + position.twist.twist.linear.x = robot->getVel()/1000; //Aria returns velocity in mm/s. + position.twist.twist.linear.y = robot->getLatVel()/1000.0; + position.twist.twist.angular.z = robot->getRotVel()*M_PI/180; + + position.header.frame_id = frame_id_odom; + position.child_frame_id = frame_id_base_link; + position.header.stamp = ros::Time::now(); + pose_pub.publish(position); + + ROS_DEBUG("RosAria: publish: (time %f) pose x: %f, y: %f, angle: %f; linear vel x: %f, y: %f; angular vel z: %f", + position.header.stamp.toSec(), + (double)position.pose.pose.position.x, + (double)position.pose.pose.position.y, + (double)position.pose.pose.orientation.w, + (double) position.twist.twist.linear.x, + (double) position.twist.twist.linear.y, + (double) position.twist.twist.angular.z + ); + + + // publishing transform odom->base_link + odom_trans.header.stamp = ros::Time::now(); + odom_trans.header.frame_id = frame_id_odom; + odom_trans.child_frame_id = frame_id_base_link; + + odom_trans.transform.translation.x = pos.getX()/1000; + odom_trans.transform.translation.y = pos.getY()/1000; + odom_trans.transform.translation.z = 0.0; + odom_trans.transform.rotation = tf::createQuaternionMsgFromYaw(pos.getTh()*M_PI/180); + + odom_broadcaster.sendTransform(odom_trans); + + // getStallValue returns 2 bytes with stall bit and bumper bits, packed as (00 00 FrontBumpers RearBumpers) + int stall = robot->getStallValue(); + unsigned char front_bumpers = (unsigned char)(stall >> 8); + unsigned char rear_bumpers = (unsigned char)(stall); + + bumpers.header.frame_id = frame_id_bumper; + bumpers.header.stamp = ros::Time::now(); + + std::stringstream bumper_info(std::stringstream::out); + // Bit 0 is for stall, next bits are for bumpers (leftmost is LSB) + for (unsigned int i=0; igetNumFrontBumpers(); i++) + { + bumpers.front_bumpers[i] = (front_bumpers & (1 << (i+1))) == 0 ? 0 : 1; + bumper_info << " " << (front_bumpers & (1 << (i+1))); + } + ROS_DEBUG("RosAria: Front bumpers:%s", bumper_info.str().c_str()); + + bumper_info.str(""); + // Rear bumpers have reverse order (rightmost is LSB) + unsigned int numRearBumpers = robot->getNumRearBumpers(); + for (unsigned int i=0; igetRealBatteryVoltageNow(); + voltage_pub.publish(batteryVoltage); + + if(robot->haveStateOfCharge()) + { + std_msgs::Float32 soc; + soc.data = robot->getStateOfCharge()/100.0; + state_of_charge_pub.publish(soc); + } + + // publish recharge state if changed + char s = robot->getChargeState(); + if(s != recharge_state.data) + { + ROS_INFO("RosAria: publishing new recharge state %d.", s); + recharge_state.data = s; + recharge_state_pub.publish(recharge_state); + } + + // publish motors state if changed + bool e = robot->areMotorsEnabled(); + if(e != motors_state.data || !published_motors_state) + { + ROS_INFO("RosAria: publishing stop motors state %d.", e); + motors_state.data = e; + motors_state_pub.publish(motors_state); + published_motors_state = true; + } + + //Publikuje czy zatrzymane silniki + if(stop_robot) + { + ROS_INFO("RosAria: publishing new motors state %d.", stop_motors_msg.data); + stop_motors_pub.publish(stop_motors_msg); + stop_robot = false; + } + + // Publish sonar information, if enabled. + if (publish_sonar || publish_sonar_pointcloud2) + { + sensor_msgs::PointCloud cloud; //sonar readings. + cloud.header.stamp = position.header.stamp; //copy time. + // sonar sensors relative to base_link + cloud.header.frame_id = frame_id_sonar; + + + std::stringstream sonar_debug_info; // Log debugging info + sonar_debug_info << "Sonar readings: "; + + for (int i = 0; i < robot->getNumSonar(); i++) { + ArSensorReading* reading = NULL; + reading = robot->getSonarReading(i); + if(!reading) { + ROS_WARN("RosAria: Did not receive a sonar reading."); + continue; + } + + // getRange() will return an integer between 0 and 5000 (5m) + sonar_debug_info << reading->getRange() << " "; + + // local (x,y). Appears to be from the centre of the robot, since values may + // exceed 5000. This is good, since it means we only need 1 transform. + // x & y seem to be swapped though, i.e. if the robot is driving north + // x is north/south and y is east/west. + // + //ArPose sensor = reading->getSensorPosition(); //position of sensor. + // sonar_debug_info << "(" << reading->getLocalX() + // << ", " << reading->getLocalY() + // << ") from (" << sensor.getX() << ", " + // << sensor.getY() << ") ;; " ; + + //add sonar readings (robot-local coordinate frame) to cloud + geometry_msgs::Point32 p; + p.x = reading->getLocalX() / 1000.0; + p.y = reading->getLocalY() / 1000.0; + p.z = 0.0; + cloud.points.push_back(p); + } + ROS_DEBUG_STREAM(sonar_debug_info.str()); + + // publish topic(s) + + if(publish_sonar_pointcloud2) + { + sensor_msgs::PointCloud2 cloud2; + if(!sensor_msgs::convertPointCloudToPointCloud2(cloud, cloud2)) + { + ROS_WARN("Error converting sonar point cloud message to point_cloud2 type before publishing! Not publishing this time."); + } + else + { + sonar_pointcloud2_pub.publish(cloud2); + } + } + + if(publish_sonar) + { + sonar_pub.publish(cloud); + } + } // end if sonar_enabled + + if(watchdog.toSec()+WATCHDOGcomInt(ArCommands::ESTOP,0); + robot->setVel(0); + if(robot->hasLatVel()) + robot->setLatVel(0); + robot->setRotVel(0); + // ROS_INFO("WATCHDOG %d", WATCHDOG); + } +} + +bool RosAriaNode::enable_motors_cb(std_srvs::Empty::Request& request, std_srvs::Empty::Response& response) +{ + ROS_INFO("RosAria: Enable motors request."); + robot->lock(); + if(robot->isEStopPressed()) + ROS_WARN("RosAria: Warning: Enable motors requested, but robot also has E-Stop button pressed. Motors will not enable."); + robot->enableMotors(); + robot->unlock(); + // todo could wait and see if motors do become enabled, and send a response with an error flag if not + return true; +} + +bool RosAriaNode::disable_motors_cb(std_srvs::Empty::Request& request, std_srvs::Empty::Response& response) +{ + ROS_INFO("RosAria: Disable motors request."); + robot->lock(); + robot->disableMotors(); + robot->unlock(); + // todo could wait and see if motors do become disabled, and send a response with an error flag if not + return true; +} + +//Damian Metody odpowiedzialne za awaryjne ztrzymanie silników +bool RosAriaNode::start_motors_cb(std_srvs::Empty::Request& request, std_srvs::Empty::Response& response) +{ + stop_robot=true; + stop_motors_msg.data=false; + + ROS_INFO("RosAria: Disable motors brakes."); + robot->lock(); + if(robot->isEStopPressed()) + ROS_WARN("RosAria: Warning: Enable motors requested, but robot also has E-Stop button pressed. Motors will not enable."); + robot->unlock(); + return true; +} + +bool RosAriaNode::stop_motors_cb(std_srvs::Empty::Request& request, std_srvs::Empty::Response& response) +{ + robot->lock(); + stop_robot=true; + stop_motors_msg.data=true; + //Zatrzymuje robota + robot->setVel(0); + if(robot->hasLatVel()) + robot->setLatVel(0); + robot->setRotVel(0); + + robot->comInt(ArCommands::ESTOP,0); + ROS_INFO("RosAria: Enable motors brakes."); + robot->unlock(); + return true; +} +bool RosAriaNode::gripper_open_cb(std_srvs::Empty::Request& request, std_srvs::Empty::Response& response) +{ + robot->lock(); + gripper->gripOpen(); + ROS_INFO("RosAria: Gripper opening."); + robot->unlock(); + return true; +} + +bool RosAriaNode::gripper_close_cb(std_srvs::Empty::Request& request, std_srvs::Empty::Response& response) +{ + robot->lock(); + gripper->gripClose(); + ROS_INFO("RosAria: Gripper closing."); + robot->unlock(); + return true; +} + +bool RosAriaNode::gripper_up_cb(std_srvs::Empty::Request& request, std_srvs::Empty::Response& response) +{ + robot->lock(); + gripper->liftUp(); + ROS_INFO("RosAria: Gripper moving up"); + robot->unlock(); + return true; +} + +bool RosAriaNode::gripper_down_cb(std_srvs::Empty::Request& request, std_srvs::Empty::Response& response) +{ + robot->lock(); + gripper->liftDown(); + ROS_INFO("RosAria: Gripper moving down."); + robot->unlock(); + return true; +} + + +void RosAriaNode::cmdvel_cb( const geometry_msgs::TwistConstPtr &msg) +{ + veltime = ros::Time::now(); + watchdog= ros::Time::now(); + if(stop_motors_msg.data) + { + ROS_INFO( "new speed: [%0.2f,%0.2f](%0.3f) but robot is stop", msg->linear.x*1e3, msg->angular.z, veltime.toSec() ); + return; + } + ROS_INFO( "new speed: [%0.2f,%0.2f](%0.3f)", msg->linear.x, msg->angular.z, veltime.toSec() ); + + ROS_INFO( "max speed: [%0.2f,%0.2f](%0.3f)", maxVel, maxRot, veltime.toSec() ); + float x,y,z; + x=msg->linear.x; + y=msg->linear.y; + z=msg->angular.z; + + if (fabs(msg->linear.x)>maxVel) + { + ROS_INFO( "angular velocity is too large"); + if(msg->linear.x<0) x=-maxVel; + if(msg->linear.x>0) x=maxVel; + } + if (fabs(msg->linear.y)>maxVel) + { + ROS_INFO( "angular velocity is too large"); + if(msg->linear.y<0) y=-maxVel; + if(msg->linear.y>0) y=maxVel; + } + if (fabs(msg->angular.z)>maxRot) + { + ROS_INFO( "rotate velocity is too large"); + if(msg->angular.z<0) z=-maxRot; + if(msg->angular.z>0) z=maxRot; + } + + + robot->lock(); + robot->setVel(x*1e3); + if(robot->hasLatVel()) + robot->setLatVel(y*1e3); + robot->setRotVel(z*180/M_PI); + robot->unlock(); + ROS_DEBUG("RosAria: sent vels to to aria (time %f): x vel %f mm/s, y vel %f mm/s, ang vel %f deg/s", veltime.toSec(), + (double) x * 1e3, (double) y * 1.3, (double) z * 180/M_PI); +} + +void RosAriaNode::maxspeed_cb( const geometry_msgs::Vector3ConstPtr &msg) +{ + veltime = ros::Time::now(); + maxVel=msg->y; + maxRot=msg->z; + ROS_INFO( "new max speed: [%0.2f,%0.2f]", msg->y, msg->z); +} + +int main( int argc, char** argv ) +{ + ros::init(argc,argv, "RosAria"); + ros::NodeHandle n(std::string("~")); + Aria::init(); + + RosAriaNode *node = new RosAriaNode(n); + + if( node->Setup() != 0 ) + { + ROS_FATAL( "RosAria: ROS node setup failed... \n" ); + return -1; + } + + node->spin(); + + delete node; + + ROS_INFO( "RosAria: Quitting... \n" ); + return 0; + +} diff --git a/Legacy/ws_linux/src/rosaria/RosAria.cpp.old.save b/Legacy/ws_linux/src/rosaria/RosAria.cpp.old.save new file mode 100644 index 0000000..216888b --- /dev/null +++ b/Legacy/ws_linux/src/rosaria/RosAria.cpp.old.save @@ -0,0 +1,900 @@ + +//#define WATCHDOG 1 +#include +#include +#ifdef ADEPT_PKG +#include +#else +#include +//Aria/Aria.h> +#endif +#include "ros/ros.h" +#include "geometry_msgs/Twist.h" +#include "geometry_msgs/Pose.h" +#include "geometry_msgs/PoseStamped.h" +#include //for sonar data +#include +#include // can optionally publish sonar as new type pointcloud2 +#include "nav_msgs/Odometry.h" +#include "rosaria/BumperState.h" +#include "tf/tf.h" +#include "tf/transform_listener.h" //for tf::getPrefixParam +#include +#include "tf/transform_datatypes.h" +#include +#include +#include "std_msgs/Float64.h" +#include "std_msgs/Float32.h" +#include "std_msgs/Int8.h" +#include "std_msgs/Bool.h" +#include "std_srvs/Empty.h" + +#include + + +// Node that interfaces between ROS and mobile robot base features via ARIA library. +// +// RosAria uses the roscpp client library, see http://www.ros.org/wiki/roscpp for +// information, tutorials and documentation. +class RosAriaNode +{ +public: + RosAriaNode(ros::NodeHandle n); + virtual ~RosAriaNode(); + +public: + int Setup(); + void cmdvel_cb( const geometry_msgs::TwistConstPtr &); + void maxspeed_cb( const geometry_msgs::Vector3ConstPtr &); + + + + //void cmd_enable_motors_cb(); + //void cmd_disable_motors_cb(); + void spin(); + void publish(); + void sonarConnectCb(); + void dynamic_reconfigureCB(rosaria::RosAriaConfig &config, uint32_t level); + void readParameters(); + +protected: + int WATCHDOG; + ros::NodeHandle n; + ros::Publisher pose_pub; + ros::Publisher bumpers_pub; + ros::Publisher sonar_pub; + ros::Publisher sonar_pointcloud2_pub; + ros::Publisher voltage_pub; + + ros::Publisher recharge_state_pub; + std_msgs::Int8 recharge_state; + + ros::Publisher state_of_charge_pub; + + ros::Publisher motors_state_pub; + std_msgs::Bool motors_state; + bool published_motors_state; + + ros::Subscriber cmdvel_sub; + ros::Subscriber maxspeed_sub; + + ros::ServiceServer enable_srv; + ros::ServiceServer disable_srv; + bool enable_motors_cb(std_srvs::Empty::Request& request, std_srvs::Empty::Response& response); + bool disable_motors_cb(std_srvs::Empty::Request& request, std_srvs::Empty::Response& response); + + ros::Publisher stop_motors_pub; + ros::ServiceServer stop_motors_srv; + ros::ServiceServer start_motors_srv; + bool stop_motors_cb(std_srvs::Empty::Request& request, std_srvs::Empty::Response& response); + bool start_motors_cb(std_srvs::Empty::Request& request, std_srvs::Empty::Response& response); + + //Gripper + ros::ServiceServer gripper_open_srv; + ros::ServiceServer gripper_close_srv; + ros::ServiceServer gripper_up_srv; + ros::ServiceServer gripper_down_srv; + + bool gripper_open_cb(std_srvs::Empty::Request& request, std_srvs::Empty::Response& response); + bool gripper_close_cb(std_srvs::Empty::Request& request, std_srvs::Empty::Response& response); + bool gripper_up_cb(std_srvs::Empty::Request& request, std_srvs::Empty::Response& response); + bool gripper_down_cb(std_srvs::Empty::Request& request, std_srvs::Empty::Response& response); + + ros::Time veltime; + + std::string serial_port; + int serial_baud; + + float maxVel; + float maxRot; + + ArRobotConnector *conn; + ArRobot *robot; + ArGripper* gripper; + + nav_msgs::Odometry position; + rosaria::BumperState bumpers; + ArPose pos; + ArFunctorC myPublishCB; + //ArRobot::ChargeState batteryCharge; + + //for odom->base_link transform + tf::TransformBroadcaster odom_broadcaster; + geometry_msgs::TransformStamped odom_trans; + //for resolving tf names. + std::string tf_prefix; + std::string frame_id_odom; + std::string frame_id_base_link; + std::string frame_id_bumper; + std::string frame_id_sonar; + + // flag indicating whether sonar was enabled or disabled on the robot + bool sonar_enabled; + + // enable and publish sonar topics. set to true when first subscriber connects, set to false when last subscriber disconnects. + bool publish_sonar; + bool publish_sonar_pointcloud2; + + // Debug Aria + bool debug_aria; + std::string aria_log_filename; + + // Robot Parameters + int TicksMM, DriftFactor, RevCount; // Odometry Calibration Settings + + // dynamic_reconfigure + dynamic_reconfigure::Server *dynamic_reconfigure_server; + + //Damian zmienna mówiąca czy robot jest zatrzymany awaryjnie + bool stop_robot; + std_msgs::Bool stop_motors_msg; + + ros::Time watchdog; +}; + +void RosAriaNode::readParameters() +{ + // Robot Parameters + robot->lock(); + ros::NodeHandle n_("~"); + if (n_.hasParam("TicksMM")) + { + n_.getParam( "TicksMM", TicksMM); + ROS_INFO("Setting TicksMM from ROS Parameter: %d", TicksMM); + robot->comInt(93, TicksMM); + } + else + { + TicksMM = robot->getOrigRobotConfig()->getTicksMM(); + n_.setParam( "TicksMM", TicksMM); + ROS_INFO("Setting TicksMM from robot controller stored configuration: %d", TicksMM); + } + + if (n_.hasParam("DriftFactor")) + { + n_.getParam( "DriftFactor", DriftFactor); + ROS_INFO("Setting DriftFactor from ROS Parameter: %d", DriftFactor); + robot->comInt(89, DriftFactor); + } + else + { + DriftFactor = robot->getOrigRobotConfig()->getDriftFactor(); + n_.setParam( "DriftFactor", DriftFactor); + ROS_INFO("Setting DriftFactor from robot controller stored configuration: %d", DriftFactor); + } + + if (n_.hasParam("RevCount")) + { + n_.getParam( "RevCount", RevCount); + ROS_INFO("Setting RevCount from ROS Parameter: %d", RevCount); + robot->comInt(88, RevCount); + } + else + { + RevCount = robot->getOrigRobotConfig()->getRevCount(); + n_.setParam( "RevCount", RevCount); + ROS_INFO("Setting RevCount from robot controller stored configuration: %d", RevCount); + } + if (n_.hasParam("WatchDog")) + { + n_.getParam( "WatchDog", WATCHDOG); + ROS_INFO("Setting WatchDog from ROS Parameter: %d", WATCHDOG); + } + else + { + n_.setParam( "WatchDog", WATCHDOG); + ROS_INFO("Setting default WatchDog : %d", WATCHDOG); + } + robot->unlock(); +} + +void RosAriaNode::dynamic_reconfigureCB(rosaria::RosAriaConfig &config, uint32_t level) +{ + // + // Odometry Settings + // + robot->lock(); + if(TicksMM != config.TicksMM and config.TicksMM > 0) + { + ROS_INFO("Setting TicksMM from Dynamic Reconfigure: %d -> %d ", TicksMM, config.TicksMM); + TicksMM = config.TicksMM; + robot->comInt(93, TicksMM); + } + + if(DriftFactor != config.DriftFactor) + { + ROS_INFO("Setting DriftFactor from Dynamic Reconfigure: %d -> %d ", DriftFactor, config.DriftFactor); + DriftFactor = config.DriftFactor; + robot->comInt(89, DriftFactor); + } + + if(RevCount != config.RevCount and config.RevCount > 0) + { + ROS_INFO("Setting RevCount from Dynamic Reconfigure: %d -> %d ", RevCount, config.RevCount); + RevCount = config.RevCount; + robot->comInt(88, RevCount); + } + + // + // Acceleration Parameters + // + int value; + value = config.trans_accel * 1000; + if(value != robot->getTransAccel() and value > 0) + { + ROS_INFO("Setting TransAccel from Dynamic Reconfigure: %d", value); + robot->setTransAccel(value); + } + + value = config.trans_decel * 1000; + if(value != robot->getTransDecel() and value > 0) + { + ROS_INFO("Setting TransDecel from Dynamic Reconfigure: %d", value); + robot->setTransDecel(value); + } + + value = config.lat_accel * 1000; + if(value != robot->getLatAccel() and value > 0) + { + ROS_INFO("Setting LatAccel from Dynamic Reconfigure: %d", value); + if (robot->getAbsoluteMaxLatAccel() > 0 ) + robot->setLatAccel(value); + } + + value = config.lat_decel * 1000; + if(value != robot->getLatDecel() and value > 0) + { + ROS_INFO("Setting LatDecel from Dynamic Reconfigure: %d", value); + if (robot->getAbsoluteMaxLatDecel() > 0 ) + robot->setLatDecel(value); + } + + value = config.rot_accel * 180/M_PI; + if(value != robot->getRotAccel() and value > 0) + { + ROS_INFO("Setting RotAccel from Dynamic Reconfigure: %d", value); + robot->setRotAccel(value); + } + + value = config.rot_decel * 180/M_PI; + if(value != robot->getRotDecel() and value > 0) + { + ROS_INFO("Setting RotDecel from Dynamic Reconfigure: %d", value); + robot->setRotDecel(value); + } + robot->unlock(); +} + +void RosAriaNode::sonarConnectCb() +{ + publish_sonar = (sonar_pub.getNumSubscribers() > 0); + publish_sonar_pointcloud2 = (sonar_pointcloud2_pub.getNumSubscribers() > 0); + robot->lock(); + if (publish_sonar || publish_sonar_pointcloud2) + { + robot->enableSonar(); + sonar_enabled = false; + } + else if(!publish_sonar && !publish_sonar_pointcloud2) + { + robot->disableSonar(); + sonar_enabled = true; + } + robot->unlock(); +} + +RosAriaNode::RosAriaNode(ros::NodeHandle nh) : + myPublishCB(this, &RosAriaNode::publish), serial_port(""), serial_baud(0), + sonar_enabled(false), publish_sonar(false), publish_sonar_pointcloud2(false) +{ + // read in runtime parameters + n = nh; + + // port and baud + n.param( "port", serial_port, std::string("/dev/ttyUSB0") ); + ROS_INFO( "RosAria: using port: [%s]", serial_port.c_str() ); + + n.param("baud", serial_baud, 0); + if(serial_baud != 0) + ROS_INFO("RosAria: using serial port baud rate %d", serial_baud); + + // handle debugging more elegantly + n.param( "debug_aria", debug_aria, false ); // default not to debug + n.param( "aria_log_filename", aria_log_filename, std::string("Aria.log") ); + + // Figure out what frame_id's to use. if a tf_prefix param is specified, + // it will be added to the beginning of the frame_ids. + // + // e.g. rosrun ... _tf_prefix:=MyRobot (or equivalently using s in + // roslaunch files) + // will result in the frame_ids being set to /MyRobot/odom etc, + // rather than /odom. This is useful for Multi Robot Systems. + // See ROS Wiki for further details. + tf_prefix = tf::getPrefixParam(n); + frame_id_odom = tf::resolve(tf_prefix, "odom"); + frame_id_base_link = tf::resolve(tf_prefix, "base_link"); + frame_id_bumper = tf::resolve(tf_prefix, "bumpers_frame"); + frame_id_sonar = tf::resolve(tf_prefix, "sonar_frame"); + + // advertise services for data topics + // second argument to advertise() is queue size. + // other argmuments (optional) are callbacks, or a boolean "latch" flag (whether to send current data to new + // subscribers when they subscribe). + // See ros::NodeHandle API docs. + pose_pub = n.advertise("pose",1000); + bumpers_pub = n.advertise("bumper_state",1000); + sonar_pub = n.advertise("sonar", 50, + boost::bind(&RosAriaNode::sonarConnectCb, this), + boost::bind(&RosAriaNode::sonarConnectCb, this)); + sonar_pointcloud2_pub = n.advertise("sonar_pointcloud2", 50, + boost::bind(&RosAriaNode::sonarConnectCb, this), + boost::bind(&RosAriaNode::sonarConnectCb, this)); + + voltage_pub = n.advertise("battery_voltage", 1000); + recharge_state_pub = n.advertise("battery_recharge_state", 5, true /*latch*/ ); + recharge_state.data = -2; + state_of_charge_pub = n.advertise("battery_state_of_charge", 100); + + motors_state_pub = n.advertise("motors_state", 5, true /*latch*/ ); + stop_motors_pub = n.advertise("stop_motors_state", 5, true /*latch*/ ); + motors_state.data = false; + published_motors_state = false; + + // subscribe to services + cmdvel_sub = n.subscribe( "cmd_vel", 1, (boost::function ) + boost::bind(&RosAriaNode::cmdvel_cb, this, _1 )); + + + maxspeed_sub = n.subscribe( "/PIONIER/distance", 1, (boost::function ) + boost::bind(&RosAriaNode::maxspeed_cb, this, _1 )); + + // advertise enable/disable services + enable_srv = n.advertiseService("enable_motors", &RosAriaNode::enable_motors_cb, this); + disable_srv = n.advertiseService("disable_motors", &RosAriaNode::disable_motors_cb, this); + + //Damian Gripper + gripper_open_srv = n.advertiseService("gripper_open", &RosAriaNode::gripper_open_cb, this); + gripper_close_srv = n.advertiseService("gripper_close", &RosAriaNode::gripper_close_cb, this); + gripper_up_srv = n.advertiseService("gripper_up", &RosAriaNode::gripper_up_cb, this); + gripper_down_srv = n.advertiseService("gripper_down", &RosAriaNode::gripper_down_cb, this); + + //Damian usługi stopu awaryjnego + stop_motors_srv = n.advertiseService("stop_motors", &RosAriaNode::stop_motors_cb, this); + start_motors_srv = n.advertiseService("start_motors", &RosAriaNode::start_motors_cb, this); + stop_robot=false; + stop_motors_msg.data=false; + + maxVel=1.4; + maxRot=1; + + + veltime = ros::Time::now(); + + +} + +RosAriaNode::~RosAriaNode() +{ + // disable motors and sonar. + robot->disableMotors(); + robot->disableSonar(); + + robot->stopRunning(); + robot->waitForRunExit(); + Aria::shutdown(); +} + +int RosAriaNode::Setup() +{ + WATCHDOG=1; + // Note, various objects are allocated here which are never deleted (freed), since Setup() is only supposed to be + // called once per instance, and these objects need to persist until the process terminates. + + robot = new ArRobot(); + gripper = new ArGripper(robot); + ArArgumentBuilder *args = new ArArgumentBuilder(); // never freed + ArArgumentParser *argparser = new ArArgumentParser(args); // Warning never freed + argparser->loadDefaultArguments(); // adds any arguments given in /etc/Aria.args. Useful on robots with unusual serial port or baud rate (e.g. pioneer lx) + + // Now add any parameters given via ros params (see RosAriaNode constructor): + + // if serial port parameter contains a ':' character, then interpret it as hostname:tcpport + // for wireless serial connection. Otherwise, interpret it as a serial port name. + size_t colon_pos = serial_port.find(":"); + if (colon_pos != std::string::npos) + { + args->add("-remoteHost"); // pass robot's hostname/IP address to Aria + args->add(serial_port.substr(0, colon_pos).c_str()); + args->add("-remoteRobotTcpPort"); // pass robot's TCP port to Aria + args->add(serial_port.substr(colon_pos+1).c_str()); + } + else + { + args->add("-robotPort"); // pass robot's serial port to Aria + args->add(serial_port.c_str()); + } + + // if a baud rate was specified in baud parameter + if(serial_baud != 0) + { + args->add("-robotBaud"); + char tmp[100]; + snprintf(tmp, 100, "%d", serial_baud); + args->add(tmp); + } + + if( debug_aria ) + { + // turn on all ARIA debugging + args->add("-robotLogPacketsReceived"); // log received packets + args->add("-robotLogPacketsSent"); // log sent packets + args->add("-robotLogVelocitiesReceived"); // log received velocities + args->add("-robotLogMovementSent"); + args->add("-robotLogMovementReceived"); + ArLog::init(ArLog::File, ArLog::Verbose, aria_log_filename.c_str(), true); + } + + + // Connect to the robot + conn = new ArRobotConnector(argparser, robot); // warning never freed + if (!conn->connectRobot()) { + ROS_ERROR("RosAria: ARIA could not connect to robot! (Check ~port parameter is correct, and permissions on port device.)"); + return 1; + } + + // causes ARIA to load various robot-specific hardware parameters from the robot parameter file in /usr/local/Aria/params + if(!Aria::parseArgs()) + { + ROS_ERROR("RosAria: ARIA error parsing ARIA startup parameters!"); + return 1; + } + + readParameters(); + + // Start dynamic_reconfigure server + dynamic_reconfigure_server = new dynamic_reconfigure::Server; + + // Setup Parameter Minimums + rosaria::RosAriaConfig dynConf_min; + dynConf_min.trans_accel = robot->getAbsoluteMaxTransAccel() / 1000; + dynConf_min.trans_decel = robot->getAbsoluteMaxTransDecel() / 1000; + // TODO: Fix rqt dynamic_reconfigure gui to handle empty intervals + // Until then, set unit length interval. + dynConf_min.lat_accel = ((robot->getAbsoluteMaxLatAccel() > 0.0) ? robot->getAbsoluteMaxLatAccel() : 0.1) / 1000; + dynConf_min.lat_decel = ((robot->getAbsoluteMaxLatDecel() > 0.0) ? robot->getAbsoluteMaxLatDecel() : 0.1) / 1000; + dynConf_min.rot_accel = robot->getAbsoluteMaxRotAccel() * M_PI/180; + dynConf_min.rot_decel = robot->getAbsoluteMaxRotDecel() * M_PI/180; + + // I'm setting these upper bounds relitivly arbitrarily, feel free to increase them. + dynConf_min.TicksMM = 10; + dynConf_min.DriftFactor = -200; + dynConf_min.RevCount = -32760; + + dynamic_reconfigure_server->setConfigMin(dynConf_min); + + + rosaria::RosAriaConfig dynConf_max; + dynConf_max.trans_accel = robot->getAbsoluteMaxTransAccel() / 1000; + dynConf_max.trans_decel = robot->getAbsoluteMaxTransDecel() / 1000; + // TODO: Fix rqt dynamic_reconfigure gui to handle empty intervals + // Until then, set unit length interval. + dynConf_max.lat_accel = ((robot->getAbsoluteMaxLatAccel() > 0.0) ? robot->getAbsoluteMaxLatAccel() : 0.1) / 1000; + dynConf_max.lat_decel = ((robot->getAbsoluteMaxLatDecel() > 0.0) ? robot->getAbsoluteMaxLatDecel() : 0.1) / 1000; + dynConf_max.rot_accel = robot->getAbsoluteMaxRotAccel() * M_PI/180; + dynConf_max.rot_decel = robot->getAbsoluteMaxRotDecel() * M_PI/180; + + // I'm setting these upper bounds relitivly arbitrarily, feel free to increase them. + dynConf_max.TicksMM = 200; + dynConf_max.DriftFactor = 200; + dynConf_max.RevCount = 32760; + + dynamic_reconfigure_server->setConfigMax(dynConf_max); + + + rosaria::RosAriaConfig dynConf_default; + dynConf_default.trans_accel = robot->getTransAccel() / 1000; + dynConf_default.trans_decel = robot->getTransDecel() / 1000; + dynConf_default.lat_accel = robot->getLatAccel() / 1000; + dynConf_default.lat_decel = robot->getLatDecel() / 1000; + dynConf_default.rot_accel = robot->getRotAccel() * M_PI/180; + dynConf_default.rot_decel = robot->getRotDecel() * M_PI/180; + + dynConf_default.TicksMM = TicksMM; + dynConf_default.DriftFactor = DriftFactor; + dynConf_default.RevCount = RevCount; + + dynamic_reconfigure_server->setConfigDefault(dynConf_max); + + dynamic_reconfigure_server->setCallback(boost::bind(&RosAriaNode::dynamic_reconfigureCB, this, _1, _2)); + + // Enable the motors + robot->enableMotors(); + + // disable sonars on startup + robot->disableSonar(); + + // callback will be called by ArRobot background processing thread for every SIP data packet received from robot + robot->addSensorInterpTask("ROSPublishingTask", 100, &myPublishCB); + + // Initialize bumpers with robot number of bumpers + bumpers.front_bumpers.resize(robot->getNumFrontBumpers()); + bumpers.rear_bumpers.resize(robot->getNumRearBumpers()); + + // Run ArRobot background processing thread + robot->runAsync(true); + return 0; +} + +void RosAriaNode::spin() +{ + ros::spin(); +} + +void RosAriaNode::publish() +{ + // Note, this is called via SensorInterpTask callback (myPublishCB, named "ROSPublishingTask"). ArRobot object 'robot' sholud not be locked or unlocked. + pos = robot->getPose(); + tf::poseTFToMsg(tf::Transform(tf::createQuaternionFromYaw(pos.getTh()*M_PI/180), tf::Vector3(pos.getX()/1000, + pos.getY()/1000, 0)), position.pose.pose); //Aria returns pose in mm. + position.twist.twist.linear.x = robot->getVel()/1000; //Aria returns velocity in mm/s. + position.twist.twist.linear.y = robot->getLatVel()/1000.0; + position.twist.twist.angular.z = robot->getRotVel()*M_PI/180; + + position.header.frame_id = frame_id_odom; + position.child_frame_id = frame_id_base_link; + position.header.stamp = ros::Time::now(); + pose_pub.publish(position); + + ROS_DEBUG("RosAria: publish: (time %f) pose x: %f, y: %f, angle: %f; linear vel x: %f, y: %f; angular vel z: %f", + position.header.stamp.toSec(), + (double)position.pose.pose.position.x, + (double)position.pose.pose.position.y, + (double)position.pose.pose.orientation.w, + (double) position.twist.twist.linear.x, + (double) position.twist.twist.linear.y, + (double) position.twist.twist.angular.z + ); + + + // publishing transform odom->base_link + odom_trans.header.stamp = ros::Time::now(); + odom_trans.header.frame_id = frame_id_odom; + odom_trans.child_frame_id = frame_id_base_link; + + odom_trans.transform.translation.x = pos.getX()/1000; + odom_trans.transform.translation.y = pos.getY()/1000; + odom_trans.transform.translation.z = 0.0; + odom_trans.transform.rotation = tf::createQuaternionMsgFromYaw(pos.getTh()*M_PI/180); + + odom_broadcaster.sendTransform(odom_trans); + + // getStallValue returns 2 bytes with stall bit and bumper bits, packed as (00 00 FrontBumpers RearBumpers) + int stall = robot->getStallValue(); + unsigned char front_bumpers = (unsigned char)(stall >> 8); + unsigned char rear_bumpers = (unsigned char)(stall); + + bumpers.header.frame_id = frame_id_bumper; + bumpers.header.stamp = ros::Time::now(); + + std::stringstream bumper_info(std::stringstream::out); + // Bit 0 is for stall, next bits are for bumpers (leftmost is LSB) + for (unsigned int i=0; igetNumFrontBumpers(); i++) + { + bumpers.front_bumpers[i] = (front_bumpers & (1 << (i+1))) == 0 ? 0 : 1; + bumper_info << " " << (front_bumpers & (1 << (i+1))); + } + ROS_DEBUG("RosAria: Front bumpers:%s", bumper_info.str().c_str()); + + bumper_info.str(""); + // Rear bumpers have reverse order (rightmost is LSB) + unsigned int numRearBumpers = robot->getNumRearBumpers(); + for (unsigned int i=0; igetRealBatteryVoltageNow(); + voltage_pub.publish(batteryVoltage); + + if(robot->haveStateOfCharge()) + { + std_msgs::Float32 soc; + soc.data = robot->getStateOfCharge()/100.0; + state_of_charge_pub.publish(soc); + } + + // publish recharge state if changed + char s = robot->getChargeState(); + if(s != recharge_state.data) + { + ROS_INFO("RosAria: publishing new recharge state %d.", s); + recharge_state.data = s; + recharge_state_pub.publish(recharge_state); + } + + // publish motors state if changed + bool e = robot->areMotorsEnabled(); + if(e != motors_state.data || !published_motors_state) + { + ROS_INFO("RosAria: publishing stop motors state %d.", e); + motors_state.data = e; + motors_state_pub.publish(motors_state); + published_motors_state = true; + } + + //Publikuje czy zatrzymane silniki + if(stop_robot) + { + ROS_INFO("RosAria: publishing new motors state %d.", stop_motors_msg.data); + stop_motors_pub.publish(stop_motors_msg); + stop_robot = false; + } + + // Publish sonar information, if enabled. + if (publish_sonar || publish_sonar_pointcloud2) + { + sensor_msgs::PointCloud cloud; //sonar readings. + cloud.header.stamp = position.header.stamp; //copy time. + // sonar sensors relative to base_link + cloud.header.frame_id = frame_id_sonar; + + + std::stringstream sonar_debug_info; // Log debugging info + sonar_debug_info << "Sonar readings: "; + + for (int i = 0; i < robot->getNumSonar(); i++) { + ArSensorReading* reading = NULL; + reading = robot->getSonarReading(i); + if(!reading) { + ROS_WARN("RosAria: Did not receive a sonar reading."); + continue; + } + + // getRange() will return an integer between 0 and 5000 (5m) + sonar_debug_info << reading->getRange() << " "; + + // local (x,y). Appears to be from the centre of the robot, since values may + // exceed 5000. This is good, since it means we only need 1 transform. + // x & y seem to be swapped though, i.e. if the robot is driving north + // x is north/south and y is east/west. + // + //ArPose sensor = reading->getSensorPosition(); //position of sensor. + // sonar_debug_info << "(" << reading->getLocalX() + // << ", " << reading->getLocalY() + // << ") from (" << sensor.getX() << ", " + // << sensor.getY() << ") ;; " ; + + //add sonar readings (robot-local coordinate frame) to cloud + geometry_msgs::Point32 p; + p.x = reading->getLocalX() / 1000.0; + p.y = reading->getLocalY() / 1000.0; + p.z = 0.0; + cloud.points.push_back(p); + } + ROS_DEBUG_STREAM(sonar_debug_info.str()); + + // publish topic(s) + + if(publish_sonar_pointcloud2) + { + sensor_msgs::PointCloud2 cloud2; + if(!sensor_msgs::convertPointCloudToPointCloud2(cloud, cloud2)) + { + ROS_WARN("Error converting sonar point cloud message to point_cloud2 type before publishing! Not publishing this time."); + } + else + { + sonar_pointcloud2_pub.publish(cloud2); + } + } + + if(publish_sonar) + { + sonar_pub.publish(cloud); + } + } // end if sonar_enabled + + if(watchdog.toSec()+WATCHDOGcomInt(ArCommands::ESTOP,0); + robot->setVel(0); + if(robot->hasLatVel()) + robot->setLatVel(0); + robot->setRotVel(0); + // ROS_INFO("WATCHDOG %d", WATCHDOG); + } +} + +bool RosAriaNode::enable_motors_cb(std_srvs::Empty::Request& request, std_srvs::Empty::Response& response) +{ + ROS_INFO("RosAria: Enable motors request."); + robot->lock(); + if(robot->isEStopPressed()) + ROS_WARN("RosAria: Warning: Enable motors requested, but robot also has E-Stop button pressed. Motors will not enable."); + robot->enableMotors(); + robot->unlock(); + // todo could wait and see if motors do become enabled, and send a response with an error flag if not + return true; +} + +bool RosAriaNode::disable_motors_cb(std_srvs::Empty::Request& request, std_srvs::Empty::Response& response) +{ + ROS_INFO("RosAria: Disable motors request."); + robot->lock(); + robot->disableMotors(); + robot->unlock(); + // todo could wait and see if motors do become disabled, and send a response with an error flag if not + return true; +} + +//Damian Metody odpowiedzialne za awaryjne ztrzymanie silników +bool RosAriaNode::start_motors_cb(std_srvs::Empty::Request& request, std_srvs::Empty::Response& response) +{ + stop_robot=true; + stop_motors_msg.data=false; + + ROS_INFO("RosAria: Disable motors brakes."); + robot->lock(); + if(robot->isEStopPressed()) + ROS_WARN("RosAria: Warning: Enable motors requested, but robot also has E-Stop button pressed. Motors will not enable."); + robot->unlock(); + return true; +} + +bool RosAriaNode::stop_motors_cb(std_srvs::Empty::Request& request, std_srvs::Empty::Response& response) +{ + robot->lock(); + stop_robot=true; + stop_motors_msg.data=true; + //Zatrzymuje robota + robot->setVel(0); + if(robot->hasLatVel()) + robot->setLatVel(0); + robot->setRotVel(0); + + robot->comInt(ArCommands::ESTOP,0); + ROS_INFO("RosAria: Enable motors brakes."); + robot->unlock(); + return true; +} +bool RosAriaNode::gripper_open_cb(std_srvs::Empty::Request& request, std_srvs::Empty::Response& response) +{ + robot->lock(); + gripper->gripOpen(); + ROS_INFO("RosAria: Gripper opening."); + robot->unlock(); + return true; +} + +bool RosAriaNode::gripper_close_cb(std_srvs::Empty::Request& request, std_srvs::Empty::Response& response) +{ + robot->lock(); + gripper->gripClose(); + ROS_INFO("RosAria: Gripper closing."); + robot->unlock(); + return true; +} + +bool RosAriaNode::gripper_up_cb(std_srvs::Empty::Request& request, std_srvs::Empty::Response& response) +{ + robot->lock(); + gripper->liftUp(); + ROS_INFO("RosAria: Gripper moving up"); + robot->unlock(); + return true; +} + +bool RosAriaNode::gripper_down_cb(std_srvs::Empty::Request& request, std_srvs::Empty::Response& response) +{ + robot->lock(); + gripper->liftDown(); + ROS_INFO("RosAria: Gripper moving down."); + robot->unlock(); + return true; +} + + +void RosAriaNode::cmdvel_cb( const geometry_msgs::TwistConstPtr &msg) +{ + veltime = ros::Time::now(); + watchdog= ros::Time::now(); + if(stop_motors_msg.data) + { + ROS_INFO( "new speed: [%0.2f,%0.2f](%0.3f) but robot is stop", msg->linear.x*1e3, msg->angular.z, veltime.toSec() ); + return; + } + ROS_INFO( "new speed: [%0.2f,%0.2f](%0.3f)", msg->linear.x, msg->angular.z, veltime.toSec() ); + + ROS_INFO( "max speed: [%0.2f,%0.2f](%0.3f)", maxVel, maxRot, veltime.toSec() ); + float x,y,z; + x=msg->linear.x; + y=msg->linear.y; + z=msg->angular.z; + + if (fabs(msg->linear.x)>maxVel) + { + ROS_INFO( "angular velocity is too large"); + if(msg->linear.x<0) x=-maxVel; + if(msg->linear.x>0) x=maxVel; + } + if (fabs(msg->linear.y)>maxVel) + { + ROS_INFO( "angular velocity is too large"); + if(msg->linear.y<0) y=-maxVel; + if(msg->linear.y>0) y=maxVel; + } + if (fabs(msg->angular.z)>maxRot) + { + ROS_INFO( "rotate velocity is too large"); + if(msg->angular.z<0) z=-maxRot; + if(msg->angular.z>0) z=maxRot; + } + + + robot->lock(); + robot->setVel(x*1e3); + if(robot->hasLatVel()) + robot->setLatVel(y*1e3); + robot->setRotVel(z*180/M_PI); + robot->unlock(); + ROS_DEBUG("RosAria: sent vels to to aria (time %f): x vel %f mm/s, y vel %f mm/s, ang vel %f deg/s", veltime.toSec(), + (double) x * 1e3, (double) y * 1.3, (double) z * 180/M_PI); +} + +void RosAriaNode::maxspeed_cb( const geometry_msgs::Vector3ConstPtr &msg) +{ + veltime = ros::Time::now(); + maxVel=msg->y; + maxRot=msg->z; + ROS_INFO( "new max speed: [%0.2f,%0.2f]", msg->y, msg->z); +} + +int main( int argc, char** argv ) +{ + ros::init(argc,argv, "RosAria"); + ros::NodeHandle n(std::string("~")); + Aria::init(); + + RosAriaNode *node = new RosAriaNode(n); + + if( node->Setup() != 0 ) + { + ROS_FATAL( "RosAria: ROS node setup failed... \n" ); + return -1; + } + + node->spin(); + + delete node; + + ROS_INFO( "RosAria: Quitting... \n" ); + return 0; + +} diff --git a/cfg/RosAria.cfg b/Legacy/ws_linux/src/rosaria/cfg/RosAria.cfg similarity index 100% rename from cfg/RosAria.cfg rename to Legacy/ws_linux/src/rosaria/cfg/RosAria.cfg diff --git a/libaria.rdmanifest b/Legacy/ws_linux/src/rosaria/libaria.rdmanifest similarity index 100% rename from libaria.rdmanifest rename to Legacy/ws_linux/src/rosaria/libaria.rdmanifest diff --git a/mainpage.dox b/Legacy/ws_linux/src/rosaria/mainpage.dox similarity index 100% rename from mainpage.dox rename to Legacy/ws_linux/src/rosaria/mainpage.dox diff --git a/msg/BumperState.msg b/Legacy/ws_linux/src/rosaria/msg/BumperState.msg similarity index 100% rename from msg/BumperState.msg rename to Legacy/ws_linux/src/rosaria/msg/BumperState.msg diff --git a/Legacy/ws_linux/src/rosaria/package.xml b/Legacy/ws_linux/src/rosaria/package.xml new file mode 100644 index 0000000..65de483 --- /dev/null +++ b/Legacy/ws_linux/src/rosaria/package.xml @@ -0,0 +1,56 @@ + + rosaria + 0.9.0 + + ROSARIA provides a ROS interface for most Adept MobileRobots, + MobileRobots Inc., and ActivMedia mobile robot bases including + Pioneer 2, Pioneer 3, AmigoBot, PeopleBot, PowerBot, PatrolBot, Seekur, + Seekur Jr., Pioneer LX, + and any other past, current or future robot base supported by Adept MobileRobot's + open source ARIA library. + Information from the robot base, and velocity and acceleration control, is implemented + via a RosAria node, which publishes topics providing data recieved from + the robot's embedded controller by ARIA, and sets desired velocity, acceleration and + other commands in ARIA when new commands are received from command topics. + + Srećko Jurić-Kavelj + Ivan Marković + Reed Hedges + + GPLv2 + + http://www.ros.org/wiki/ROSARIA + https://github.com/amor-ros-pkg/rosaria/issues + + Srećko Jurić-Kavelj + + catkin + + message_generation + libaria + roscpp + nav_msgs + geometry_msgs + sensor_msgs + std_msgs + tf + dynamic_reconfigure + libaria + roscpp + nav_msgs + geometry_msgs + sensor_msgs + std_msgs + tf + dynamic_reconfigure + + + + + + diff --git a/Legacy/ws_linux/src/rosaria_msgs/CMakeLists.txt b/Legacy/ws_linux/src/rosaria_msgs/CMakeLists.txt new file mode 100644 index 0000000..e04f1f5 --- /dev/null +++ b/Legacy/ws_linux/src/rosaria_msgs/CMakeLists.txt @@ -0,0 +1,202 @@ +cmake_minimum_required(VERSION 2.8.3) +project(rosaria_msgs) + +## Compile as C++11, supported in ROS Kinetic and newer +# add_compile_options(-std=c++11) + +## Find catkin macros and libraries +## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz) +## is used, also find other catkin packages +find_package(catkin REQUIRED COMPONENTS + geometry_msgs + rospy + std_msgs + message_generation +) + +## System dependencies are found with CMake's conventions +# find_package(Boost REQUIRED COMPONENTS system) + + +## Uncomment this if the package has a setup.py. This macro ensures +## modules and global scripts declared therein get installed +## See http://ros.org/doc/api/catkin/html/user_guide/setup_dot_py.html +# catkin_python_setup() + +################################################ +## Declare ROS messages, services and actions ## +################################################ + +## To declare and build messages, services or actions from within this +## package, follow these steps: +## * Let MSG_DEP_SET be the set of packages whose message types you use in +## your messages/services/actions (e.g. std_msgs, actionlib_msgs, ...). +## * In the file package.xml: +## * add a build_depend tag for "message_generation" +## * add a build_depend and a run_depend tag for each package in MSG_DEP_SET +## * If MSG_DEP_SET isn't empty the following dependency has been pulled in +## but can be declared for certainty nonetheless: +## * add a run_depend tag for "message_runtime" +## * In this file (CMakeLists.txt): +## * add "message_generation" and every package in MSG_DEP_SET to +## find_package(catkin REQUIRED COMPONENTS ...) +## * add "message_runtime" and every package in MSG_DEP_SET to +## catkin_package(CATKIN_DEPENDS ...) +## * uncomment the add_*_files sections below as needed +## and list every .msg/.srv/.action file to be processed +## * uncomment the generate_messages entry below +## * add every package in MSG_DEP_SET to generate_messages(DEPENDENCIES ...) + +## Generate messages in the 'msg' folder + add_message_files( + FILES + RestrictionsMsg.msg + RobotInfoMsg.msg + ) + +## Generate services in the 'srv' folder +# add_service_files( +# FILES +# Service1.srv +# Service2.srv +# ) + +## Generate actions in the 'action' folder +# add_action_files( +# FILES +# Action1.action +# Action2.action +# ) + +## Generate added messages and services with any dependencies listed here + generate_messages( + DEPENDENCIES + std_msgs + geometry_msgs + ) + +################################################ +## Declare ROS dynamic reconfigure parameters ## +################################################ + +## To declare and build dynamic reconfigure parameters within this +## package, follow these steps: +## * In the file package.xml: +## * add a build_depend and a run_depend tag for "dynamic_reconfigure" +## * In this file (CMakeLists.txt): +## * add "dynamic_reconfigure" to +## find_package(catkin REQUIRED COMPONENTS ...) +## * uncomment the "generate_dynamic_reconfigure_options" section below +## and list every .cfg file to be processed + +## Generate dynamic reconfigure parameters in the 'cfg' folder +# generate_dynamic_reconfigure_options( +# cfg/DynReconf1.cfg +# cfg/DynReconf2.cfg +# ) + +################################### +## catkin specific configuration ## +################################### +## The catkin_package macro generates cmake config files for your package +## Declare things to be passed to dependent projects +## INCLUDE_DIRS: uncomment this if your package contains header files +## LIBRARIES: libraries you create in this project that dependent projects also need +## CATKIN_DEPENDS: catkin_packages dependent projects also need +## DEPENDS: system dependencies of this project that dependent projects also need +catkin_package( + CATKIN_DEPENDS message_runtime +# INCLUDE_DIRS include +# LIBRARIES rosaria_msgs +# CATKIN_DEPENDS geometry_msgs rospy std_msgs +# DEPENDS system_lib +) + +########### +## Build ## +########### + +## Specify additional locations of header files +## Your package locations should be listed before other locations +include_directories( +# include + ${catkin_INCLUDE_DIRS} +) + +## Declare a C++ library +# add_library(${PROJECT_NAME} +# src/${PROJECT_NAME}/rosaria_msgs.cpp +# ) + +## Add cmake target dependencies of the library +## as an example, code may need to be generated before libraries +## either from message generation or dynamic reconfigure +# add_dependencies(${PROJECT_NAME} ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS}) + +## Declare a C++ executable +## With catkin_make all packages are built within a single CMake context +## The recommended prefix ensures that target names across packages don't collide +# add_executable(${PROJECT_NAME}_node src/rosaria_msgs_node.cpp) + +## Rename C++ executable without prefix +## The above recommended prefix causes long target names, the following renames the +## target back to the shorter version for ease of user use +## e.g. "rosrun someones_pkg node" instead of "rosrun someones_pkg someones_pkg_node" +# set_target_properties(${PROJECT_NAME}_node PROPERTIES OUTPUT_NAME node PREFIX "") + +## Add cmake target dependencies of the executable +## same as for the library above +# add_dependencies(${PROJECT_NAME}_node ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS}) + +## Specify libraries to link a library or executable target against +# target_link_libraries(${PROJECT_NAME}_node +# ${catkin_LIBRARIES} +# ) + +############# +## Install ## +############# + +# all install targets should use catkin DESTINATION variables +# See http://ros.org/doc/api/catkin/html/adv_user_guide/variables.html + +## Mark executable scripts (Python etc.) for installation +## in contrast to setup.py, you can choose the destination +install(PROGRAMS +# scripts/my_python_script + DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} + ) + +## Mark executables and/or libraries for installation +# install(TARGETS ${PROJECT_NAME} ${PROJECT_NAME}_node +# ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} +# LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} +# RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} +# ) + +## Mark cpp header files for installation +# install(DIRECTORY include/${PROJECT_NAME}/ +# DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION} +# FILES_MATCHING PATTERN "*.h" +# PATTERN ".svn" EXCLUDE +# ) + +## Mark other files for installation (e.g. launch and bag files, etc.) +# install(FILES +# # myfile1 +# # myfile2 +# DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION} +# ) + +############# +## Testing ## +############# + +## Add gtest based cpp test target and link libraries +# catkin_add_gtest(${PROJECT_NAME}-test test/test_rosaria_msgs.cpp) +# if(TARGET ${PROJECT_NAME}-test) +# target_link_libraries(${PROJECT_NAME}-test ${PROJECT_NAME}) +# endif() + +## Add folders to be run by python nosetests +# catkin_add_nosetests(test) diff --git a/Legacy/ws_linux/src/rosaria_msgs/msg/RestrictionsMsg.msg b/Legacy/ws_linux/src/rosaria_msgs/msg/RestrictionsMsg.msg new file mode 100644 index 0000000..2b0aa55 --- /dev/null +++ b/Legacy/ws_linux/src/rosaria_msgs/msg/RestrictionsMsg.msg @@ -0,0 +1,3 @@ +std_msgs/Float64 distance +std_msgs/Float64 linear_velocity +std_msgs/Float64 angular_velocity \ No newline at end of file diff --git a/Legacy/ws_linux/src/rosaria_msgs/msg/RobotInfoMsg.msg b/Legacy/ws_linux/src/rosaria_msgs/msg/RobotInfoMsg.msg new file mode 100644 index 0000000..f3ded53 --- /dev/null +++ b/Legacy/ws_linux/src/rosaria_msgs/msg/RobotInfoMsg.msg @@ -0,0 +1,6 @@ +std_msgs/UInt8 robot_id +std_msgs/Float64 battery_voltage +geometry_msgs/Twist twist +std_msgs/Bool state +std_msgs/Bool clutch +std_msgs/Bool obstacle_detected \ No newline at end of file diff --git a/Legacy/ws_linux/src/rosaria_msgs/package.xml b/Legacy/ws_linux/src/rosaria_msgs/package.xml new file mode 100644 index 0000000..81a1a54 --- /dev/null +++ b/Legacy/ws_linux/src/rosaria_msgs/package.xml @@ -0,0 +1,21 @@ + + + rosaria_msgs + 0.0.0 + The rosaria_msgs package + + Aleksander Bojda + + MIT + + catkin + std_msgs + message_generation + + std_msgs + message_generation + + std_msgs + message_runtime + + diff --git a/Legacy/ws_linux/src/safety/.gitignore b/Legacy/ws_linux/src/safety/.gitignore new file mode 100644 index 0000000..1c565ef --- /dev/null +++ b/Legacy/ws_linux/src/safety/.gitignore @@ -0,0 +1,3 @@ +# ignore tmp and backup files +*.sw* +*.*~ diff --git a/Legacy/ws_linux/src/safety/CMakeLists.txt b/Legacy/ws_linux/src/safety/CMakeLists.txt new file mode 100644 index 0000000..f1aee9d --- /dev/null +++ b/Legacy/ws_linux/src/safety/CMakeLists.txt @@ -0,0 +1,34 @@ +cmake_minimum_required(VERSION 2.8.3) +project(safety) + +## Find catkin and any catkin packages +find_package(catkin REQUIRED COMPONENTS roscpp rospy std_msgs message_generation rosaria +) + +## Declare ROS messages and services +#add_message_files(#DIRECTORY msg +# FILES Num.msg) +#add_service_files(#DIRECTORY srv +# FILES AddInts.srv) + +## Generate added messages and services +generate_messages(DEPENDENCIES std_msgs) + +## Declare a catkin package +#catkin_package() +catkin_package( + # INCLUDE_DIRS include + LIBRARIES safety + CATKIN_DEPENDS message_runtime roscpp rospy std_msgs rosaria + DEPENDS system_lib +) + +include_directories(include ${catkin_INCLUDE_DIRS}) + + +add_executable(cloud_reader src/cloud_reader.cpp) +target_link_libraries(cloud_reader ${catkin_LIBRARIES}) +add_dependencies(cloud_reader safety_generate_messages_cpp) + + + diff --git a/Legacy/ws_linux/src/safety/README.txt b/Legacy/ws_linux/src/safety/README.txt new file mode 100644 index 0000000..aeb97f5 --- /dev/null +++ b/Legacy/ws_linux/src/safety/README.txt @@ -0,0 +1,29 @@ + + Package 'safety' prevents robot from crashing into obstacle. + Enables motor brakes when the distance is smaller than + minimum_distance specified in command-line. + + Note. After moving robot back into safe place, + turning on of breaks is needed. Also is + suggested to set robot cmd_vel to 0, + before restaring. + +------------------------------------------------------------------ + LAUNCHING + + To launch package, make sure roscore and modified RosAria (with + service stop_motors) is allready running. + + In terminal type: + + rosrun safety cloud_reader [minimal_distance] + + where minimal_distance is the distance to obstacle, where robot + breaks are enabled, measured in meters. + + Suggested minimal distance for Pionier is 0.7. + + + + + diff --git a/Legacy/ws_linux/src/safety/gnu_licence.txt b/Legacy/ws_linux/src/safety/gnu_licence.txt new file mode 100644 index 0000000..94a9ed0 --- /dev/null +++ b/Legacy/ws_linux/src/safety/gnu_licence.txt @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/Legacy/ws_linux/src/safety/package.xml b/Legacy/ws_linux/src/safety/package.xml new file mode 100644 index 0000000..c73f4e1 --- /dev/null +++ b/Legacy/ws_linux/src/safety/package.xml @@ -0,0 +1,24 @@ + + + safety + 0.2.1 + Package prevents robot from crashing into obstacle. Enables robot brakes when the distance is smaller than minimum_distance. + + Aleksandra Grzelak + GNU GPLv3 + + message_generation + message_runtime + catkin + roscpp + rospy + std_msgs + rosaria + + roscpp + rospy + std_msgs + rosaria + + + diff --git a/Legacy/ws_linux/src/safety/src/cloud_reader.cpp b/Legacy/ws_linux/src/safety/src/cloud_reader.cpp new file mode 100644 index 0000000..74889de --- /dev/null +++ b/Legacy/ws_linux/src/safety/src/cloud_reader.cpp @@ -0,0 +1,198 @@ +/* ------------------------------------------------------------------------ + * cloud_reader + * + * copyright 2015 Aleksandra Grzelak + * + * Wroclaw University of Technology, + * 27 Wybrzeze Wyspianskiego St + * 50-370 Wroclaw, + * Poland, + * www.pwr.edu.pl + * + * Contact email: aleksandra.j.grzelak@gmail.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * ------------------------------------------------------------------------ */ + +#include "ros/ros.h" +#include "sensor_msgs/PointCloud.h" +#include +#include +#include +#include +#include +#include +#include + +#define N_POINTS_ 8 //because only 8 sonars are working in PIONIER + +/* SAFETY cloud_reader [minimum_distance] + * + * Package prevents robot from crashing into obstacle + * Enables motor brakes when the distance is smaller than + * minimum_distance + * + * Note. After moving robot back into safe place, + * it is needed to disable breaks. Also, it is + * suggested to set robot cmd_vel to 0, + * before restaring. + */ + +class SafeReader { + public: + ros::NodeHandle n; + + protected: + bool motors_on; // information for toggling motors + float stop_dist; // minimal distance to obstacle + + ros::ServiceClient client_stop; // client for stopping motors + std_srvs::Empty stop_srv; // service for stopping motors + ros::Subscriber sub_sonar; // subscriber from robot sonars + ros::Subscriber sub_dist; // subscriber from safe distance + + public: + + /* SafeReader + * constructor, gets namespace in node + * and initiates client responsible for stopping motors + * + * NOTE. requires modified RosAria with service stop_motors + */ + SafeReader() { + std::stringstream node_motor; + std::stringstream node_sonar; + std::stringstream node_distance; + node_motor << ros::this_node::getNamespace(); + motors_on=1; + set_stop_dist( 2.0 ); + + node_motor << "/RosAria/"; + node_sonar << node_motor.str() << "sonar"; + //node_distance << node_motor.str() << "distance"; + node_distance << "/PIONIER/distance"; + node_motor << "stop_motors"; + ROS_DEBUG( "namespace: [%10s]", node_motor.str().c_str() ); + client_stop = n.serviceClient< std_srvs::Empty >( node_motor.str().c_str() ); + sub_dist = n.subscribe( node_distance.str().c_str(), 100, &SafeReader::distance_callback, this ); + sub_sonar = n.subscribe( node_sonar.str().c_str(), 100, &SafeReader::reader_callback , this ); + + } + + /* get_stop_dist + * returns defined minimal distance, after which robot stops + */ + float get_stop_dist() const { + return stop_dist; + } + + /* set_stop_distance + * sets the minmal distance after which robot stops + * new_dist -- new minimal distance + */ + void set_stop_dist( float new_dist ) { + stop_dist = new_dist; + } + + /* get_motors + * returns if motors are enabled + * + * return value: + * 1 -- motors enabled, brakes off + * 0 -- motors disabled, brakes on + */ + bool get_motors() const { + return motors_on; + } + + /* calc_distance + * returns the distance to obstacle + * x,y -- coordinates of the obstacle + */ + float calc_distance( float x, float y ) { // (x,y) are obstacle coordinates + return sqrt(x*x+y*y); + } + + /* distance_callback + * after changing value of safe distance + * this safe distance is published + * after reciving safe_distance is set + * + * NOTE. After connecting new robot + * this message must be published. + */ + void distance_callback( const geometry_msgs::Vector3::ConstPtr & msg ) { + set_stop_dist( msg->x ); + ROS_DEBUG( "recieved new safe_dist: %0.3f", get_stop_dist() ); + } + + /* reader_callback + * after recieving message with coordinates of obstacle + * calculcates the distance, if the smallest distance is smaller + * than specified minimal distance, sets the parameter motors_on + * to 0 and enables robot breaks (calling the service stop_motors), + * otherwise parameter motors_on is set to 1. + * + * NOTE. Once the breaks are enabled, they must be disabled manually, + * even though the distance is proper. + */ + void reader_callback( const sensor_msgs::PointCloud::ConstPtr & msg ) { + geometry_msgs::Twist out; + float x,y, min_x, min_y; + float temp_dist, dist=99999; + for( int i=0; i < N_POINTS_; ++i ) { //all points from PointCloud + x=msg->points[i].x; + y=msg->points[i].y; + if( x != 0.0 && y != 0.0 ) { + temp_dist=calc_distance( x,y ); + if( dist > temp_dist ) { //get the smallest distance + dist=temp_dist; + min_x=x; + min_y=y; + } + } + } //endfor + + if( dist < get_stop_dist() ) { // disable motors + ROS_DEBUG( "Distance %0.3f too small (min: %0.3f)", dist, get_stop_dist() ); //DEBUG + motors_on=0; + client_stop.call( stop_srv ); + ROS_DEBUG( "Stopped motors" ); //DEBUG + } else { // distance ok + ROS_DEBUG( " Distance OK %0.3f, x=%0.3f, y=%0.3f (min: %0.3f)", dist, x,y, get_stop_dist() ); //DEBUG + motors_on=1; + } // endif + } +}; // SAFEREADER + + +int main( int argc, char **argv ) { + ros::init( argc, argv, "cloud_reader" ); + SafeReader reader; + + if( argc == 2 ) { // stop distance must be given in command-line + reader.set_stop_dist( atof( argv[1] ) ); + ROS_DEBUG( " Stop distance at [%0.3f] ", reader.get_stop_dist() ); + } else { + ROS_INFO( "Distance parameters not specified. Usage:\n cloud_reader [stop_distance] " ); + return 1; + } + + ROS_INFO( " Ready. "); + ros::spin(); + + return 0; +} diff --git a/Legacy/ws_linux/src/videostream/.gitignore b/Legacy/ws_linux/src/videostream/.gitignore new file mode 100644 index 0000000..9020de0 --- /dev/null +++ b/Legacy/ws_linux/src/videostream/.gitignore @@ -0,0 +1,2 @@ +*.*~ +*.sw* diff --git a/Legacy/ws_linux/src/videostream/CMakeLists.txt b/Legacy/ws_linux/src/videostream/CMakeLists.txt new file mode 100644 index 0000000..caed66f --- /dev/null +++ b/Legacy/ws_linux/src/videostream/CMakeLists.txt @@ -0,0 +1,160 @@ +cmake_minimum_required(VERSION 2.8.3) +project(videostream) + +## Find catkin macros and libraries +## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz) +## is used, also find other catkin packages +find_package(catkin REQUIRED COMPONENTS + roscpp + rospy + std_msgs + message_generation + ) + +## System dependencies are found with CMake's conventions +# find_package(Boost REQUIRED COMPONENTS system) + + +## Uncomment this if the package has a setup.py. This macro ensures +## modules and global scripts declared therein get installed +## See http://ros.org/doc/api/catkin/html/user_guide/setup_dot_py.html +# catkin_python_setup() + +################################################ +## Declare ROS messages, services and actions ## +################################################ + +## To declare and build messages, services or actions from within this +## package, follow these steps: +## * Let MSG_DEP_SET be the set of packages whose message types you use in +## your messages/services/actions (e.g. std_msgs, actionlib_msgs, ...). +## * In the file package.xml: +## * add a build_depend and a run_depend tag for each package in MSG_DEP_SET +## * If MSG_DEP_SET isn't empty the following dependencies might have been +## pulled in transitively but can be declared for certainty nonetheless: +## * add a build_depend tag for "message_generation" +## * add a run_depend tag for "message_runtime" +## * In this file (CMakeLists.txt): +## * add "message_generation" and every package in MSG_DEP_SET to +## find_package(catkin REQUIRED COMPONENTS ...) +## * add "message_runtime" and every package in MSG_DEP_SET to +## catkin_package(CATKIN_DEPENDS ...) +## * uncomment the add_*_files sections below as needed +## and list every .msg/.srv/.action file to be processed +## * uncomment the generate_messages entry below +## * add every package in MSG_DEP_SET to generate_messages(DEPENDENCIES ...) + +## Generate messages in the 'msg' folder +# add_message_files( +# FILES +# Message1.msg +# Message2.msg +# ) + +## Generate services in the 'srv' folder +add_service_files( + FILES + ip_get.srv +) + +## Generate actions in the 'action' folder +# add_action_files( +# FILES +# Action1.action +# Action2.action +# ) + +## Generate added messages and services with any dependencies listed here +generate_messages( + DEPENDENCIES + std_msgs # Or other packages containing msgs + ) + +################################### +## catkin specific configuration ## +################################### +## The catkin_package macro generates cmake config files for your package +## Declare things to be passed to dependent projects +## INCLUDE_DIRS: uncomment this if you package contains header files +## LIBRARIES: libraries you create in this project that dependent projects also need +## CATKIN_DEPENDS: catkin_packages dependent projects also need +## DEPENDS: system dependencies of this project that dependent projects also need +catkin_package( + INCLUDE_DIRS include + LIBRARIES videostream + CATKIN_DEPENDS message_runtime roscpp rospy std_msgs + DEPENDS system_lib +) + +########### +## Build ## +########### + +## Specify additional locations of header files +## Your package locations should be listed before other locations +# include_directories(include) + +## Declare a cpp library +# add_library(videostream +# src/${PROJECT_NAME}/videostream.cpp +# ) + +## Declare a cpp executable +add_executable(videostream src/videostream.cpp) + +## Add cmake target dependencies of the executable/library +## as an example, message headers may need to be generated before nodes +add_dependencies(videostream videostream_generate_messages_cpp) + +## Specify libraries to link a library or executable target against +target_link_libraries(videostream + ${catkin_LIBRARIES} + ) + +############# +## Install ## +############# + +# all install targets should use catkin DESTINATION variables +# See http://ros.org/doc/api/catkin/html/adv_user_guide/variables.html + +## Mark executable scripts (Python etc.) for installation +## in contrast to setup.py, you can choose the destination +# install(PROGRAMS +# scripts/my_python_script +# DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} +# ) + +## Mark executables and/or libraries for installation +# install(TARGETS videostream videostream_node +# ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} +# LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} +# RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} +# ) + +## Mark cpp header files for installation +# install(DIRECTORY include/${PROJECT_NAME}/ +# DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION} +# FILES_MATCHING PATTERN "*.h" +# PATTERN ".svn" EXCLUDE +# ) + +## Mark other files for installation (e.g. launch and bag files, etc.) +# install(FILES +# # myfile1 +# # myfile2 +# DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION} +# ) + +############# +## Testing ## +############# + +## Add gtest based cpp test target and link libraries +# catkin_add_gtest(${PROJECT_NAME}-test test/test_videostream.cpp) +# if(TARGET ${PROJECT_NAME}-test) +# target_link_libraries(${PROJECT_NAME}-test ${PROJECT_NAME}) +# endif() + +## Add folders to be run by python nosetests +# catkin_add_nosetests(test) diff --git a/Legacy/ws_linux/src/videostream/include/Videostream.h b/Legacy/ws_linux/src/videostream/include/Videostream.h new file mode 100644 index 0000000..1e35e4c --- /dev/null +++ b/Legacy/ws_linux/src/videostream/include/Videostream.h @@ -0,0 +1,51 @@ +#ifndef __VIDEOSTREAM__ +#define __VIDEOSTREAM__ + +#include "ros/ros.h" +#include "videostream/ip_get.h" + +#include "std_msgs/String.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAX_STREAMERS 1 +#define PORT_NR 1234 + +class Videostream { + public: + ros::NodeHandle n; + + protected: + std::map< std::string, pid_t > ip_list; + std::vector< std::string > dev_list; + int number_streamers; + + ros::ServiceServer service_add; + ros::ServiceServer service_rmv; + + int _find_free_device() const; + void _occupy_device( std::string ip, int dev_number ); + void _free_device( int dev_number ); + pid_t system2( const char * command, int * infp, int * outfp ) const; + bool _validate( const std::string & ip ) const; + bool _ip_exist( const std::string & ip ) const; + void DE_view_dev() const; + + public: + Videostream(); + + bool add_ip( videostream::ip_get::Request &req, videostream::ip_get::Response &res ) ; + bool remove_ip( videostream::ip_get::Request &req, videostream::ip_get::Response &res ); + +}; + +#endif diff --git a/Legacy/ws_linux/src/videostream/package.xml b/Legacy/ws_linux/src/videostream/package.xml new file mode 100644 index 0000000..fefd5f1 --- /dev/null +++ b/Legacy/ws_linux/src/videostream/package.xml @@ -0,0 +1,59 @@ + + + videostream + 0.0.0 + The videostream package + + + + + lab + + + + + + TODO + + + + + + + + + + + + + + + + + + + message_generation + + + + message_runtime + + + catkin + roscpp + rospy + std_msgs + roscpp + rospy + std_msgs + + + + + + + + + + + diff --git a/Legacy/ws_linux/src/videostream/src/videostream.cpp b/Legacy/ws_linux/src/videostream/src/videostream.cpp new file mode 100644 index 0000000..2b96918 --- /dev/null +++ b/Legacy/ws_linux/src/videostream/src/videostream.cpp @@ -0,0 +1,216 @@ +/* + * VIDEOSTREAM is a program for streaming video using ROS services + * + * Copyright (C) 2015 Aleksandra Grzelak (aleksandra.grzelak@pwr.edu.pl) + * Copyright (C) 2015 Damian Baranski (damian.baranski@pwr.edu.pl) + * + * Wroclaw University of Technology, + * 27 Wybrzeze Wyspianskiego St + * 50-370 Wroclaw, + * Poland, + * www.pwr.edu.pl + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + + +#include "../include/Videostream.h" + + +Videostream::Videostream() { + number_streamers=0; + dev_list.resize( MAX_STREAMERS ); + service_add = n.advertiseService("add_ip_to_stream", &Videostream::add_ip, this); + service_rmv = n.advertiseService("remove_ip_from_stream", &Videostream::remove_ip, this); +} + +int Videostream::_find_free_device() const { + for( int i=0; i < MAX_STREAMERS; ++i ) { + if( dev_list[i].empty() ) { + return i; + } + } + return -1; + +} + +void Videostream::_occupy_device( std::string ip, int dev_number ) { + dev_list[dev_number]=ip; + +} + +void Videostream:: _free_device( int dev_number ) { + dev_list[dev_number].clear(); +} + + +/* SYSTEM 2 + * launches command and returns pid of the process */ +pid_t Videostream::system2( const char * command, int * infp, int * outfp ) const { + int p_stdin[2]; + int p_stdout[2]; + pid_t pid; + + if( pipe( p_stdin ) == -1 ) + return -1; + + if( pipe( p_stdout) == -1 ) { + close( p_stdin[0] ); + close( p_stdin[1] ); + return -1; + } + + pid = fork(); + + if( pid < 0 ) { + close( p_stdin[0]); + close( p_stdin[1] ); + close( p_stdout[0] ); + close( p_stdout[1] ); + return pid; + } else if(pid == 0 ) { + close( p_stdin[1] ); + dup2( p_stdin[0], 0); + close( p_stdout[0] ); + dup2( p_stdout[1], 1 ); + dup2( ::open( "/dev/null", O_RDONLY ), 2 ); + /// Close all other descriptors for the safety sake. + for( int i = 3; i < 4096; ++i ) + ::close(i); + + setsid(); + execl( "/bin/sh", "sh", "-c", command, NULL ); + _exit( 1 ); + } + + close( p_stdin[0] ); + close( p_stdout[1] ); + + if( infp == NULL ) { + close( p_stdin[1] ); + } else { + *infp = p_stdin[1]; + } + + if( outfp == NULL ) { + close( p_stdout[0] ); + } else { + *outfp = p_stdout[0]; + } + + return pid; +} + +/* VALIDATE + * checks if given ip matches to be an ip address + * using regex */ +bool Videostream::_validate( const std::string & ip ) const{ + std::tr1::regex rx("[0-9][0-9]?[0-9]?\\.[0-9][0-9]?[0-9]?\\.[0-9][0-9]?[0-9]?\\.[0-9][0-9]?[0-9]?"); + return std::tr1::regex_match( ip.begin(), ip.end() ,rx ); +} + +bool Videostream::_ip_exist( const std::string & ip ) const { + if( ip_list.find( ip ) != ip_list.end() ) { + return true; + } + return false; +} + +void Videostream::DE_view_dev() const{ + for( std::vector < std::string >::const_iterator it=dev_list.begin(); it != dev_list.end(); ++it ) { + std::cout << *it << std::endl; + } +} +/* ADD_IP + * service for adding ip for streaming */ +bool Videostream::add_ip( + videostream::ip_get::Request &req, + videostream::ip_get::Response &res ) { + if( number_streamers >= MAX_STREAMERS ) { + ROS_INFO("[err] too much streamers "); + return false; + } + std::string ip_to_add=req.str.c_str(); + + if( ! _validate(ip_to_add) ) { + ROS_INFO("[err] illegal expresion "); + return false; + } + if( _ip_exist(ip_to_add) ) { + ROS_INFO("[err] ip already exists "); + return false; + } + int free_dev=_find_free_device(); + if( free_dev == -1 ) { + ROS_INFO("[err] no free device "); + return false; + } + + _occupy_device( ip_to_add, free_dev ); + ROS_INFO("[added %1s]", ip_to_add.c_str() ); + ++number_streamers; + + std::stringstream command; + command << "gst-launch v4l2src device=/dev/video" <::iterator vect_iter; + + vect_iter= std::find( dev_list.begin(), dev_list.end(), ip_to_del ) ; // make ip empty + if( vect_iter == dev_list.end() ) { + ROS_INFO("[err] no device found "); + return false; + } + vect_iter->clear(); + ip_list.erase(iter); + DE_view_dev(); + return true; + +} + + +/* ========= MAIN =================*/ +int main(int argc, char**argv ) { + ros::init(argc,argv,"videostream"); + Videostream video; + ROS_INFO("Ready to stream"); + ros::spin(); + return 0; +} + + diff --git a/Legacy/ws_linux/src/videostream/srv/ip_get.srv b/Legacy/ws_linux/src/videostream/srv/ip_get.srv new file mode 100644 index 0000000..53ee91c --- /dev/null +++ b/Legacy/ws_linux/src/videostream/srv/ip_get.srv @@ -0,0 +1,2 @@ +string str +--- diff --git a/ros.desktop b/ros.desktop deleted file mode 100755 index 7a71050..0000000 --- a/ros.desktop +++ /dev/null @@ -1,7 +0,0 @@ -# Pleace change ${ID} to ID of robot -[Desktop Entry] -Type=Application -Exec=/home/lab1_5/run.sh ${ID} -Hidden=false -NoDisplay=false -Name=ros diff --git a/run.sh b/run.sh deleted file mode 100755 index 759723d..0000000 --- a/run.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/bash -ID=$1 -if [[ -n ${ID//[0-9]/} ]]; then - echo "Invalid pioneer number!" - exit 1 -fi -source /opt/ros/hydro/setup.bash -source /home/lab1_5/ws/ws_linux/devel/setup.bash -export ROS_MASTER_URI='http://10.104.16.29:11311' -export ROS_IP=10.104.16.4${ID} -export PIONIER_ID=${ID} -export ROS_NAMESPACE=/PIONIER${ID} - -#rosrun rosaria RosAria _port:=/dev/ttyS0 & >/dev/null 2>&1 -rosrun rosaria RosAria _port:=/dev/ttyS0 _tf_prefix:=/PIONIER${ID} & -#rosrun safety cloud_reader 0.7 & -rosrun hokuyo_node hokuyo_node _frame_id:="${ROS_NAMESPACE}/laser" & -#rosrun videostream videostream & -#cvlc v4l2:///dev/video0 :v4l2-standard= :sout='#transcode{vcodec=FLV1,vb=0,scale=0,acodec=none}:http{mux=ffmpeg{mux=flv},dst=:8080/}' :sout-keep :live-caching=300 &

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 z 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 tc)P0b|!;N4)-#6Wd`aSwnT7cMJ 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 z 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